Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
 
 
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
#1

Генератор звука нужной частоты - Android

07.09.2016, 01:42. Просмотров 1004. Ответов 27
Метки нет (Все метки)

Всем привет.
Что то не могу найти на просторах Интернета, как можно воспроизвести звук нужной частоты? Вариант с файлом не подходит, ибо пользователь должен подбирать частоту по его личной благозвучности. Для азбуки Морзе.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
07.09.2016, 02:03     Генератор звука нужной частоты #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Генератор звукового сигнала
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
07.09.2016, 13:35  [ТС]     Генератор звука нужной частоты #3
Tester64, Спасибо. Странно, что нет готового метода, типа Beep ( int Hz, int Ms).

Добавлено через 3 часа 36 минут
Странно. Срабатывает 25 раз. На 26 останавливается приложение:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Генератор звука
    private AudioTrack generateTone(double freqHz, int durationMs)
    {
        int sampleRate = 48000;  // 44100 Hz
 
        int count = (int)( sampleRate * 2.0 * (durationMs / 1000.0)) & ~1;
        short[] samples = new short[count];
 
        for(int i = 0; i < count; i += 2){
            short sample = (short)(Math.sin(2 * Math.PI * i / (sampleRate / freqHz)) * 0x7FFF);
            samples[i + 0] = sample;
        }
 
        AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                count * (Short.SIZE / 8), AudioTrack.MODE_STATIC);
 
        track.write(samples, 0, count);
 
        return track;
    }
Вызываю по кнопке или из потока. Разницы нет, на 26 раз зависает.
Java
1
2
AudioTrack at = generateTone(1000, 100); // freqHz, durationMs
            at.play();
Добавлено через 46 минут
В эмуляторе виснет на 31-36 вызове, а в телефоне стабильно на 26. Причём даже если выйти из активности, не не выходить из приложения и потом вернуться в активность, то счётчик до вылета не сбрасывается.
vxg
Модератор
3016 / 1818 / 188
Регистрация: 13.01.2012
Сообщений: 6,892
07.09.2016, 13:44     Генератор звука нужной частоты #4
gvsp, ну так наверное надо освободить ресурсы
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
07.09.2016, 14:05  [ТС]     Генератор звука нужной частоты #5
vxg, А как? track.stop(); не помог. Больше идей нет.
REALIST07
Автор FAQ
Автор FAQ
174 / 174 / 13
Регистрация: 11.06.2010
Сообщений: 932
07.09.2016, 14:10     Генератор звука нужной частоты #6
gvsp, как вариант можно записать в файл и считать из него

Добавлено через 15 секунд
В той же теме есть как это делается
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
07.09.2016, 14:30  [ТС]     Генератор звука нужной частоты #7
Цитата Сообщение от REALIST07 Посмотреть сообщение
как вариант можно записать в файл и считать из него
Не хотелось бы. Это будет время и ресурсы занимать. А нужен мгновенный отклик на клавишу.
vxg
Модератор
3016 / 1818 / 188
Регистрация: 13.01.2012
Сообщений: 6,892
07.09.2016, 15:26     Генератор звука нужной частоты #8
Цитата Сообщение от gvsp Посмотреть сообщение
А как?
Java
1
2
3
4
5
6
7
            try {
                track.pause();
            } catch (IllegalStateException e) {
            }
            track.flush();
            track.release();
            track = null;
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
07.09.2016, 15:44  [ТС]     Генератор звука нужной частоты #9
vxg, К сожалению так не работает:
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
// Генератор звука
    private AudioTrack generateTone(double freqHz, int durationMs)
    {
        int sampleRate = 48000;  // 44100 Hz
 
        int count = (int)( sampleRate * 2.0 * (durationMs / 1000.0)) & ~1;
        short[] samples = new short[count];
 
        for(int i = 0; i < count; i += 2){
            short sample = (short)(Math.sin(2 * Math.PI * i / (sampleRate / freqHz)) * 0x7FFF);
            samples[i + 0] = sample;
        }
 
        AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                count * (Short.SIZE / 8), AudioTrack.MODE_STATIC);
 
        track.write(samples, 0, count);
 
        try {
            track.pause();
        } catch (IllegalStateException e) {
        }
        track.flush();
        track.release();
        track = null;
        return track;
}
При наличии строчек track.release(); или track = null; вылетает сразу при попытке воспроизвести звук.
REALIST07
Автор FAQ
Автор FAQ
174 / 174 / 13
Регистрация: 11.06.2010
Сообщений: 932
07.09.2016, 16:09     Генератор звука нужной частоты #10
gvsp, не в обиду братан,но ты программировать вообще умеешь?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
AudioTrack at = generateTone(1000, 100); // freqHz, durationMs
            at.play();
clearMemory(at);
 
void clearMemory(Audiotrack track) {
try {
            track.pause();
        } catch (IllegalStateException e) {
        }
        track.flush();
        track.release();
        track = null;
}
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
07.09.2016, 17:52  [ТС]     Генератор звука нужной частоты #11
REALIST07, Да фактически нет, но написал достаточно не маленькое и не простое приложение. А тут вот опять ничего подходящего не нашёл. Думаю опыта немного есть. Из старого проекта тоже всё возьму. А тут такая засада на ровном месте, простой бип на Яве не сделать. Чёй то всё равно не выходит:
Java
1
2
3
4
5
6
// кнопка RF А
    public void onClickRF(View view) {
            AudioTrack at = generateTone(1000, 100); // freqHz, durationMs freq, durationDot
            at.play();
            clearMemory(at);
    }
Так понятно вылетает ибо онклик выполняет всё одновременно. А если без clearMemory(at);
то at красная, а определять его не хочет - подчёркивает красным. Ну и в track = null track серый;
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
// Генератор звука
    private AudioTrack generateTone(double freqHz, int durationMs)
    {
        int sampleRate = 48000;  // 44100 Hz
        int count = (int)( sampleRate * 2.0 * (durationMs / 1000.0)) & ~1;
        short[] samples = new short[count];
        for(int i = 0; i < count; i += 2){
            short sample = (short)(Math.sin(2 * Math.PI * i / (sampleRate / freqHz)) * 0x7FFF);
            samples[i + 0] = sample;
        }
        AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                count * (Short.SIZE / 8), AudioTrack.MODE_STATIC);
        track.write(samples, 0, count);
        return track;
        AudioTrack at = generateTone(1000, 100);
        clearMemory(at);
    }
 
    void clearMemory(AudioTrack track) {
        try {
            track.pause();
        } catch (IllegalStateException e) {
        }
        track.flush();
        track.release();
        track = null;
    }
REALIST07
Автор FAQ
Автор FAQ
174 / 174 / 13
Регистрация: 11.06.2010
Сообщений: 932
07.09.2016, 19:45     Генератор звука нужной частоты #12
gvsp,

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
// кнопка RF А
    public void onClickRF(View view) {
            AudioTrack at = generateTone(1000, 100); // freqHz, durationMs freq, durationDot
            at.play();
            clearMemory(at);
    }
 
 
// Генератор звука
    private AudioTrack generateTone(double freqHz, int durationMs)
    {
        int sampleRate = 48000;  // 44100 Hz
        int count = (int)( sampleRate * 2.0 * (durationMs / 1000.0)) & ~1;
        short[] samples = new short[count];
        for(int i = 0; i < count; i += 2){
            short sample = (short)(Math.sin(2 * Math.PI * i / (sampleRate / freqHz)) * 0x7FFF);
            samples[i + 0] = sample;
        }
        AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                count * (Short.SIZE / 8), AudioTrack.MODE_STATIC);
        track.write(samples, 0, count);
        return track;
    }
 
 
void clearMemory(AudioTrack track) {
        try {
            track.pause();
        } catch (IllegalStateException e) {
        }
        track.flush();
        track.release();
        track = null;
    }
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
07.09.2016, 21:16  [ТС]     Генератор звука нужной частоты #13
REALIST07, У меня так и есть. Но в track = null; - track серый. Ну и звук не выводится потому, что все события онклик обрабатываются одновременно. Попробую вынести в поток.
REALIST07
Автор FAQ
Автор FAQ
174 / 174 / 13
Регистрация: 11.06.2010
Сообщений: 932
07.09.2016, 22:14     Генератор звука нужной частоты #14
gvsp, дык

Java
1
2
3
4
5
6
7
public void onClickRF(View view) { 
 
     switch(view.getId()) {
    case R.id.button1 : break;
    case R.id.button2 : break;
}
}
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
08.09.2016, 11:46  [ТС]     Генератор звука нужной частоты #15
REALIST07, В общем оказалось не так просто. Вот такое, не работает, ибо вторая строчка сразу убивает первую.
Java
1
2
at.play();
clearMemory(at);
Пришлось вынести это дело в потоки и сделать так:
Java
1
2
3
4
5
 AudioTrack at = generateTone(freq, duration); // freqHz, duration
            at.play();
            Thread.sleep(duration); // ждём отработки звука
            clearMemory(at); 
            Thread.sleep(duration); // даём время очистить ресурсы перед выводом следующего звука
Добавлено через 29 минут
Генератор плохо заканчивает звук. Он обрывается со щелчком.
vxg
Модератор
3016 / 1818 / 188
Регистрация: 13.01.2012
Сообщений: 6,892
08.09.2016, 12:20     Генератор звука нужной частоты #16
gvsp, щелчок это потому что в самом конце не нулевая амплитуда. либо обрывайте когда синусоида проходит ноль либо снижайте амплитуду синусоиды до нуля перед выключением либо костылите с громкостью
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
08.09.2016, 14:42  [ТС]     Генератор звука нужной частоты #17
В общем кривая какая то метода. Ещё и при первом запуске генератор как бы раскачивается. Звук длительностью менее полусекунды может вообще не проиграть. Да и второй третий короткий звук играет с заметными задержками. Потом работает стабильно, но стоит не генерировать звук более 6 секунд и опять ему разогрев нужен. Пришлось даже добавить, чтобы первый звук проигрывался:
Java
1
2
3
                soundtaskini = new SoundTaskIni();
                soundtaskini.execute();
// далее вызовы нужных звуков
duration около 60 милисекунд.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// инициализатор возбуждения генератора
    class SoundTaskIni extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                AudioTrack at = generateTone(1, duration); // freqHz, durationMs
                at.play();
                Thread.sleep(duration);
                clearMemory(at);
                Thread.sleep(duration);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
vxg
Модератор
3016 / 1818 / 188
Регистрация: 13.01.2012
Сообщений: 6,892
08.09.2016, 15:09     Генератор звука нужной частоты #18
Цитата Сообщение от gvsp Посмотреть сообщение
с заметными задержками
все относительно. сколько именно задержки?

Добавлено через 1 минуту
как вариант - не убивать трек, а лишь заменять/добавлять данные
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
08.09.2016, 15:15  [ТС]     Генератор звука нужной частоты #19
vxg, ну, если бы не морзянку делал, то и не замечал бы. А так если первой вызывалась точка на 60 миллисекунд, то она вообще не проигрывалась. После введения проигрывания вначале беззвучного файла, стал и первый звук слышен, но всё равно первая точка на 60 мс, почти не отличима от тире на 180 мс. А где то к третьему - четвёртому звуку всё приходит в норму. В общем не критично, но странно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.09.2016, 09:35     Генератор звука нужной частоты
Еще ссылки по теме:

Android Получение частоты ЦП
Генератор / сборник иконок Android
Android Прочитать данные из нужной БД
Генератор звукового сигнала Android
Запись звука unity Android

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

Или воспользуйтесь поиском по форуму:
gvsp
13 / 2 / 0
Регистрация: 10.11.2015
Сообщений: 71
12.09.2016, 09:35  [ТС]     Генератор звука нужной частоты #20
Очень плохо работает, звук не чистый и часто заикается (одну и туже последовательность из звуков 60 мкс, 180 мкс и пауз 60 мкс всё время проигрывает по разному) и в конце звука щелчок. Хотя телефон не такой уж и слабенький. Память и процессор не загружены. Никто не может переделать в прямоугольные импульсы (синусоида сама почти получится индуктивностью динамика, а считать меньше) и с уходом в конце частоты вниз или вверх из области слышимости (чтобы щелчок убрать).
Yandex
Объявления
12.09.2016, 09:35     Генератор звука нужной частоты
Ответ Создать тему
Опции темы

Текущее время: 09:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru