2012-12-01 3 views
6

Ich versuche, eine iOS-Anwendung zu schreiben, die den Ton von Mikrofon zu Lautsprecher ohne Änderungen übergeben wird. Ich habe Apple Docs und Anleitungen gelesen. Ich wählte das erste Muster aus dieser guide. Aber nichts passiert - Stille. Wie Sie sehen können, habe ich versucht, das AUAudioGraph (kommentiert) zu verwenden - das gleiche Ergebnis (brauche ich es in diesem einfachen Beispiel überhaupt?).iOS AudioUnits durchlaufen

Ich sah einige Beispiele im Internet, wo Rückrufe verwendet werden, aber ich möchte keine verwenden. Ist es möglich?

Irgendwelche Vorschläge? Danke für die Aufmerksamkeit.

Der eigentliche Code

#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 
+2

Sieht so aus, als ob du alles ziemlich genau machst. Ich sehe jedoch nicht, wo Sie das Ausgabeelement des Eingabebereichs tatsächlich mit dem Eingabeelement des Ausgabebereichs verbinden. Die RemoteIO-Einheit ist insofern speziell, als sie sowohl die Hardware-Eingabe als auch die Hardware-Ausgabe verarbeitet, aber diese sind nicht implizit verbunden, wenn die Einheit instanziiert wird. – warrenm

+0

hmmm, kannst du mir bitte einen Hinweis geben, wie ich es erreichen kann? Sprechen Sie über AUAudioGraph? Oder gibt es eine andere Möglichkeit, eine Verbindung zwischen Elementen herzustellen? Vielen Dank. –

+0

Danke, fertig mit AudioUnitConnection conn; conn.destInputNumber = 0; conn.sourceAudioUnit = Einheit; conn.sourceOutputNumber = 1; err = AudioUnitSetProperty (Einheit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, & conn, sizeof (conn)); if (noErr! = Err) { [self showStatus: err]; } –

Antwort

10

Als Warrenm Verbindungsaufbau zwischen dem Remote-IO-Elemente geholfen. So ist der Code, nachdem alle Initialisierung gesetzt getan:

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]; } 

UPDATE Um es anderen leicht zu machen, um die Lösung zu verwenden, die ich hier voll Code schreiben:

Die H-Datei

#import <Foundation/Foundation.h> 

@interface AudioController : NSObject 

- (void)setUp; 
- (void)start; 
- (void)end; 
@end 

Die .m-Datei

#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 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(@"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 
+0

Können Sie bitte erläutern, wie Sie es geschafft haben? Ich bin nicht in der Lage, es zur Arbeit zu bekommen – Srikanth

+2

@Srikanth, sehen Sie sich bitte den Code, den ich gepostet habe. Zuerst müssen Sie ein Objekt von 'AudioController' erstellen, dann' setUp' aufrufen und dann die Wiedergabe steuern, indem Sie 'start' und' end' Methoden aufrufen. –

+1

@Srikanth erstellen zwei Tasten nämlich Start und Stopp und dann für Start-Taste Ausgang, rufen Sie die Start-Methode und für Stop-Taste Ausgang, rufen Sie die End-Methode. Hoffe das hilft. – madLokesh