gpt4 book ai didi

ios - 将 float 组写入音频文件

转载 作者:行者123 更新时间:2023-11-29 12:43:47 25 4
gpt4 key购买 nike

我有一个名为 _recordingSamples 的 Float32 值数组,我希望将其写入音频文件。 _recordingLength 的值约为 390000。我使用以下代码:

NSString *outputPath = @"/Users/evanjackson/output.caf";
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:outputPath contents:nil attributes:nil];

AudioStreamBasicDescription _audioFormat;
_audioFormat.mSampleRate = 44100.0;
_audioFormat.mFormatID = kAudioFormatLinearPCM;
_audioFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
_audioFormat.mChannelsPerFrame = 1;
_audioFormat.mBitsPerChannel = 32;
_audioFormat.mBytesPerFrame = 4;
_audioFormat.mFramesPerPacket = 1;
_audioFormat.mBytesPerPacket = _audioFormat.mFramesPerPacket * _audioFormat.mBytesPerFrame;

UInt32 lengthPropertySize = sizeof(SInt64);
ExtAudioFileRef filteredAudio;
NSURL *destinationURL = [NSURL URLWithString:outputPath];
OSStatus status = ExtAudioFileCreateWithURL((__bridge CFURLRef)destinationURL, kAudioFileCAFType, &_audioFormat, NULL, kAudioFileFlags_EraseFile, &filteredAudio);
printf("Status: %d\n", status);
//ExtAudioFileOpenURL((__bridge CFURLRef)[NSURL fileURLWithPath:outputPath], &filteredAudio);
const AudioStreamBasicDescription audioFormat = [del audioFormat];
status = ExtAudioFileSetProperty(filteredAudio, kExtAudioFileProperty_ClientDataFormat, sizeof(audioFormat), &audioFormat);
printf("Status: %d\n", status);
status = ExtAudioFileGetProperty(filteredAudio, kExtAudioFileProperty_FileLengthFrames, &lengthPropertySize, &_recordingLength);
printf("Status: %d\n", status);
AudioBufferList *buffers = (AudioBufferList *)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer));
buffers->mNumberBuffers = 1;
for (int i = 0; i < buffers->mNumberBuffers; i++) {
buffers->mBuffers[0].mData = _recordingSamples;
buffers->mBuffers[0].mNumberChannels = 1;
buffers->mBuffers[0].mDataByteSize = _recordingLength * sizeof(Float32);
}

status = ExtAudioFileWrite(filteredAudio, _recordingLength, buffers);
printf("Status: %d\n", status);

所有状态都返回为 0,文件已创建(4 字节)但 Quicktime 不会打开它并返回错误 -12842,编译器会提供以下消息:

libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
(lldb)

有人知道怎么回事吗?提前致谢。

最佳答案

废弃我在问题中发布的代码。我在这里找到了解决方案:How to write array of float values to audio file in Core Audio? .看第一个答案。我去了给定的链接,下载了源代码,然后将 EAFWrite.h 和 EAFWrite.mm 添加到我的项目中。该类假定音频将从多个缓冲区(即:二维数组)读取,但需要它与一维数组一起使用,因此我修改了函数 writeToFloats 如下:

-(OSStatus) writeFloats:(long)numFrames fromArray:(float *)data
{
OSStatus err = noErr;

if (!data) return -1;
if (!numFrames) return -1;

AudioBufferList *abl = AllocateAudioBufferList(mStreamFormat.mChannelsPerFrame, numFrames*sizeof(short));
if (!abl) return -1;

abl->mBuffers[0].mNumberChannels = 1;
abl->mBuffers[0].mDataByteSize = numFrames*sizeof(short);
short *buffer = (short*)abl->mBuffers[0].mData;
for (long v = 0; v < numFrames; v++) {
if (data[v] > 0.999)
data[v] = 0.999;
else if (data[v] < -1)
data[v] = -1;
buffer[v] = (short)(data[v]*32768.f);
}

abl->mBuffers[0].mData = buffer;

err = ExtAudioFileWrite(mOutputAudioFile, numFrames, abl);

DestroyAudioBufferList(abl);

if(err != noErr)
{
char formatID[5];
*(UInt32 *)formatID = CFSwapInt32HostToBig(err);
formatID[4] = '\0';
fprintf(stderr, "ExtAudioFileWrite FAILED! %d '%-4.4s'\n",(int)err, formatID);
return err;
}

return err;

}

要调用此函数,您需要:

NSString *outputPath = @"outputFile.caf"
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:outputPath contents:nil attributes:nil];
NSURL* fileURL = [NSURL URLWithString:outputPath];

EAFWrite *writer = [[EAFWrite alloc] init];
[writer openFileForWrite:fileURL sr:44100.0 channels:1 wordLength:32 type:kAudioFileCAFType];
[writer writeFloats:_recordingLength fromArray:_recordingSamples];

关于ios - 将 float 组写入音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24188678/

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