iOS AudioUnits pasa por

Estoy intentando escribir una aplicación de iOS que transmita el sonido recibido del micrófono al altavoz sin ningún cambio. He leído documentos y guías de Apple. Escogí el primer patrón de esta guía . Pero nada sucede: silencio. Como puede ver, he intentado utilizar el AUAudioGraph (comentado), el mismo resultado (¿lo necesito en este simple ejemplo?).

Vi algunos ejemplos en Internet donde se utilizan devoluciones de llamada, pero no quiero usar ninguno. ¿Es posible?

¿Alguna sugerencia? Gracias por la atención.

El codigo real

#import "AudioController.h" #import <AudioToolbox/AudioToolbox.h> #import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioServices.h> #define kInputBus 1 #define kOutputBus 0 @interface AudioController () { AudioComponentDescription desc; AudioComponent component; AudioUnit unit; AudioStreamBasicDescription audioFormat; double rate; //AUGraph graph; } @end @implementation AudioController - (void) setUp { AVAudioSession *sess = [AVAudioSession shanetworkingInstance]; NSError *error = nil; rate = 44100.0; [sess setPrefernetworkingSampleRate:rate error:&error]; [sess setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]; [sess setActive:YES error:&error]; rate = [sess sampleRate]; if (error) { NSLog(@"%@", error); } NSLog(@"Init..."); [self createUnitDesc]; [self getComponent]; [self getAudioUnit]; [self enableIORec]; [self enableIOPb]; [self createFormat]; [self applyFormat]; OSStatus err = AudioUnitInitialize(unit); if (noErr != err) { [self showStatus:err]; } /*NewAUGraph(&graph); AUNode node; AUGraphAddNode(graph, &desc, &node); AUGraphInitialize(graph); AUGraphOpen(graph);*/ } - (void) createUnitDesc { desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_RemoteIO; desc.componentFlags = 0; desc.componentFlagsMask = 0; desc.componentManufacturer = kAudioUnitManufacturer_Apple; } - (void) getComponent { component = AudioComponentFindNext(NULL, &desc); } - (void) getAudioUnit { OSStatus res = AudioComponentInstanceNew(component, &unit); if (noErr != res) { [self showStatus:res]; } } - (void) enableIORec { UInt32 flag = 1; OSStatus err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); if (noErr != err) { [self showStatus:err]; } } - (void) enableIOPb { UInt32 flag = 1; OSStatus err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); if (noErr != err) { [self showStatus:err]; } } - (void) createFormat { // Describe format audioFormat.mSampleRate = rate;//44100.00; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = 2; audioFormat.mBytesPerFrame = 2; } - (void) applyFormat { OSStatus err = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof(audioFormat)); if (noErr != err) { [self showStatus:err]; } } - (void) start { NSLog(@"starting"); OSStatus err = AudioOutputUnitStart(unit); //AUGraphStart(graph); if (noErr != err) { [self showStatus:err]; } } - (void) end { NSLog(@"ending"); OSStatus err = AudioOutputUnitStop(unit); //AUGraphStop(graph); if (noErr != err) { [self showStatus:err]; } } - (void) showStatus:(OSStatus) st{ NSString *text = nil; switch (st) { case kAudioUnitErr_CannotDoInCurrentContext: text = @"kAudioUnitErr_CannotDoInCurrentContext"; break; case kAudioUnitErr_FailedInitialization: text = @"kAudioUnitErr_FailedInitialization"; break; case kAudioUnitErr_FileNotSpecified: text = @"kAudioUnitErr_FileNotSpecified"; break; case kAudioUnitErr_FormatNotSupported: text = @"kAudioUnitErr_FormatNotSupported"; break; case kAudioUnitErr_IllegalInstrument: text = @"kAudioUnitErr_IllegalInstrument"; break; case kAudioUnitErr_Initialized: text = @"kAudioUnitErr_Initialized"; break; case kAudioUnitErr_InstrumentTypeNotFound: text = @"kAudioUnitErr_InstrumentTypeNotFound"; break; case kAudioUnitErr_InvalidElement: text = @"kAudioUnitErr_InvalidElement"; break; case kAudioUnitErr_InvalidFile: text = @"kAudioUnitErr_InvalidFile"; break; case kAudioUnitErr_InvalidOfflineRender: text = @"kAudioUnitErr_InvalidOfflineRender"; break; case kAudioUnitErr_InvalidParameter: text = @"kAudioUnitErr_InvalidParameter"; break; case kAudioUnitErr_InvalidProperty: text = @"kAudioUnitErr_InvalidProperty"; break; case kAudioUnitErr_InvalidPropertyValue: text = @"kAudioUnitErr_InvalidPropertyValue"; break; case kAudioUnitErr_InvalidScope: text = @"kAudioUnitErr_InvalidScope"; break; case kAudioUnitErr_NoConnection: text = @"kAudioUnitErr_NoConnection"; break; case kAudioUnitErr_PropertyNotInUse: text = @"kAudioUnitErr_PropertyNotInUse"; break; case kAudioUnitErr_PropertyNotWritable: text = @"kAudioUnitErr_PropertyNotWritable"; break; case kAudioUnitErr_TooManyFramesToProcess: text = @"kAudioUnitErr_TooManyFramesToProcess"; break; case kAudioUnitErr_Unauthorized: text = @"kAudioUnitErr_Unauthorized"; break; case kAudioUnitErr_Uninitialized: text = @"kAudioUnitErr_Uninitialized"; break; case kAudioUnitErr_UnknownFileType: text = @"kAudioUnitErr_UnknownFileType"; break; default: text = @"unknown error"; } NSLog(@"TRANSLATED_ERROR = %li = %@", st, text); } - (void) dealloc { AudioUnitUninitialize(unit); [super dealloc]; } @end 

Como Warrenm dijo que establecer una connection entre los elementos Remote IO ayudó. Entonces, el código colocado después de la initialization realizada:

 AudioUnitConnection conn; conn.destInputNumber = kOutputBus; conn.sourceAudioUnit = unit; conn.sourceOutputNumber = kInputBus; err = AudioUnitSetProperty(unit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, kOutputBus, &conn, sizeof(conn)); if (noErr != err) { [self showStatus:err]; } 

ACTUALIZACIÓN Para que otros usuarios puedan usar la solución, publicaré el código completo aquí:

El file .h

 #import <Foundation/Foundation.h> @interface AudioController : NSObject - (void)setUp; - (void)start; - (void)end; @end 

El file .m

 #import "AudioController.h" #import <AudioToolbox/AudioToolbox.h> #import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioServices.h> #define kInputBus 1 #define kOutputBus 0 @interface AudioController () { AudioComponentDescription desc; AudioComponent component; AudioUnit unit; AudioStreamBasicDescription audioFormat; double rate; } @end @implementation AudioController - (void)setUp { AVAudioSession *sess = [AVAudioSession shanetworkingInstance]; NSError *error = nil; rate = 44100.0; [sess setPrefernetworkingSampleRate:rate error:&error]; [sess setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]; [sess setActive:YES error:&error]; rate = [sess sampleRate]; if (error) { NSLog(@"%@", error); } NSLog(@"Initing"); [self createUnitDesc]; [self getComponent]; [self getAudioUnit]; [self enableIORec]; [self enableIOPb]; [self createFormat]; [self applyFormat]; OSStatus err = AudioUnitInitialize(unit); if (noErr != err) { [self showStatus:err]; } AudioUnitConnection conn; conn.destInputNumber = 0; conn.sourceAudioUnit = unit; conn.sourceOutputNumber = 1; err = AudioUnitSetProperty(unit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &conn, sizeof(conn)); if (noErr != err) { [self showStatus:err]; } } - (void)createUnitDesc { desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_RemoteIO; desc.componentFlags = 0; desc.componentFlagsMask = 0; desc.componentManufacturer = kAudioUnitManufacturer_Apple; } - (void)getComponent { component = AudioComponentFindNext(NULL, &desc); } - (void)getAudioUnit { OSStatus res = AudioComponentInstanceNew(component, &unit); if (noErr != res) { [self showStatus:res]; } } - (void)enableIORec { UInt32 flag = 1; OSStatus err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); if (noErr != err) { [self showStatus:err]; } } - (void)enableIOPb { UInt32 flag = 1; OSStatus err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); if (noErr != err) { [self showStatus:err]; } } - (void)createFormat { // Describe format audioFormat.mSampleRate = rate; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = 2; audioFormat.mBytesPerFrame = 2; } - (void)applyFormat { OSStatus err = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof(audioFormat)); if (noErr != err) { [self showStatus:err]; } } - (void)start { NSLog(@"starting"); OSStatus err = AudioOutputUnitStart(unit); if (noErr != err) { [self showStatus:err]; } } - (void)end { NSLog(@"ending"); OSStatus err = AudioOutputUnitStop(unit); if (noErr != err) { [self showStatus:err]; } } - (void)showStatus:(OSStatus)st { NSString *text = nil; switch (st) { case kAudioUnitErr_CannotDoInCurrentContext: text = @"kAudioUnitErr_CannotDoInCurrentContext"; break; case kAudioUnitErr_FailedInitialization: text = @"kAudioUnitErr_FailedInitialization"; break; case kAudioUnitErr_FileNotSpecified: text = @"kAudioUnitErr_FileNotSpecified"; break; case kAudioUnitErr_FormatNotSupported: text = @"kAudioUnitErr_FormatNotSupported"; break; case kAudioUnitErr_IllegalInstrument: text = @"kAudioUnitErr_IllegalInstrument"; break; case kAudioUnitErr_Initialized: text = @"kAudioUnitErr_Initialized"; break; case kAudioUnitErr_InstrumentTypeNotFound: text = @"kAudioUnitErr_InstrumentTypeNotFound"; break; case kAudioUnitErr_InvalidElement: text = @"kAudioUnitErr_InvalidElement"; break; case kAudioUnitErr_InvalidFile: text = @"kAudioUnitErr_InvalidFile"; break; case kAudioUnitErr_InvalidOfflineRender: text = @"kAudioUnitErr_InvalidOfflineRender"; break; case kAudioUnitErr_InvalidParameter: text = @"kAudioUnitErr_InvalidParameter"; break; case kAudioUnitErr_InvalidProperty: text = @"kAudioUnitErr_InvalidProperty"; break; case kAudioUnitErr_InvalidPropertyValue: text = @"kAudioUnitErr_InvalidPropertyValue"; break; case kAudioUnitErr_InvalidScope: text = @"kAudioUnitErr_InvalidScope"; break; case kAudioUnitErr_NoConnection: text = @"kAudioUnitErr_NoConnection"; break; case kAudioUnitErr_PropertyNotInUse: text = @"kAudioUnitErr_PropertyNotInUse"; break; case kAudioUnitErr_PropertyNotWritable: text = @"kAudioUnitErr_PropertyNotWritable"; break; case kAudioUnitErr_TooManyFramesToProcess: text = @"kAudioUnitErr_TooManyFramesToProcess"; break; case kAudioUnitErr_Unauthorized: text = @"kAudioUnitErr_Unauthorized"; break; case kAudioUnitErr_Uninitialized: text = @"kAudioUnitErr_Uninitialized"; break; case kAudioUnitErr_UnknownFileType: text = @"kAudioUnitErr_UnknownFileType"; break; default: text = @"unknown error"; } NSLog(@"TRANSLATED_ERROR = %li = %@", st, text); } - (void)dealloc { AudioUnitUninitialize(unit); [super dealloc]; } @end