2012-02-20 4 views
3

Я просто работаю над получением образцов для обработки с микрофона. У меня есть аудиоустройство, настроенное для ввода и вывода, и оба имеют обратные вызовы визуализации. Мой вопрос касается обратного вызова для обратного вызова микрофона.kAudioUnitProperty_ShouldAllocateBuffer не имеет эффекта

Я хочу, чтобы ядро-аудио выделяло буфер в обратном вызове микрофона для меня.

UInt32 shouldAllocateBuffer = 1; 
AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer)); 

Выполнение этого, однако, всегда приводит к указателю NULL ioData в обратном вызове. Я задерживаю выделение моего собственного буфера?

Входной

static OSStatus recordingCallback(void *inRefCon, 
          AudioUnitRenderActionFlags *ioActionFlags, 
          const AudioTimeStamp *inTimeStamp, 
          UInt32 inBusNumber, 
          UInt32 inNumberFrames, 
          AudioBufferList *ioData) { 

OSStatus status; 
status = AudioUnitRender(audioUnit, 
         ioActionFlags, 
         inTimeStamp, 
         inBusNumber, 
         inNumberFrames, 
         ioData); // ioData is null here 
} 

Воспроизведение

static OSStatus playbackCallback(void *inRefCon, 
            AudioUnitRenderActionFlags *ioActionFlags, 
            const AudioTimeStamp *inTimeStamp, 
            UInt32 inBusNumber, 
            UInt32 inNumberFrames, 
            AudioBufferList *ioData) {  
// ioData is not NULL here but I get silence in the headphones. 
    return noErr; 
} 

ответ

4

AudioUnitRender по-прежнему ожидает параметр AudioBufferList (ioData), чтобы быть не-NULL.

Если ioData является указателем на AudioBufferList, то буфером, который должен быть, является ioData-> mBuffers [0] .mData для большинства случаев (см. docs). Если вы не выделяете буферы, список буферов, вероятно, должен быть локальной переменной, поскольку он действителен только для обратного вызова.

Итак, в основном используйте локальную переменную, а не ioData.

Обратите внимание, что вам все равно необходимо настроить AudioBufferList в соответствии с топологией, которую вы описываете.

Вот пример:

AudioBufferList bufferList; 
bufferList.mNumberBuffers = 1; 
bufferList.mBuffers[0].mData = NULL; 
OSStatus status; 
status = AudioUnitRender(audioUnit, 
         ioActionFlags, 
         inTimeStamp, 
         inBusNumber, 
         inNumberFrames, 
         &bufferList); // bufferList.mBuffers[0].mData is null 
// Use the input data in now valid bufferList.mBuffers[0].mData 
// note the buffer is only valid for the callback. 

Обратите внимание, что если вам нужно больше, чем один буфер (вы, вероятно, нет, даже для стерео), вы можете использовать таНос, чтобы увеличить размер массива mBuffers.

+0

, так что независимо от того, когда вы в обратном вызове записи должны назначить свой собственный буфер? Кроме того, если я хочу использовать этот захваченный звук в обратном вызове воспроизведения, я, вероятно, должен скопировать локальные данные буфера в какой-то другой автономный буфер для копирования на обратные вызовы ioData? – dubbeat

+0

mData NULL, поэтому AudioUnit назначает и предоставляет это для вас. Это отличается от предоставления вашего собственного - если вы предоставляете свои собственные буферы, вам нужно сначала их размонтировать и освободить их позже. Если вы хотите захватить его для последующего использования, вы можете скопировать его в другой буфер, но это не так эффективно - вы, вероятно, должны просто предоставить свои собственные буферы в этом случае. –

+0

Поймать 22. Если вы не предоставляете свои собственные буферы и не хотите данных, вам придется копировать данные в свой собственный буфер (ы) в любом случае. – hotpaw2

Смежные вопросы