Воспроизведение сгенерированного аудио на iPhone - PullRequest
2 голосов
/ 10 ноября 2009

В качестве одноразового проекта для iPhone, чтобы научить меня работать с Objective C и библиотеками iPhone, я пытался создать приложение, которое будет воспроизводить различные виды случайных шумов.

Я строил шум как массив чисел с плавающей точкой, нормализованных от [-1,1].

Я застрял в игре сгенерированных данных. Кажется, это должно быть довольно просто, но я рассмотрел использование AudioUnit и AVAudioPlayer, и ни один из них не кажется оптимальным.

AudioUnit, очевидно, требует несколько сотен строк кода, чтобы выполнить даже эту простую задачу, и AVAudioPlayer, похоже, требует, чтобы я преобразовал аудио в то, что CoreAudio может понять (насколько я могу сказать, это означает, что LPCM помещен в файл WAV) .

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

Ответы [ 2 ]

3 голосов
/ 10 ноября 2009

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

AudioStreamBasicDescription format;
memset(&format, 0, sizeof(format));
format.mSampleRate = 44100;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
format.mChannelsPerFrame = 1;
format.mBitsPerChannel = 16;
format.mBytesPerFrame = (format.mBitsPerChannel / 8) * format.mChannelsPerFrame;
format.mFramesPerPacket = 1;
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;

AudioQueueRef queue;

AudioQueueNewOutput(&format, 
            AQPlayer::AQOutputCallback, 
            this,  // opaque reference to whatever you like
            CFRunLoopGetCurrent(), 
            kCFRunLoopCommonModes, 
            0, 
            &queue); 

const int bufferSize = 0xA000;  // 48K - around 1/2 sec of 44kHz 16 bit mono PCM        
for (int i = 0; i < kNumberBuffers; ++i)
    AudioQueueAllocateBufferWithPacketDescriptions(queue, bufferSize, 0, &mBuffers[i]);

AudioQueueSetParameter(queue, kAudioQueueParam_Volume, 1.0);

UInt32 category = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);

AudioSessionSetActive(true);

// prime the queue with some data before starting
for (int i = 0; i < kNumberBuffers; ++i)
    OutputCallback(queue, mBuffers[i]);

AudioQueueStart(queue, NULL);

Код выше относится к этому обратному вызову вывода. Каждый раз, когда выполняется этот обратный вызов, заполните переданный буфер сгенерированным аудио. Здесь я наполняю его случайным шумом.

void OutputCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) {
    // Fill 
    //AQPlayer* that = (AQPlayer*) inUserData;
    inCompleteAQBuffer->mAudioDataByteSize = next->mAudioDataBytesCapacity; 
    for (int i = 0; i < inCompleteAQBuffer->mAudioDataByteSize; ++i)
        next->mAudioData[i] = rand();
    AudioQueueEnqueueBuffer(queue, inCompleteAQBuffer, 0, NULL);
 }
0 голосов
/ 10 ноября 2009

Звучит так, будто вы пришли с платформы, на которой был простой встроенный генератор тона. IPhone не имеет ничего подобного. Проще воспроизводить простые звуки из звуковых файлов. AudioUnit для фактической обработки и генерации настоящей музыки.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...