Как создать и воспроизвести процедурно сгенерированный звук Chirp

#iphone #objective-c #audio #avaudioplayer

#iPhone #objective-c #Аудио #avaudioplayer

Вопрос:

Моя цель — создать класс «Chirper». Устройство chirper должно быть способно издавать процедурно сгенерированный звук chirp. Конкретная идея заключается в том, что chirp должен быть сгенерирован процедурно, а не воспроизводиться как предварительно записанный звук.

Какой самый простой способ добиться процедурно сгенерированного звука chirp на iPhone?

Комментарии:

1. Что вы подразумеваете под звуком chirp? Вы имеете в виду что-то вроде обычной прямоугольной волны или пилообразной волны, или что-то более сложное?

2. Я имею в виду что-то, что «в основном представляет собой звук, основанный на коротких синусоидальных волнах, но частота синусоидальной волны меняется с высокой частоты на низкую во время воспроизведения звука»

3. Но даже процедурно сгенерированный ровный звуковой сигнал был бы хорошим началом.

4. Вы спрашиваете, как сгенерировать chirp? Или как взаимодействовать с буфером вывода звука? Или вы просите кого-то написать это за вас?

5. Я спрашиваю, если кто-то действительно написал эту штуку, не могли бы вы поделиться способами сделать это? Если у вас есть исходный код, которым вы можете поделиться, пожалуйста, предоставьте им общий доступ. Все, что ты знаешь по этому вопросу, выкладывай, детка.

Ответ №1:

Вы можете сделать это с помощью синусоидальной волны, как вы сказали, которую вы определили бы с помощью функций sin. Создайте буфер такой длины, какой вы хотите, чтобы звук содержался в сэмплах, например:

 // 1 second chirp
float samples[44100];
  

Затем выберите начальную частоту и конечную частоту, которые вы, вероятно, хотите, чтобы начало было выше конца, что-то вроде:

 float startFreq = 1400;
float endFreq = 1100;

float thisFreq;
int x;
for(x = 0; x < 44100; x  )
{
    float lerp = float(float(x) / 44100.0);

    thisFreq = (lerp * endFreq)   ((1 - lerp) * startFreq);
    samples[x] = sin(thisFreq * x);
}
  

Во всяком случае, что-то в этом роде.

И если вы хотите жужжание или другой звук, используйте разные формы сигналов — создайте их так, чтобы они работали очень похоже на sin, и вы можете использовать их взаимозаменяемо. Таким образом, вы могли бы создать saw () sqr () tri (), и вы могли бы делать такие вещи, как комбинировать их для формирования более сложных или разнообразных звуков

========================

Редактировать —

Если вы хотите воспроизвести, вы должны быть в состоянии сделать что-то в этом роде, используя OpenAL. Важно использовать OpenAL или аналогичный iOS API для воспроизведения необработанного буфера.

     alGenBuffers (1, amp;buffer); 
    alBufferData (buffer, AL_FORMAT_MONO16, buf, size, 8000); 
    alGenSources (1, amp;source); 

    ALint state; 

    // attach buffer and play 
    alSourcei (source, AL_BUFFER, buffer); 
    alSourcePlay (source); 

    do 
    { 
        wait (200); 
        alGetSourcei (source, AL_SOURCE_STATE, amp;state); 
    } 
    while ((state == AL_PLAYING) amp;amp; play); 

    alSourceStop(source); 
    alDeleteSources (1, amp;source); 

    delete (buf) 
} 
  

Комментарии:

1. Что ж, если никто больше даже не попытается ответить, я начислю вам 50 баллов.

2. можете ли вы указать метод, который будет использоваться для воспроизведения звука?

3. Я бы использовал OpenAL, у которого не должно возникнуть проблем с воспроизведением подобных буферов — добавление в качестве редактирования к моему сообщению

Ответ №2:

Вы можете использовать код Нектариоса в обратном вызове рендеринга для удаленного устройства ввода-вывода. Кроме того, вы даже можете изменять формы сигналов в режиме реального времени (низкая задержка).