오디오 장치를 사용하여 음악 녹음 앱을 코딩하고 있는데 결과 M4A 파일이 굉장한 윙윙 거리는 소리가 아닌 다른 것을 재생하는 데 문제가 있습니다. . 나는 이걸 사용했습니다 sourcesasreferences, 나는 모든 문제를 해결하려고 노력했습니다.원격 I/O 출력을 파일로 작성 및 인코딩 - Core Audio
AUGraph
에는 멀티 채널 믹서와 원격 I/O 노드가 2 개 있습니다. 믹서에는 두 개의 입력 콜백이 있습니다. 하나는 마이크에서 입력을 가져오고 하나는 오디오 파일에서 가져옵니다. 믹서 출력은 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];}
}
저장 방법 :
- (void) saveFile {
OSStatus status = ExtAudioFileDispose(extAudioFileRef);
NSLog(@"OSStatus(ExtAudioFileDispose): %ld\n", status);
}
이 6,내가 내 콘솔에서 볼 것입니다 :
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