2012-05-07 15 views
7

私は、オーディオユニットを使用して音楽レコーディングアプリケーションをコーディングしています。私の結果M4Aファイルに騒々しい騒音以外のものを再生するにはいくつか問題があります。 。私はこれらを使用しましたsourcesasreferences、私はトラブルシューティングのためにすべてを試しました。リモートI/O出力をファイルに書き込んでエンコードする - Core Audio

マルチチャネルミキサーとリモートI/Oの2つのノードを持つAUGraphがあります。私はミキサーに2つの入力コールバックを持っています.1つは、マイクからの入力を引き出すものと、もう1つはオーディオファイルからのものです。ミキサ出力は、I/Oユニットの出力スコープの入力エレメントに接続されています。これにより、同時I/Oが可能になります。

コールバック

static OSStatus recordAndSaveCallback (void *    inRefCon, 
             AudioUnitRenderActionFlags * ioActionFlags, 
             const AudioTimeStamp *  inTimeStamp, 
             UInt32      inBusNumber, 
             UInt32      inNumberFrames, 
             AudioBufferList *   ioData) 
{ 
    Mixer* THIS = (__bridge Mixer*)inRefCon; 
    AudioBufferList bufferList; 

    OSStatus status; 
    status = AudioUnitRender(THIS.ioUnit,  
          ioActionFlags, 
          inTimeStamp, 
          0, 
          inNumberFrames, 
          &bufferList); 

    SInt16 samples[inNumberFrames]; // A large enough size to not have to worry about buffer overrun 
    memset (&samples, 0, sizeof (samples)); 

    bufferList.mNumberBuffers = 1; 
    bufferList.mBuffers[0].mData = samples; 
    bufferList.mBuffers[0].mNumberChannels = 1; 
    bufferList.mBuffers[0].mDataByteSize = inNumberFrames*sizeof(SInt16); 

    OSStatus result; 
    if (*ioActionFlags == kAudioUnitRenderAction_PostRender) { 
     result = ExtAudioFileWriteAsync(THIS.extAudioFileRef, inNumberFrames, &bufferList); 
     if(result) printf("ExtAudioFileWriteAsync %ld \n", result);} 
    return noErr; 
} 

記録方式:

- (void)recordFile 
{  
    OSStatus result; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *recordFile = [documentsDirectory stringByAppendingPathComponent: @"audio.m4a"]; 

    CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, 
                  (__bridge CFStringRef)recordFile, 
                  kCFURLPOSIXPathStyle, 
                  false);  

    AudioStreamBasicDescription destinationFormat; 
    memset(&destinationFormat, 0, sizeof(destinationFormat)); 
    destinationFormat.mChannelsPerFrame = 1; 
    destinationFormat.mFormatID = kAudioFormatMPEG4AAC; 
    UInt32 size = sizeof(destinationFormat); 
    result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &destinationFormat);   
    if(result) printf("AudioFormatGetProperty %ld \n", result);  


    result = ExtAudioFileCreateWithURL(destinationURL, 
             kAudioFileM4AType, 
             &destinationFormat, 
             NULL, 
             kAudioFileFlags_EraseFile, 
             &extAudioFileRef); 
    if(result) printf("ExtAudioFileCreateWithURL %ld \n", result); 


    AudioStreamBasicDescription clientFormat; 
    memset(&clientFormat, 0, sizeof(clientFormat)); 


    UInt32 clientsize = sizeof(clientFormat); 
    result = AudioUnitGetProperty(ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &clientFormat, &clientsize); 
    if(result) printf("AudioUnitGetProperty %ld \n", result); 

    UInt32 codec = kAppleHardwareAudioCodecManufacturer; 

    result = ExtAudioFileSetProperty(extAudioFileRef, 
            kExtAudioFileProperty_CodecManufacturer, 
            sizeof(codec), 
            &codec); 

    if(result) printf("ExtAudioFileSetProperty %ld \n", result); 


    result = ExtAudioFileSetProperty(extAudioFileRef,kExtAudioFileProperty_ClientDataFormat,sizeof(clientFormat), &clientFormat); 
    if(result) printf("ExtAudioFileSetProperty %ld \n", result); 


    result = ExtAudioFileWriteAsync(extAudioFileRef, 0, NULL); 
    if (result) {[self printErrorMessage: @"ExtAudioFileWriteAsync error" withStatus: result];} 

    result = AudioUnitAddRenderNotify(ioUnit, recordAndSaveCallback, (__bridge void*)self); 
    if (result) {[self printErrorMessage: @"AudioUnitAddRenderNotify" withStatus: result];}  
} 

保存方法:私はコールバックと2つのメソッドを追加した出力をキャプチャする

- (void) saveFile { 
    OSStatus status = ExtAudioFileDispose(extAudioFileRef); 
    NSLog(@"OSStatus(ExtAudioFileDispose): %ld\n", status); 

} 

これは私が私のコンソールで見るものです:

Stopping audio processing graph 
OSStatus(ExtAudioFileDispose): 0 
ExtAudioFileWriteAsync -50 
ExtAudioFileWriteAsync -50 
ExtAudioFileWriteAsync -50 

私のコードは、仕事にこれを得ている人たちのものと非常に似ているように私には思えるが、はっきりと私はしました重大な誤りを引き起こした。私は確信している他の人がこれで苦労している必要があります。

誰にも洞察力はありますか?

ありがとうございました。

+0

'recordAndSaveCallback'が終了する前に' -saveFile'メソッドが呼び出されているようです。 saveFileを呼び出す前にAUGraphを停止していますか? – sbooth

+0

グラフの問題を除外するための実験として、wavなどのよりシンプルな形式を使って試してみることをお勧めします。 ASBDは正しいことが難しいかもしれませんが、あなたがASBDが問題であると判断できる場合(私の意見)、少なくともファイルフォーマットを実験することに集中することができます。 – dubbeat

+0

コマンドラインからmacerror -50を実行すると、次のようになります。 Mac OSエラー-50(paramErr):ユーザーパラメータリストでエラーが発生しました – morgancodes

答えて

1

私は長い時間前に質問されていることを知っています。あなたはおそらく今までにこのエラーを発見したでしょう、私は同じ問題を抱えているかもしれない他の人に答えています。

私は間違っているかもしれませんが、問題はバッファ内の範囲内の変数宣言を行っているという事実から来ていると思います。

私はあなたが変更することをお勧めします

SInt16 samples[inNumberFrames]; 

recordAndSaveCallbackはあなたがスコープ宣言をすれば、件のデータは以下のように破壊される、バッファリストを埋めるためのものですので

SInt16* samples = malloc(inNumberFrames * sizeof(SInt16)); 

へスコープが終了するとすぐに

関連する問題