Форум программистов, компьютерный форум, киберфорум
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
 
tip42
3 / 3 / 0
Регистрация: 02.03.2015
Сообщений: 18
#1

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

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

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

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

Отображение содержимого звукового буфера в логах - Программирование Android
while(!stopped) { short buffer = buffers; //short buffer = new short; ...

Как заполнить заголовок звукового файла? - Программирование Android
public class AudioRecord { byte header = new byte; byte channels ; void run() { channels = 1;

Генератор String - Программирование Android
Добрый день, уважаемые форумчане. Уже который день пытаюсь решить маленькую проблему, но не получается. Возможно ли при помощи Random...

Генератор кубиков - Программирование Android
Всем привет) Помогите новичку... Познания нулевые и вот решил попробовать сделать что-то похожее на игральные кости (кубики). Кодить...

Сделать звуковой генератор - Программирование Android
Всем привет. Ребят, как выдать в наушник звук импульсами примерно прямоугольной формы? Нужно сделать звуковой генератор от ~10 до...

73
Vladimir93
44 / 44 / 5
Регистрация: 28.06.2015
Сообщений: 190
22.08.2016, 11:02 #16
Цитата Сообщение от tip42 Посмотреть сообщение
Чет не работает.
Я сейчас доступа не имею к среде разработки. Могу схематично описать.
Рисуете разметку, на 2 EditText (для частоты и длительности) и кнопку что бы все это запускать. Все, лайот на этом закончен.
Код.
Объявляете, так же две переменных, что бы получить значения и передать в метод (double и int).
Потом, в коде, который выполняться по нажатию кнопки, получаете переменные из EditText и передаете их в метод описанный выше вот таким вот способом
Java
1
2
 AudioTrack at = generateTone(тут double переменная, тут int);
 at.play();
Если не получиться выложите код посмотрим что там не так.
0
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
23.11.2016, 01:30 #17
Здравствуйте. Очень классный генератор звука,но у меня возникли следующие вопросы: 1. Как можно улучшить качество звука,не портя его. Я пробовал использовать прямоугольную волну как у Вас в проекте,подставив одинаковые значения в параметр метода,который возвращает прямоугольную волну для конкретного элемента массива,частоты и частоты дискретизации fase и добился улучшения качества,но на высоких частотах слышны гармоники,т.е начинают наслаиваться неизвестно откуда взявшиеся низкие частоты.
2. Я пытался генерировать один звук с разными частотами,чтобы добиться плавного изменения частоты. Для этого я использовал режим STREAM класса AudioTrack,и в цикле воспроизводил и записывал новые данные в буфер аудиотрека,используя play и write методы. Всё работает прекрасно,т.е частота меняется плавно,но во время воспроизведения звука слышен треск. Подскажите пожалуйста,как правильно генерировать звук с изменяющейся частотой,чтобы не было слышно треска и звук менялся плавно. Для генерации звука я использовал функцию x*x,при этом x менялся от 0 до 100 с шагом 0.1. Частота звука равна именно этой функции.
3. Можно ли как-то более тонко управлять каналами,используя AudioTrack,т.е сделать так,чтобы звук перетекал плавно из левого канала в правый и наоборот,или звучал не вправом или левом канале а где-то посередине сверху. В общем я хочу сделать что-то вроде 3d звука.
4. Можно ли как-то генерировать и воспроизводить одновременно несколько звуков на разных частотах используя класс audiotrack? Заранее благодарю всех за помощь.
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
23.11.2016, 08:59 #18
КАВ
1 не совсем понятно о какой волне речь
2 щелчки обычно появляются при нестыковке амплитуд во время переключения, надо смотреть код
3 можно управлять балансом громкости L/R
4 можно запустив параллельно воспроизведение нескольких звуков
0
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
23.11.2016, 12:52 #19
Здравствуйте. 1. Гармоники возникают при использовании прямоугольной волны.
2. Спасибо Вам за идею,как убрать щелчки,но вроде с амплитудой у меня всё в порядке. Хотя полностью согласен с Вами,что без кода тут трудно что-то подсказать,поэтому ниже будет код моего класса,который генерирует звук по синусоидальной волне.
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
class beeper {
public static short[] sample;
public static AudioTrack audioTrack;
public static void createAudioTrack() {
if(audioTrack==null) {
audioTrack=new AudioTrack(AudioManager.STREAM_MUSIC,48000, AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT,sample.length*(Short.SIZE / 8), AudioTrack.MODE_STREAM,AudioTrack.STATE_INITIALIZED);
if(Build.VERSION.SDK_INT<21 ) audioTrack.setStereoVolume(AudioTrack.getMaxVolume(),AudioTrack.getMaxVolume()); else audioTrack.setVolume(AudioTrack.getMaxVolume());
}
}
private static short getSquareSignalPerTact(int tact ,double freqHz,double mPhase) {
// Используется для генерации звука с помощью прямоугольной волны,но я не использую этот метод,из-за проблемы,о которой я писал выше.
return Math.sin(mPhase+(2 * Math.PI * tact / (((double) 48000)/ freqHz))) < 0 ? Short.MIN_VALUE : Short.MAX_VALUE;
}
static void sound(double frequency,double durationMs) {
sample = new short[(int)(2*48000*durationMs/1000)];
for (int i = 0; i < sample.length; i+=2) {
sample[i] = (short) (Math.sin(2* Math.PI * i / (48000/frequency))*0x7FFF);
sample[i+1] = (short) (Math.sin(2* Math.PI * i / (48000/frequency))*0x7FFF);
}
createAudioTrack();
audioTrack.play();
audioTrack.write(sample, 0, sample.length);
}
public static void audioTrackdestroy() {
    if (audioTrack != null) {
audioTrack.stop();
audioTrack.flush();
audioTrack.release();
audioTrack = null;
}
}
}
Так как в классе MainActivity используется генерация звука только в одной кнопке,далее будет её код. переменные a,b,steppchange и result типа double,а также thread и другие переменные объявлены в начале класса. Во избежании неточности при вычислении значений функции x*x,которая связана с ошибками округления в типе double,я округляю полученное значение до 4-х знаков. Чтобы избежать тормозов,я обернул мой код,который генерирует звук,в thread.
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
public void button0 (View view) {
try {
a=Double.valueOf(edit1.getText().toString());
b=Double.valueOf(edit2.getText().toString());
canbuildfunction=true;
}
catch (NumberFormatException e) {
canbuildfunction =false;
show(getString(R.string.NumberFormatException));
}
if(canbuildfunction) {
if(a<b) steppchange=0.1; else if(a>b) steppchange=-0.1; else steppchange =0;
thread=new Thread(new Runnable() {
@Override
public void run() {
while((a<b && steppchange>0) || (a>b &&steppchange<0)) {
build=true;
a=new BigDecimal(a).setScale(4, BigDecimal.ROUND_HALF_DOWN).doubleValue();
result=new BigDecimal(a*a).setScale(4, BigDecimal.ROUND_HALF_DOWN).doubleValue();
if(canbuildfunction && result>=0) beeper.sound(result+100,200); else if(canbuildfunction &&result<0) beeper.sound(result-100,200);
show(getString(R.string.x)+a+","+getString(R.string.y)+result);
a+=steppchange;
}
}
});
}
}
3. Подскажите пожалуйста,если знайте,как управлять балансом в audiotrack и как одновременно воспроизводить несколько звуков. Заранее благодарю всех за помощь.
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
23.11.2016, 13:37 #20
КАВ
1 обычно сигнал синусоидальный или у вас по другому? так или иначе неограниченно увеличивая частоту вы можете достигнуть частоты близкой к той на которой работает железо формирующее звук. в этом случае могут появится артефакты.
2 функция sound генерирует блок данных которые суть сигнал заданной частоты и продолжительности. если продолжительность не кратна периоду колебаний, то в момент окончания ваш сигнал будет иметь ненулевую амплитуду в то время как продолжающий его сигнал другой частоты начинается с нулевой амплитуды. согласуйте амплитуды и направления изменения амплитуд заложив в процедуру генерации сигнала начальную фазу.
3 MediaPlayer метод setVolume наверное
1
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
23.11.2016, 15:54 #21
Помогите пожалуйста,как её правильно рассчитать и согласовать. Если Вас не затруднит,дайте пожалуйста пример кода,который делает это. Что касается setVolume,я имею в виду другое. Как сделать так,чтобы звук был слышен не в левом канале или в правом,а где-то посередине.
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
23.11.2016, 16:22 #22
Цитата Сообщение от КАВ Посмотреть сообщение
Как сделать так,чтобы звук был слышен не в левом канале или в правом,а где-то посередине.
поставить одинаковую громкость на обоих каналах
1
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
23.11.2016, 16:47 #23
Я Вас не совсем понял. Просто если я поставлю одинаковую громкость на 2 канала,то звук и будет звучать в 2-х каналах,а мне нужно чтобы он звучал,к примеру,посередине. Ещё подскажите пожалуйста,если Вы знайте,формулу для расчёта амплитуды,просто хочется избавиться от щелчков во время воспроизведения звука.
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
23.11.2016, 16:56 #24
КАВ
про согласование фаз.
пусть есть сигнал y = a sin ( 2 pi (f t + p) ),
a - амплитуда
pi - число пи
f - частота [Гц]
f = 1 / T, T - период [с]
t - время [с]
p - фаза [доли периода]
пусть мы генерируем этот сигнал в течение времени D
на этом времени укладывается n = D / T периодов. так же останется хвост. его можно получить выделив дробную часть n. это хвост будет в долях периода. по этой величине мы сможем понять
-были ли мы на подъеме в области положительных амплитуд (T < 0.25)
-были ли мы на спуске в области положительных амплитуд (0.25 < T < 0.5)
-были ли мы на спуске в области отрицательных амплитуд (0.5 < T < 0.75)
-были ли мы на подъеме в области отрицательных амплитуд (0.75 < T)
амплитуду в конце мы знаем.
область мы знаем.
из уравнения сигнала можно получить фазу которая правильно пристыкует новый сигнал к тому который отзвучал

Добавлено через 1 минуту
КАВ, если громкость одинаковая в обоих каналах человек воспринимает это так как будто источник звука находится между левым и правым динамиком
1
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
23.11.2016, 23:05 #25
Я Вас не совсем понял. Согласно Вашему уравнению y = a*sin ( 2*pi*(f*t + p) f умножается на t,а потом к этому прибавляется p. f по Вашей формуле равно 1/T. Но я не понял,как рассчитать T. Также мне не понятно,чем отличается время D от времени t? Ещё не понятно,какое значение можно подставить в качестве a. Вроде все подставляют 32767,но я не уверен,правильно ли это. Как потом Ваше уравнение применить,учитывая,что у нас есть frequency и samplerate,где frequency - Частота звукового сигнала в герцах,а sampleRate частота дискретизации. Помогите пожалуйста вывести общую формулу для генерации звука в каждом бите,чтобы звуковые сигналы правильно стыковались. Заранее огромное спасибо за помощь.

Добавлено через 4 часа 20 минут
Ещё хочу спросить,что значит начальная фаза. Просто в начале Вы писали,что её нужно задавать,а в последнем сообщении Вы писали,что её нужно вычислять. Если её нужно задавать в формуле,то какую фазу лучше задать? Предыдущие вопросы остаются актуальны.
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
24.11.2016, 09:57 #26
КАВ, фазу нужно вычислить по текущему сигналу что бы задать ее следующему сигналу. Период не нужно знать - я просто написал соотношение между частотой и периодом. Период - это время за которое происходит возврат амплитуды в исходное состояние, посмотрите литературу по математике раздел где рисуют графики синуса и подобного. Продолжительность - это то сколько звучит сигнал. А время - это аргумент функции. Если подставить вместо t D получим амплитуду в конце сигнала.

Добавлено через 3 часа 6 минут
КАВ, амплитуду (a) вы можете задать какую вам хочется. задавая 32767 вы просто будете получать 16 битный сигнал с максимальной громкостью (которую потом дополнительно можно будет менять задавая громкость на самом устройстве). что касается дискретизации 48 кГц то тут дело обстоит так: уравнение дает зависимость амплитуды от времени. каждую секунду вы должны разбить на 48 000 отсчетов и посчитать в полученных точках (t) амплитуду

Добавлено через 1 минуту
КАВ, я могу написать за вас код, но тогда я украду у вас радость познания и творения)
1
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
24.11.2016, 10:29 #27
То есть в качестве f можно подставить частоту делённую на частоту дискретизации и в качестве фазы следующего сигнала подставлять фазу предыдущего сигнала,правильно ли я Вас понял? Извините пожалуйста за очень глупый вопрос,но как вывести фазу из того уравнения,которое Вы давали раньше?
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
24.11.2016, 10:42 #28
КАВ
имеем y = a sin ( 2 pi (f t + p) )
для того что бы получить блок данных который будет восприниматься устройством как звук с частотой дискретизации 48 кГц продолжительностью D мы считаем y для t равного
0
dt
dt * 2
dt * 3
...
D
где
dt = 1 / 48000 - float естественно
в самом конце мы будем иметь
y = a sin ( 2 pi (f D + p) ) - мы подставили вместо t значение D
именно с такой начальной амплитуды должен стартовать следующий звук. кроме амплитуды нам нужно знать характер ее изменения что бы не попасть на ситуацию когда она снижалась, а мы будем генерировать звук начинающийся с нужной амплитуды, но при этом она будет возрастать, что может восприниматься человеческим ухом как разновидность артефакта.
выразим фазу из уравнения
очевидно будет что то вроде
p = arcsin (y / a) / (2 pi)
у этой фазы может быть двойник соответствующий такой же амплитуде но другой области. по идее эта фаза будет расположена симметрично "горбу" волны
1
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 51
24.11.2016, 12:26 #29
Подскажите пожалуйста,как считать фазу для первого сигнала. Пока что я прибавил к нему 0.1 в качестве фазы,но теперь звука вообще не слышно. Ниже будет мой код,который заполняет массив с данными,согласно Вашим рассуждениям.
Java
1
2
3
for (int i = 0; i < sample.length; i++) {
sample[i] = (short) (32767*Math.sin(2* Math.PI*(frequency*i*(float) (1/48000)+0.01))*0x7FFF);
}
0
vxg
Модератор
3199 / 2002 / 230
Регистрация: 13.01.2012
Сообщений: 7,753
24.11.2016, 12:35 #30
КАВ, для самого первого фаза может быть какой угодно например ноль. фаза нужна лишь для последующих сигналов. кстати, что бы было быстрее и понятнее - предлагаю вам генерировать звуки с продолжительностью исключительно кратной периоду. тогда они все будут стыковаться по нулевой возрастающей амплитуде и не нужно будет ничего считать. ну а с добавкой +/- периода к времени звучания я думаю кошмара не будет
1
24.11.2016, 12:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.11.2016, 12:35
Привет! Вот еще темы с ответами:

Генератор / сборник иконок - Программирование Android
Может кто знает что то типа https://design.google.com/icons/? - но чтобы в разные цвета можно было генерировать - Что там не так? - То...

Непрерывная генерация сигнала - Программирование Android
Нужно сделать генератор сигналов, нашел код рабочий: // originally from...

Распознавание звукового сигнала - Искусственный интеллект
Здравствуйте, прошу прощения если немного не в тот раздел. Изучаю Data Science, заинтересовался такой вещью - как, имея записанный звуковой...

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


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

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

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