Grabación desde RemoteIO: el .caf resultante es el tono más lento + distorsionado

Así que he reunido algunas rutinas para grabar audio basadas en algunas publicaciones aquí. Las publicaciones a las que he hecho referencia son:aquí yaquí, junto con la lectura de los sitios a los que hacen referencia.

Mi configuración: Tengo un AUGraph existente: (varios AUSamplers -> Mixer -> RemoteIO). Los AUSamplers están conectados a pistas en una instancia de MusicPlayer. Eso funciona bien, pero quiero añadirle una grabación.

La grabación está funcionando pero el .caf resultante es el tono / tempo cambiado más lento + tiene una mala calidad de sonido. ¿Debe haber algo mal con el formato que estoy especificando?

¿Alguien puede ver esto y decirme dónde estoy configurando el formato incorrectamente?

EDITAR: ¿Podría ser esto un problema estéreo / mono? Quiero grabar en mono.

Establecí el formato de transmisión en la instancia de RemoteIO a esto:

<code>   AudioStreamBasicDescription audioFormat;

audioFormat.mSampleRate         = 44100.00;
audioFormat.mFormatID           = kAudioFormatLinearPCM;
audioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket    = 1;
audioFormat.mChannelsPerFrame   = 1;
audioFormat.mBitsPerChannel     = 16;
audioFormat.mBytesPerPacket     = 2;
audioFormat.mBytesPerFrame      = 2;

// Apply format
result = AudioUnitSetProperty(ioUnit, 
                              kAudioUnitProperty_StreamFormat, 
                              kAudioUnitScope_Output, 
                              kInputBus, 
                              &audioFormat, 
                              sizeof(audioFormat));
</code>

Luego, desde una acción de botón, creo un fileRef y adjunto un renderCallback a la instancia de RemoteIO:

<code>- (void)startRecording
{

OSStatus result;

AudioStreamBasicDescription audioFormat;

audioFormat.mSampleRate         = 44100.00;
audioFormat.mFormatID           = kAudioFormatLinearPCM;
audioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket    = 1;
audioFormat.mChannelsPerFrame   = 1;
audioFormat.mBitsPerChannel     = 16;
audioFormat.mBytesPerPacket     = 2;
audioFormat.mBytesPerFrame      = 2;

NSArray  *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory];
CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, 
                                                        (__bridge CFStringRef)destinationFilePath, 
                                                        kCFURLPOSIXPathStyle, 
                                                        false);

result = ExtAudioFileCreateWithURL(destinationURL, 
                                   kAudioFileWAVEType, 
                                   &audioFormat, 
                                   NULL, 
                                   kAudioFileFlags_EraseFile, 
                                   &extAudioFileRef);  

CFRelease(destinationURL);
NSAssert(result == noErr, @"Couldn't create file for writing");

result = ExtAudioFileSetProperty(extAudioFileRef, 
                                 kExtAudioFileProperty_ClientDataFormat, 
                                 sizeof(AudioStreamBasicDescription), 
                                 &audioFormat);

NSAssert(result == noErr, @"Couldn't create file for format");

result =  ExtAudioFileWriteAsync(extAudioFileRef, 0, NULL);
NSAssert(result == noErr, @"Couldn't initialize write buffers for audio file");   


printf("Adding render to remoteIO     \n");
result = AudioUnitAddRenderNotify(ioUnit, renderCallback, (__bridge void*)self);
if (result) {[self printErrorMessage: @"AudioUnitAddRenderNotify" withStatus: result]; return;}
 }
</code>

Finalmente, en mi rendercallback escribo los datos en la fase postRender:

<code>static OSStatus renderCallback (void *                       inRefCon,
                            AudioUnitRenderActionFlags * ioActionFlags,
                            const AudioTimeStamp *       inTimeStamp,
                            UInt32                       inBusNumber,
                            UInt32                       inNumberFrames,
                            AudioBufferList *            ioData) 
{

OSStatus result;
   if (*ioActionFlags == kAudioUnitRenderAction_PostRender){
    double timeInSeconds = inTimeStamp->mSampleTime / kSampleRate;
    printf("%fs inBusNumber: %lu inNumberFrames: %lu \n", timeInSeconds, inBusNumber, inNumberFrames);

    MusicPlayerController* THIS = (__bridge MusicPlayerController *)inRefCon;

   result =  ExtAudioFileWriteAsync(THIS->extAudioFileRef, inNumberFrames, ioData);
    if(result) printf("ExtAudioFileWriteAsync %ld \n", result);

  }

return noErr; 
}
</code>

Respuestas a la pregunta(1)

Su respuesta a la pregunta