gpt4 book ai didi

iphone - 将远程 I/0 输出写入并编码到文件 - Core Audio

转载 作者:行者123 更新时间:2023-12-03 18:40:14 24 4
gpt4 key购买 nike

我正在使用音频单元编写音乐录制应用程序,但在让生成的 M4A 文件播放除不太令人敬畏的嗡嗡声之外的任何内容时遇到了一些问题。我用过这些SOsources as references ,并且我已经尝试了一切方法来排除故障。

我有一个带有 2 个节点的 AUGraph:一个多 channel 混音器和一个远程 I/O。我的混音器上有两个输入回调:一个从麦克风提取输入,另一个从音频文件提取。混频器输出连接到 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);

}

这是我在控制台中看到的内容:

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

在我看来,我的代码与那些让它工作的人的代码非常相似,但显然我犯了一个严重的错误。我确信肯定还有其他人正在为此苦苦挣扎。

有人有见解吗?

谢谢。

最佳答案

我知道这个问题很久以前就已经被问过,你现在可能已经发现了错误,我只是回答其他可能有同样问题的人。

我可能是错的,但我认为问题在于您正在为缓冲区进行范围内变量声明。

我建议你改变

SInt16 samples[inNumberFrames];

进入

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

由于 recordAndSaveCallback 旨在填充缓冲区列表,因此如果您进行范围内声明,则一旦范围结束,数据将被销毁。

关于iphone - 将远程 I/0 输出写入并编码到文件 - Core Audio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10481002/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com