私は、オーディオユニットを使用して音楽レコーディングアプリケーションをコーディングしています。私の結果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
私のコードは、仕事にこれを得ている人たちのものと非常に似ているように私には思えるが、はっきりと私はしました重大な誤りを引き起こした。私は確信している他の人がこれで苦労している必要があります。
誰にも洞察力はありますか?
ありがとうございました。
'recordAndSaveCallback'が終了する前に' -saveFile'メソッドが呼び出されているようです。 saveFileを呼び出す前にAUGraphを停止していますか? – sbooth
グラフの問題を除外するための実験として、wavなどのよりシンプルな形式を使って試してみることをお勧めします。 ASBDは正しいことが難しいかもしれませんが、あなたがASBDが問題であると判断できる場合(私の意見)、少なくともファイルフォーマットを実験することに集中することができます。 – dubbeat
コマンドラインからmacerror -50を実行すると、次のようになります。 Mac OSエラー-50(paramErr):ユーザーパラメータリストでエラーが発生しました – morgancodes