2016-07-20 28 views
4

Ich habe versucht, meine Eingabe während einer Inter-App-Audiositzung auf iOS 9 aufzuzeichnen. Die Lautsprecherausgabe klingt gut, aber die aufgenommene Datei hat ein rhythmisches Klickgeräusch. Die Wellenform sieht aus wie unten ...Klicken während der Inter-App-Audioaufnahme

enter image description here

ich jede Einstellung und Parameter gezwickt habe ich denken kann, und nichts scheint zu funktionieren.

Hier sind die Formateinstellungen (Stream-Einstellungen identisch sind) ...

AudioStreamBasicDescription fileFormat; 
fileFormat.mSampleRate   = kSessionSampleRate; 
fileFormat.mFormatID   = kAudioFormatLinearPCM; 
fileFormat.mFormatFlags   = kAudioFormatFlagsNativeFloatPacked; 
fileFormat.mFramesPerPacket  = 1; 
fileFormat.mChannelsPerFrame = 1; 
fileFormat.mBitsPerChannel  = 32;  //tone is correct but there is still pops 
fileFormat.mBytesPerPacket  = sizeof(Float32); 
fileFormat.mBytesPerFrame  = sizeof(Float32); 

Hier werden die Stream-Einstellungen sind ...

 //connect instrument to output 
AudioComponentDescription componentDescription = unit.componentDescription; 
AudioComponent inputComponent = AudioComponentFindNext(NULL, &componentDescription); 
OSStatus status = AudioComponentInstanceNew(inputComponent, &_instrumentUnit); 
NSLog(@"%d",status); 
AudioUnitElement instrumentOutputBus = 0; 
AudioUnitElement ioUnitInputElement = 0; 

    //connect instrument unit to remoteIO output's input bus 
AudioUnitConnection connection; 
connection.sourceAudioUnit = _instrumentUnit; 
connection.sourceOutputNumber = instrumentOutputBus; 
connection.destInputNumber = ioUnitInputElement; 
status = AudioUnitSetProperty(_ioUnit, 
           kAudioUnitProperty_MakeConnection, 
           kAudioUnitScope_Output, 
           ioUnitInputElement, 
           &connection, 
           sizeof(connection)); 
NSLog(@"%d",status); 
UInt32 maxFrames = 1024; //I tried setting this to 4096 but it did not help 
status = AudioUnitSetProperty(_instrumentUnit, 
           kAudioUnitProperty_MaximumFramesPerSlice, 
           kAudioUnitScope_Output, 
           0, 
           &maxFrames, 
           sizeof(maxFrames)); 
NSLog(@"%d",status); 



_connectedInstrument = YES; 
_instrumentIconImageView.image = unit.icon; 
NSLog(@"Remote Instrument connected"); 
status = AudioUnitInitialize(_ioUnit); 
NSLog(@"%d",status); 
status = AudioOutputUnitStart(_ioUnit); 
NSLog(@"%d",status); 
status = AudioUnitInitialize(_instrumentUnit); 
NSLog(@"%d",status); 
[self setupFile]; 

Hier mein Rückruf ist ...

static OSStatus recordingCallback(void        *inRefCon, 
           AudioUnitRenderActionFlags   *ioActionFlags, 
           const AudioTimeStamp    *inTimeStamp, 
           UInt32        inBusNumber, 
           UInt32        inNumberFrames, 
           AudioBufferList     *ioData) 
{ 
    ViewController* This = This = (__bridge ViewController *)inRefCon; 
    if (inBusNumber == 0 && !(*ioActionFlags & kAudioUnitRenderAction_PostRenderError)) 
    { 
      ExtAudioFileWriteAsync(This->fileRef, inNumberFrames, ioData); 
    } 

    return noErr; 
} 

Full view controller code here

Danke für Ihre Hilfe.

+0

Ist dies auf einem Gerät oder dem Simulator? – dave234

+0

@Dave Es ist auf einem iPad Mini 2. – Pescolly

+0

Ich habe es herausgefunden. Ich musste die Flags überprüfen UND den Render-Callback an die IO Unit übertragen. – Pescolly

Antwort

5

Sie schreiben in die Datei vor und nach dem Rendern. Ändern Sie in Ihrem Render-Callback Ihre if-Anweisung so, dass sie nur auf Post-Rendering schreibt.

if (inBusNumber == 0 && *ioActionFlags == kAudioUnitRenderAction_PostRender){ 
    ExtAudioFileWriteAsync(This->fileRef, inNumberFrames, ioData); 
} 

ExtAudioFileWriteAsync hat einige interne Kopieren und Pufferung so ist es in Ordnung, so lange in der Render Rückruf zu verwenden, wie Sie prime es vor dem ersten Schreib.

+0

Mit Priming meinst du das? ExtAudioFileWriteAsync (DateiRef, 0, NULL); – Pescolly

+0

@Pescolly Ja, dies richtet den internen Ringpuffer ein. – dave234

1

Höchstwahrscheinlich werden Sie für sowohl überprüfen:

  • post-render Aktion Fahnen
  • Post machen Fehler

Der kritische Teil Ihres Rückruf wird wahrscheinlich muss ungefähr so ​​aussehen:

if (*ioActionFlags & kAudioUnitRenderAction_PostRender){ 
    static int TEMP_kAudioUnitRenderAction_PostRenderError = (1 << 8); 
    if (!(*ioActionFlags & TEMP_kAudioUnitRenderAction_PostRenderError)) 
    { 
     ExtAudioFileWriteAsync(This->fileRef, inNumberFrames, ioData); 
     //whichever additional code needed 
     // { … } 
    }