2016-06-03 15 views
0

Ich schrieb eine Befehlszeile c-Tool zum Erzeugen einer Sinuswelle und spielt es mit CoreAudio auf der Standard-Audio-Ausgang. Ich initialisiere ein AURenderCallbackStruct und initialisiere ein AudioUnit mit AudioUnitInitialize (wie bereits in diesem Forum diskutiert). All dies funktioniert wie vorgesehen, aber wenn es um das Schließen des Programms kommt Ich bin nicht in der Lage, die Audio Unit zu schließen, weder bei der Verwendung von AudioOutputUnitStop(player.outputUnit); noch AudioOutputUnitStop(player.outputUnit); noch AudioComponentInstanceDispose(player.outputUnit);CoreAudio: AudioUnit kann nicht gestoppt oder nicht initialisiert werden

Die Reihenfolge des Erscheinens dieser Anrufe in dem Code nicht ändert das Verhalten. Das Programm wird ohne Fehlermeldungen kompiliert, aber der Sinus ist noch hörbar, solange der Rest des Programms läuft.

Hier ist der Code, den ich für die Initialisierung des Audio Unit mit:

void CreateAndConnectOutputUnit (ToneGenerator *player) { 

    AudioComponentDescription outputcd = {0}; 
    outputcd.componentType = kAudioUnitType_Output; 
    outputcd.componentSubType = kAudioUnitSubType_DefaultOutput; 
    outputcd.componentManufacturer = kAudioUnitManufacturer_Apple; 

    AudioComponent comp = AudioComponentFindNext (NULL, &outputcd); 
    if (comp == NULL) { 
     printf ("can't get output unit"); 
     exit (-1); 
    } 

    AudioComponentInstanceNew(comp, &player->outputUnit); 

    // register render callback 
    AURenderCallbackStruct input; 
    input.inputProc = SineWaveRenderCallback; 
    input.inputProcRefCon = player; 
    AudioUnitSetProperty(player->outputUnit, 
         kAudioUnitProperty_SetRenderCallback, 
         kAudioUnitScope_Output, 
         0, 
         &input, 
         sizeof(input); 

    // initialize unit 
    AudioUnitInitialize(player->outputUnit); 
} 

In meinem Hauptprogramm mir das Audio Unit und die Sinuswelle fange.

void main { 
    // code for doing various things 

    ToneGenerator player = {0};   // create a sound object 
    CreateAndConnectOutputUnit (&player); 
    AudioOutputUnitStart(player.outputUnit); 

    // waiting to listen to the sine wave 
    sleep(3); 

    // attempt to stop the sound output 
    AudioComponentInstanceDispose(player.outputUnit); 
    AudioUnitUninitialize(player.outputUnit); 
    AudioOutputUnitStop(player.outputUnit); 

    //additional code that should be executed without sine wave being audible 
} 

Wie ich bin neu in beide, dieses Forum sowie Programmierung in Xcode Ich hoffe, dass ich dieses Problem in einer Weise erklären könnte, dass Sie mir helfen können, und ich hoffe, dass ich nicht die vermißte antworten Sie irgendwo im Forum, während Sie nach einer Lösung suchen.

Vielen Dank im Voraus für Ihre Zeit und Eingabe,

Stefan

+0

Ich würde damit beginnen, dafür zu sorgen, dass die Dinge in der umgekehrten Reihenfolge ablaufen: InstanceNew; Initialize; Start -> Stop; Uninitialize; InstanceDispose und Überprüfung der Rückgabewerte aller Funktionen. (Sie geben Fehlercodes aus einem Grund zurück, und der Grund ist nicht, dass sie ignoriert werden sollten.) – molbdnilo

+0

Vielen Dank für Ihre Antwort molbdnilo. Das Ändern der Reihenfolge scheint logisch zu sein, ändert jedoch nicht das Verhalten. Die Funktionen werfen Fehler -2147450879. Ich habe keine nützlichen Informationen zu diesen Fehlern gefunden. Ich benutze diese Funktion zum Abfangen der Fehler: [link] (https://github.com/Xcode-Snippets/Objective-C/blob/master/checkerror.m). –

Antwort

1

Sie sollten Ihre Audio-Einheit in einer logischen Reihenfolge verwalten und Unmanage. Es macht keinen Sinn, die Wiedergabe auf einer bereits nicht initialisierten Audioeinheit zu stoppen, die zuvor in der Mitte der Wiedergabe zuvor entsorgt worden war. Anstatt dass, versuchen Sie die folgende Reihenfolge:

AudioOutputUnitStop(player.outputUnit);   //first stops playback 
AudioUnitUninitialize(player.outputUnit);   //then deallocates unit's resources 
AudioComponentInstanceDispose(player.outputUnit); //finally disposes of the AU itself 

Die Sinus-Befehlszeile App sind Sie nach ist eine gut ausgearbeitete Lektion in this textbook. Bitte lesen Sie es Schritt für Schritt.

Last but not least, Ihre Frage hat nichts mit C++ zu tun, CoreAudio ist eine Plain-C-API, also C++ in Ihrem Titel und Tag sind falsch und irreführend.

+0

Vielen Dank für Ihr Feedback. Wie oben beschrieben, änderte ich die Reihenfolge des Aufrufs der Funktionen ohne Änderung. Mein Code basiert tatsächlich auf dem verknüpften Lehrbuch.Wenn ich den ursprünglichen Code ausführe, scheint es zu funktionieren, so dass ich erwarte, dass das Problem im zusätzlichen Code erscheint. Ich werde mich damit beschäftigen. Ich habe auch den Link zu C++ korrigiert. –

+0

Bereiten Sie sich auf eine steile Lernkurve und maximale Lesekonzentration vor. Diese API ist _very_ verbous. Was mir scheint, ist, dass Sie versuchen, Mittel zur Kontrolle der Lebensdauer der Einheit zu entwickeln, die aussagekräftiger sind als 'sleep (3)'. Es ist wichtig, dass Sie den Rest Ihres Programms nicht von Ihrem AU "trennen", während es noch spielt. – user3078414

0

Eine Audio-Einheit wird in einem asynchronen Thread ausgeführt, der möglicherweise nicht sofort gestoppt wird, wenn Sie AudioOutputUnitStop aufrufen. Daher kann es besser sein, einen Bruchteil einer Sekunde zu warten (mindestens ein paar Audio-Callback-Pufferdauern in der Zeit), bevor AudioUnitUninitialize und AudioComponentInstanceDispose auf einer möglicherweise noch laufenden Audioeinheit aufgerufen werden.

Überprüfen Sie außerdem, ob der player.outputUnit-Wert eine gültige Einheit (und keine nicht initialisierte oder verworfene Variable) zum Zeitpunkt des Stopps der Einheit ist.

Verwandte Themen