grabar sonidos reproducidos por mi aplicación de iPhone con unidades de audio

Hoy tengo muchas cosas interesantes sobre iOS y unidades de audio y he encontrado una gran cantidad de resources útiles (SO incluido).

En primer lugar , estoy confundido con algo: ¿es realmente necesario crear un gráfico de audio con la unidad de mezcla para grabar sonidos reproducidos por una aplicación?

¿O es suficiente reproducir sonidos con ObjectAL (o más simplemente llamadas AVAudioPlayer) y crear una sola unidad io remota adicionada en el bus correcto con una callback de grabación?

¡En segundo lugar , un problema más programático! Como no estoy cómodo con los conceptos de unidades de audio , trato de adaptar el proyecto Apple Mixer Host con la capacidad de grabar la mezcla resultante. Obviamente, trato de hacer esto con la publicación Michael Tyson RemoteIO .

Y obtengo un EXC_BAD_ACCESS en mi function de callback:

static OSStatus recordingCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { AudioBufferList *bufferList; // <- Fill this up with buffers (you will want to malloc it, as it's a dynamic-length list) EffectState *effectState = (EffectState *)inRefCon; AudioUnit rioUnit = effectState->rioUnit; OSStatus status; // BELOW I GET THE ERROR status = AudioUnitRender(rioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, bufferList); if (noErr != status) { NSLog(@"AudioUnitRender error"); return noErr;} // Now, we have the samples we just read sitting in buffers in bufferList //ExtAudioFileWriteAsync(effectState->audioFileRef, inNumberFrames, bufferList); return noErr; } 

Antes de usar la function de callback que hice en MixerHostAudio.h

 typedef struct { AudioUnit rioUnit; ExtAudioFileRef audioFileRef; } EffectState; 

Y crea en la interfaz:

 AudioUnit iOUnit; EffectState effectState; AudioStreamBasicDescription iOStreamFormat; ... @property AudioUnit iOUnit; @property (readwrite) AudioStreamBasicDescription iOStreamFormat; 

Luego, en el file de implementación MixerHostAudio.h :

 #define kOutputBus 0 #define kInputBus 1 ... @synthesize iOUnit; // the Remote IO unit ... result = AUGraphNodeInfo ( processingGraph, iONode, NULL, &iOUnit ); if (noErr != result) {[self printErrorMessage: @"AUGraphNodeInfo" withStatus: result]; return;} // Enable IO for recording UInt32 flag = 1; result = AudioUnitSetProperty(iOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty" withStatus: result]; return;} // Describe format iOStreamFormat.mSampleRate = 44100.00; iOStreamFormat.mFormatID = kAudioFormatLinearPCM; iOStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; iOStreamFormat.mFramesPerPacket = 1; iOStreamFormat.mChannelsPerFrame = 1; iOStreamFormat.mBitsPerChannel = 16; iOStreamFormat.mBytesPerPacket = 2; iOStreamFormat.mBytesPerFrame = 2; // Apply format result = AudioUnitSetProperty(iOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &iOStreamFormat, sizeof(iOStreamFormat)); if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty" withStatus: result]; return;} result = AudioUnitSetProperty(iOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &iOStreamFormat, sizeof(iOStreamFormat)); if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty" withStatus: result]; return;} effectState.rioUnit = iOUnit; // Set input callback ----> RECORDING AURenderCallbackStruct callbackStruct; callbackStruct.inputProc = recordingCallback; callbackStruct.inputProcRefCon = self; result = AudioUnitSetProperty(iOUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, kInputBus, &callbackStruct, sizeof(callbackStruct)); if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty" withStatus: result]; return;} 

Pero no sé qué está mal y no sé cómo digg. Nota: La estructura EffectState está presente porque también trato de integrar la capacidad del proyecto BioAudio para escribir files desde búferes.

Y tercero , me pregunto si hay algo más fácil de hacer para grabar sonidos reproducidos por mi aplicación de iPhone (es decir, micrófono excluido)?

Encontrado por mi mismo Me olvidé de encadenar así:

 callbackStruct.inputProcRefCon = &effectState; 

Esta es la parte del código. Ahora tengo nuevamente problemas conceptuales …