Las unidades de audio de iOS pasan a través

Estoy intentando escribir una aplicación iOS que pasará el sonido recibido del micrófono al altavoz sin ningún cambio. He leído docs y guías de apple. Elegí el primer patrón de esteguía. Pero no pasa nada, el silencio. Como puede ver, he intentado usar el AUAudioGraph (comentado) - 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 código actual

#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 sharedInstance];
    NSError *error = nil;
    rate = 44100.0;
    [sess setPreferredSampleRate: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

Respuestas a la pregunta(1)

Su respuesta a la pregunta