如何使用 coreAudio 将标准化浮点值数组写入 AIFF?

Posted

技术标签:

【中文标题】如何使用 coreAudio 将标准化浮点值数组写入 AIFF?【英文标题】:How can I write an array of normalized float values to AIFF using coreAudio? 【发布时间】:2012-08-28 12:39:29 【问题描述】:

我尝试了以下代码,但在执行时会给出“fmt?”错误告诉我“此文件类型不支持数据格式”。不幸的是,我在任何地方都找不到任何参考资料来解释如果要写入 AIFF,应该如何设置 AudiostreamBasicDescription。

我已经搜索了这个问题并阅读了我能找到的所有文档,但无济于事。以前有人做过这种事情吗?任何想法我做错了什么?

//  This path is just for testing
char * filePath = "/Users/user/Desktop/reverb.aiff";

//  This value will actually be set by earlier code depending on how many mics are defined    
int channels = 1;

CFURLRef audioFileURL = CFURLCreateFromFileSystemRepresentation(NULL,
                                                                (const UInt8 *)filePath,
                                                                strlen(filePath),
                                                                false);

AudioStreamBasicDescription audioFileDescription = 0;
audioFileDescription.mFormatID         = kAudioFormatLinearPCM;
audioFileDescription.mFormatFlags      = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian;
audioFileDescription.mBitsPerChannel   = sizeof(float) * 8;
audioFileDescription.mChannelsPerFrame = channels;
audioFileDescription.mBytesPerFrame    = (audioFileDescription.mBitsPerChannel / 8) * audioFileDescription.mChannelsPerFrame;
audioFileDescription.mFramesPerPacket  = 1;
audioFileDescription.mBytesPerPacket   = audioFileDescription.mBytesPerFrame * audioFileDescription.mFramesPerPacket;

AudioFileID audioFileID = 0;

OSStatus createFileStatus = AudioFileCreateWithURL(audioFileURL,
                                                   kAudioFileAIFFType,
                                                   &audioFileDescription,
                                                   kAudioFileFlags_EraseFile,
                                                   &audioFileID);

if (createFileStatus != 0) 
    cout << "Error creating output file" << endl;
    cout << "Error code: " << createFileStatus << ", ";

    //  hacky way of converting number back to kinda-readable enum code
    char chars[5];
    for (int i = 3; i >= 0; i--) 
        chars[i] = (char)createFileStatus;
        createFileStatus = createFileStatus >> 8;
    
    char[4] = '\0';
    cout << chars << endl;
    return 1;

【问题讨论】:

一目了然:尝试将kAudioFormatFlagIsBigEndian 添加到您的格式标志 已经完成,但是重新编译时输出没有变化,很遗憾。 改变计划 - 因为我很懒,所以我打算使用像 WRAIFFPP 这样更简单的库。 你真的想在你的 AIFF 中使用 32 位浮点数吗? 理想情况下,是的。这样我可以在必要时下采样到 16 位或 24 位,并且可以将所有数据生成为 +/- 1.0 之间的值 【参考方案1】:

AIFF 类型不支持浮点数据,您需要创建 AIFF-C 文件。所以当你调用AudioFileCreateWithURL 时,你使用kAudioFileAIFCType

Big Endian 和 float 互不兼容,不要指定 bigEndian。

【讨论】:

以上是关于如何使用 coreAudio 将标准化浮点值数组写入 AIFF?的主要内容,如果未能解决你的问题,请参考以下文章

将浮点值存储到无符号字符数组

读写非标准浮点值

如何从函数返回浮点数组?

Python 3:将波形数据(字节数组)转换为浮点值的 numpy 数组

将浮点值存储在数组中,并分析最后 20 个值以在 C++ 中检查

如何从 CoreAudio 获得首选频道布局