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

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

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

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

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

Здравствуйте, кто может помочь написать простенький генератор сигнала, синус. Важна любая помощь. По интернетам смотрел информации мало. Если у кого-то есть желание, может в личку написать, может договоримся.
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 до...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
24.11.2016, 13:05 #31
Просто хотелось бы понять,почему так,как я написал в коде выше не работает и генерировать звуки не только кратные периоду,но и любой другой длинны
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
24.11.2016, 13:28 #32
КАВ, имхо не цепляйтесь за точную длину - что для вас такого случиться если в самом худшем случае вы получите звук на 60 мс дольше или короче? я вам больше скажу - никто не узнает об этом - ведь это длина блока данных. вы можете выбрать ее любой. вы можете даже плавно менять частоту при генерации блока данных. зато реализация при "удобной" длине этого чисто технического "отреза" звука будет в разы проще
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
24.11.2016, 14:55 #33
vxg,

Добавлено через 46 минут
Я исправил формулу для генерации звука,и теперь она выглядит так:
sample[i] = (short) (32767*Math.sin(2* Math.PI*(frequency*i*1/48000))*0x7FFF);
Но когда я подставляю туда амплитуду 32767,звук очень сильно искажается. Также я не совсем понял,как считать фазу для следующего сигнала,ведь Вы писали,что фаза следующего сигнала вычисляется по предыдущему сигналу,но ведь фаза предыдущего сигнала равна 0,значит фаза следующего сигнала тоже будет равна 0.,так как она по Вашим рассуждениям равна фазе предыдущего сигнала. Правильно ли я Вас понял,что фаза должна меняться в каждом бите.
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
24.11.2016, 15:09 #34
КАВ, зачем вы дважды умножаете на амплитуду? 32767 = 0x7FFF. сейчас нарисую для тех кто думает глазом
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
24.11.2016, 16:09 #35
КАВ, см рисунок
на нем два сигнала:
-первый сигнал (синий) с частотой 1 Гц имеет период 1 с (по оси икс отложено время по оси игрек уровень сигнала)
-второй сигнал (красный) с частотой 2 Гц имеет период 2 с
стыкуем их:
-на первом мы стыкуем сигналы как попало - в результате в точке переключения имеем щелчок связанный с тем что уровень сигнала меняется скачком
-на втором рисунке мы стыкуем при помощи первой вычисленной фазы - видно что вычисленных фаз две - они расположены симметрично экстремума - обе фазы подходят нам по уровню сигнала однако видно что первая фаза меняется не в том направлении
-на третьем рисунке мы стыкуем при помощи второй вычисленной фазы - она правильно продолжает форму кривой
-на четвертом рисунке мы стыкуем при помощи подбора длительности - незначительно сократив длительность первого сигнала мы сделали ее кратной периоду - благодаря этому в точке стыковки мы сразу имеем одинаковый уровень сигнала (ноль) и верное направление изменения сигнала
Миниатюры
Генератор звукового сигнала  
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
24.11.2016, 16:17 #36
...естественно второй сигнал думает что отсчет времени для него пошел с нуля, а не с 2,4 с
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
25.11.2016, 10:00 #37
Огромное Вам спасибо за пояснение. Просто когда мне нужно было сгенерировать звуковой сигнал,я искал в нете генераторы звука,но не понимал формулы,которые используются в коде и как это работает. Теперь благодаря Вам я начал понимать,как это работает. Помогите всё-таки пожалуйста с кодом. Просто раз я уже начал разбираться с этим,хочется разобраться,как это работает. Я по Вашим рассуждениям доработал код,но треск так и остался. Его неслышно только первые несколько звуков. Переменную с фазой я объявил в классе. Заранее благодарю Вас за помощь и за понимание ситуации.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static void sound(double frequency,double durationMs) {
    sample = new short[(int)(2*48000*durationMs/1000)];
    phase=Math.asin(sample[sample.length-1]/32767)/(2*Math.PI)-frequency/sample.length;
    for (int i = 0; i < sample.length; i++) {
        sample[i] = (short) (32767*Math.sin(2* Math.PI*(frequency*i/48000+phase)));
    }
    createAudioTrack();
    if(audioTrack.getPlayState()!=AudioTrack.PLAYSTATE_PLAYING) audioTrack.play();
    audioTrack.write(sample, 0, sample.length);
}
public static void audioTrackdestroy() {
    if (audioTrack != null) {
        audioTrack.stop();
        audioTrack.flush();
        audioTrack.release();
        audioTrack = null;
    }
}
 Комментарий модератора 
Используйте теги для выделения кода

Добавлено через 14 часов 14 минут
Кстати какую задержки Вы бы посоветовали поставить,близкую к 200 мс,чтобы не было щелчков? Просто может проблема совсем не в том,что Вы говорили. Если ближайшая задержка,которая подходит для генерации звука больше 1000,То напишите пожалуйста код,который правильно генерирует звуки. Заранее благодарю Вас за помощь.
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
25.11.2016, 10:35 #38
Цитата Сообщение от КАВ Посмотреть сообщение
Кстати какую задержки Вы бы посоветовали поставить,близкую к 200 мс,чтобы не было щелчков?
о какой задержке речь?
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
25.11.2016, 10:38 #39
Задержка звука
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
25.11.2016, 10:47 #40
Цитата Сообщение от КАВ Посмотреть сообщение
Задержка звука
OMG. где она у вас и зачем она вам?
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
25.11.2016, 10:51 #41
Задержка звука - сколько миллисекунд звук будет звучать. Вроде в Вашем уравнении она обозначалась D
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
25.11.2016, 10:53 #42
КАВ, как вы экстраординарно извращаете терминологию. это не задержка. это продолжительность, длительность, время звучания. все что угодно, но не задержка. D может быть разным и зависит лишь от того какого размера блок вы готовы хранить в памяти.
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
25.11.2016, 10:59 #43
Ну хорошо. Я был не прав,но всё же как подобрать нужную продолжительность звука и нужную задержку между звуками,чтобы они состыковались,учитывая,что продолжительность моего звука 200 мс?
vxg
Модератор
3158 / 1960 / 219
Регистрация: 13.01.2012
Сообщений: 7,504
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);
    }
}
Вложения
Тип файла: rar soundtest.rar (1.14 Мб, 6 просмотров)
КАВ
13 / 1 / 0
Регистрация: 16.04.2016
Сообщений: 42
25.11.2016, 21:48 #45
Огромное Вам спасибо за код. Я адаптировал Ваш генератор под свой код и щелчки почти исчезли. Единственное что,когда я разбираю математическую функцию,которую ввёл пользователь с шагом 0.1,чтобы построить звуковой график,щелчки всё же иногда проявляются,но я думаю,что хоть я и привёл значения типа double,которые возвращает метод,к типу float,происходят ошибки вычисления и соответственно,нестыковка сигналов. Также если очень сильно прислушаться,можно услышать щелчки на очень высоких частотах в Вашем генераторе звука и в моём коде. Но я думаю что это проблема происходит по той же причине. Огромное Вам спасибо за код,ведь Вы мне помогли написать одну из важных частей моей программы. Кстати может можно так преобразовать блок данных,который используется для генерации звука,чтобы можно было воспроизводить несколько звуков одновременно? Я понимаю,что можно,к примеру,пройтись по массиву,и в энный элемент записать первую частоту,а в н+первый - вторую,т е в каждом канале играть свою частоту,при этом массив будет в два раза больше,т.к у нас будет 2 канала. Но что делать,если я хочу воспроизвести 3 и более частот?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2016, 21:48
Привет! Вот еще темы с ответами:

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
25.11.2016, 21:48
Ответ Создать тему
Опции темы

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