Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
tip42
3 / 3 / 0
Регистрация: 02.03.2015
Сообщений: 21
#1

Генератор звукового сигнала - Программирование Android

11.08.2016, 12:38. Просмотров 3356. Ответов 73
Метки нет (Все метки)

Здравствуйте, кто может помочь написать простенький генератор сигнала, синус. Важна любая помощь. По интернетам смотрел информации мало. Если у кого-то есть желание, может в личку написать, может договоримся.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.08.2016, 12:38
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Генератор звукового сигнала (Программирование Android):

Передача звукового потока в микрофон
Здравствуйте все форумчане! Хотел бы узнать в какую мне сторону двигаться....

Отображение содержимого звукового буфера в логах
while(!stopped) { short buffer...

Как заполнить заголовок звукового файла?
public class AudioRecord { byte header = new byte; byte channels ;...

Генератор кубиков
Всем привет) Помогите новичку... Познания нулевые и вот решил попробовать...

Генератор String
Добрый день, уважаемые форумчане. Уже который день пытаюсь решить маленькую...

Сделать звуковой генератор
Всем привет. Ребят, как выдать в наушник звук импульсами примерно...

73
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
25.11.2016, 10:51 #41
Задержка звука - сколько миллисекунд звук будет звучать. Вроде в Вашем уравнении она обозначалась D
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
25.11.2016, 10:53 #42
КАВ, как вы экстраординарно извращаете терминологию. это не задержка. это продолжительность, длительность, время звучания. все что угодно, но не задержка. D может быть разным и зависит лишь от того какого размера блок вы готовы хранить в памяти.
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
25.11.2016, 10:59 #43
Ну хорошо. Я был не прав,но всё же как подобрать нужную продолжительность звука и нужную задержку между звуками,чтобы они состыковались,учитывая,что продолжительность моего звука 200 мс?
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
25.11.2016, 13:27 #44
КАВ, пример в архиве.
-при нажатии на start создается поток в котором начинает воспроизводится звук (синус)
-продолжительность звука 201 мс
-частота 250 Гц
-после окончания звука сразу же начинается следующий звук
-за генерацию блока данных отвечает функция generate, за коррекцию фазы - функция getNextP
-следующий звук имеет частоту больше частоты предыдущего звука на 2 Гц (если вы закомментируете строку f += 2 звук будет иметь постоянную частоту 250 Гц)
-продолжительность звука специально выбрана равной 201 мс для того что бы на этом интервале размещалось нецелое количество периодов звуковой волны начальной частоты (250 Гц, период волны 1 / 250 = 4 мс) и стыковка соседних звуков проходила не при начальных условиях (если вы закомментируете строку p = getNextP(f, p) для того что бы коррекция фазы нового звука не производилась вы услышите щелчки - это артефакты стыковки звуков со скачком амплитуды)
-если поменять продолжительность звука на 200 мс, то звук постоянной частоты 250 Гц не будет содержать щелчков даже без коррекции фазы так как на интервале 200 мс размещается целое количество периодов звуковой волны и стыковка звуков проходит при начальных условиях
-если вы увеличите ступень на которую меняется частота (вместо 2 Гц поставите большее значение, например, 5 или 10 Гц) вы услышите звук напоминающий уу-уу-уу - я думаю это не артефакт стыковки - это так наше ухо воспринимает существенные изменения частоты
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.example.soundtest;
 
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
public class MainActivity extends Activity {
    private static Thread thread;
    
    private static AudioTrack at;
    
    private static int nSamplesPerSec = 44100;
    private static float dt = 1f / nSamplesPerSec;
    
    private static int nChannels = 1;
    private static int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
    
    private static int bitsPerSample = 16;
    private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    
    private static int duration = 201;
    private static int nSamplesPerChannel = nSamplesPerSec * duration / 1000;
    private static int nSamples = nSamplesPerChannel * nChannels;
 
    private static float d = nSamplesPerChannel * dt;
    
    private static short[] buffer = new short[nSamples];
 
    private static void generate(float f, float p) {
        for (int i = 0; i < nSamplesPerChannel; i++) {
            buffer[i] = (short)(0x7FFF * Math.sin(2 * Math.PI * (f * dt * i + p)));
        }
    }
    
    private static float getNextP(float f1, float p1) {
        float T = 1 / f1;
        float p2 = p1 + d / T;
        p2 -= (int)p2;
        return p2;
    }
 
    private static void interrupt(Thread thread) {
        if (thread != null) {
            thread.interrupt();
        }
    }
    
    private static void wait(Thread thread) {
        if (thread != null) {
            try {
                thread.join();
            } catch (InterruptedException e) {
            }
        }
    }
 
    private static void start() {
        stop();
        thread = new Thread(new Runnable() {
            public void run() {
                float f = 250;
                float p = 0;
                while (!Thread.currentThread().isInterrupted()) {
                    generate(f, p);
                    if (at != null) {
                        at.write(buffer, 0, nSamples);
                    } else {
                        try {
                            at = new AudioTrack(AudioManager.STREAM_MUSIC, nSamplesPerSec, channelConfig, audioFormat, nSamples * bitsPerSample / 8, AudioTrack.MODE_STREAM);
                        } catch (IllegalArgumentException e) {
                            return;
                        }
                        at.write(buffer, 0, nSamples);
                        try {
                            at.play();
                        } catch (IllegalStateException e) {
                            return;
                        }
                    }
                    p = getNextP(f, p);
                    f += 2;
                }
            }
        });
        thread.start();
    }
    
    private static void stop() {
        interrupt(thread);
        
        if (at != null) {
            try {
                at.pause();
            } catch (IllegalStateException e) {
            }
        }
        
        wait(thread);
        
        if (at != null) {
            at.flush();
            at.release();
            at = null;
        }
    }
    
    private Button startButton;
    private Button stopButton;
    
    private OnClickListener startButtonClick = new OnClickListener() {
        @Override
        public void onClick(View arg0) {
            start();
        }
    };
 
    private OnClickListener stopButtonClick = new OnClickListener() {
        @Override
        public void onClick(View arg0) {
            stop();
        }
    };
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        startButton = (Button)findViewById(R.id.start);
        startButton.setOnClickListener(startButtonClick);
 
        stopButton = (Button)findViewById(R.id.stop);
        stopButton.setOnClickListener(stopButtonClick);
    }
}
1
Вложения
Тип файла: rar soundtest.rar (1.14 Мб, 6 просмотров)
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
25.11.2016, 21:48 #45
Огромное Вам спасибо за код. Я адаптировал Ваш генератор под свой код и щелчки почти исчезли. Единственное что,когда я разбираю математическую функцию,которую ввёл пользователь с шагом 0.1,чтобы построить звуковой график,щелчки всё же иногда проявляются,но я думаю,что хоть я и привёл значения типа double,которые возвращает метод,к типу float,происходят ошибки вычисления и соответственно,нестыковка сигналов. Также если очень сильно прислушаться,можно услышать щелчки на очень высоких частотах в Вашем генераторе звука и в моём коде. Но я думаю что это проблема происходит по той же причине. Огромное Вам спасибо за код,ведь Вы мне помогли написать одну из важных частей моей программы. Кстати может можно так преобразовать блок данных,который используется для генерации звука,чтобы можно было воспроизводить несколько звуков одновременно? Я понимаю,что можно,к примеру,пройтись по массиву,и в энный элемент записать первую частоту,а в н+первый - вторую,т е в каждом канале играть свою частоту,при этом массив будет в два раза больше,т.к у нас будет 2 канала. Но что делать,если я хочу воспроизвести 3 и более частот?
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
26.11.2016, 07:26 #46
КАВ, сложный звук это сумма нескольких волн. Разделять их на треки не нужно

Добавлено через 4 минуты
Что касается щелчков на высоких частотах - скажите значение частоты, проверим
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
26.11.2016, 13:47 #47
ели слышимые щелчки наблюдаются на частотах от 660 до примерно 700 гц. По поводу сложного звука,правильно ли я понял,что звук на нескольких частотах для конкретного бита будет рассчитываться как-то так: 32767*(Math.sin(2* Math.PI*(f1*dt*i+p1)+(Math.sin(2* Math.PI*(f2*dt*i+p2)+:+(Math.sin(2* Math.PI*(fn*dt*i+pn)),где f1,f2,fn частоты,а p1,p2,pn - их фазы,i - номер бита,а dt - период колебаний на частоте 48000 =1/48000/
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
26.11.2016, 14:06 #48
КАВ, да, только у каждого может быть своя амплитуда не обязательно единица и все это дело потом впихивается в 0x7FFF
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
26.11.2016, 14:52 #49
А я думал что 0x7fff это и есть амплитуда.
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
26.11.2016, 15:05 #50
КАВ, есть синусы. Каждый со своей амплитудой. Мы их сложили и у сложного сигнала тоже будет максимальное и минимальное значение. Мы хотим его нормализовать. Для этого сделаем так что бы максимум и минимум не выходили за диапазон +/-x7FFF. Это можно сделать смасштабировав сигнал
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
26.11.2016, 15:27 #51
Я Вас не совсем понял,как смаштабировать сигнал? Может быть Вы имейте ввиду,что нужно подобрать такие значения амплитуд для каждой частоты,чтобы в сумме они давали 32767?
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
26.11.2016, 15:40 #52
КАВ, грустно товарищи... как масштабировать? Умножить его на такое число и прибавить к произведению такое число чтобы значение сигнала всегда было в заданном интервале.
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
26.11.2016, 17:54 #53
Спасибо. Я почти всё понял,только что Вы имейте ввиду под интервалом: от 0 до 1,или от 0 до 32767? Ещё у меня есть вопрос,как регулировать баланс звука? Ведь в моём случае звук не обязательно должен быть посередине. Просто я это привёл как пример,чтобы было понятно,о чём я говорю. Сложность ещё в том,что с пятого андроида можно управлять только общей громкостью каналов в аудиотреке.
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
26.11.2016, 18:03 #54
КАВ, обычно диапазон 0x7FFF если это 16 бит, как менять мнимое положение источника звука я вам писал выше
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
27.11.2016, 23:17 #55
Хотелось бы ещё уточнить,Ваш генератор звука работает для любой продолжительности звука,или для продолжительности звука 200 мс? Просто при продолжительности звука 200 мс и даже 100 мс генератор работает практически нормально,а вот если я к примеру хочу задать функцию x*x к примеру от 0 до 100 с продолжительностью звука 5 мс,иногда можно услышать "солидные" щелчки. Конечно,пока что меня вполне устраивает звук с шагом 0.1,но не все функции нормально звучат на этом шаге,а на шаге 0.01 они звучат более плавно,но,как я уже писал ранее,иногда возникают щелчки.
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
28.11.2016, 11:53 #56
КАВ, звук продолжительностью 5 мс? На таком интервале поместится 1 период для 250 Гц например - на кой вам такой "звук"? 201 мс - это размер порции данных которые будет воспроизводить устройство. К звуку это число не имеет никакого отношения и может влиять на него чисто технически если вы будете задавать полоумно малые значения.

Добавлено через 5 часов 30 минут
Цитата Сообщение от КАВ Посмотреть сообщение
ели слышимые щелчки наблюдаются на частотах от 660 до примерно 700 гц
не услышал

Добавлено через 1 минуту
Цитата Сообщение от КАВ Посмотреть сообщение
с продолжительностью звука 5 мс,иногда можно услышать "солидные" щелчки
на частоте 660 Гц не услышал
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
01.12.2016, 22:11 #57
По поводу положения звука,Вы писали только,как сделать,чтобы он был посередине. А вот как сделать,чтобы он был ближе к правому каналу,или ближе к левому,но не прямо в левом или правом канале,я такого у Вас не нашёл.
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
02.12.2016, 08:18 #58
КАВ, если задано 1:1 это центр, если 1:0 это лево, а если 1:0.56 к примеру это где-то между центром и лево
1
КАВ
13 / 1 / 1
Регистрация: 16.04.2016
Сообщений: 72
02.12.2016, 19:18 #59
Но начиная с пятого андроида этот метод класса audiotrack устарел и теперь можно ставить громкость только для 2-х каналов одновременно.
0
vxg
Модератор
3231 / 2034 / 319
Регистрация: 13.01.2012
Сообщений: 7,885
02.12.2016, 19:57 #60
КАВ, выход только один - прыгнуть в окно
1
02.12.2016, 19:57
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.12.2016, 19:57
Привет! Вот еще темы с решениями:

Генератор / сборник иконок
Может кто знает что то типа https://design.google.com/icons/? - но чтобы в...

Фильтрация звукового сигнала
Здравствуйте друзья, пишу работу по фильтрации звуковых сигналов (от шумов). В...

ВЧ фильтрация звукового сигнала
Добрый день! Подскажите, пожалуйста, какой фильтр лучше использовать для ВЧ...

Воспроизведение звукового сигнала
Здравствуйте, меня интересует вопрос как в командной строке воспроизвести...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru