使用 CoreAudio 获取正确的 FileLengthFrames

Posted

技术标签:

【中文标题】使用 CoreAudio 获取正确的 FileLengthFrames【英文标题】:Get correct FileLengthFrames with CoreAudio 【发布时间】:2017-04-26 22:14:34 【问题描述】:

我正在将我的 Python 代码转换为 Objective C 以在 ios 设备上运行。关于读取音频文件的代码。在 Python 中,我使用 AudioSegment 读取文件,结果是数组中有 2 个单独的通道。

例如:

Left channel  [-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]  //length = 10
Right channel [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]   //length = 10

所以python的总长度是20

这是我在目标 c 中获得音频输出的方法

float *audioTotal = malloc(fileLengthInFrames * sizeof(float));
SInt16 *inputFrames = (SInt16*)bufferList->mBuffers[0].mData;
for(int i = 0; i < fileLengthInFrames; ++i) 
    audioTotal[i] = (float)inputFrames[i];
    printf("%f ", audioTotal[i]);

输出是:

[-1, 1, -2, 2, -3, 3, -4, 4, -5, 5] // length = 10

所以目标 c 的输出是左右声道混合的。所以我必须通过代码将它们分开:

if (clientFormat.mChannelsPerFrame > 1) 
        int indexLeft = 0;
        int indexRight = 0;
        float *leftAudio = malloc(fileLengthInFrames* sizeof(float));
        float *rightAudio = malloc(fileLengthInFrames * sizeof(float));
        for(int i = 0; i < fileLengthInFrames; i++) 
            if (i%2 == 0) 
                leftAudio[indexLeft] = audioTotal[i];
                printf("%f ", leftAudio[indexLeft]);
                indexLeft ++;
             else 
                rightAudio[indexRight] = audioTotal[i];
                printf("%f ", rightAudio[indexRight]);
                indexRight ++;
            
        

现在我有 2 个与目标 c 分开的频道:

Left channel  [-1,-2,-3,-4,-5]  //length = 5
Right channel [ 1, 2, 3, 4, 5]   //length = 5

所以我从目标 c 得到的总长度是 10,而在 python 中是 20。 我的其余数据在哪里?我错过了一些步骤吗?还是配置错误? 感谢您的帮助。

【问题讨论】:

【参考方案1】:

当你有交错样本并且你“用代码分隔它们”时,你忘记乘以channelsPerBuffer(这似乎是交错的精明?),所以对于立体声你错过了一半样品。尝试将 for 循环更改为

for(int i = 0; i < fileLengthInFrames*channelsPerBuffer; i++) 
    // display left and right samples here ...

audioTotal 的长度也应该是fileLengthInFrames*channelsPerBuffer

附言如果客户端和文件采样率相同,为什么要重新计算 fileLengthInFrames

【讨论】:

audioTotal 的长度是 10,所以如果我循环 fileLengthInFrames*clientFormat.mChannelsPerFrame,它将超出范围。我是否计算了两次“fileLengthInFrames”? 哎呀,audioTotal 也是错误的。它的长度也应该是fileLengthInFrames*clientFormat.mChannelsPerFrame。你从文件中获取fileLengthInFrames,然后重新计算它。 更新了使用channelsPerBuffer的答案,这似乎理解了交错和非交错之间的区别。

以上是关于使用 CoreAudio 获取正确的 FileLengthFrames的主要内容,如果未能解决你的问题,请参考以下文章

CoreAudio/OpenAL:如何获取传出的音频信号

为特定的 ASBD 缓冲区获取正确的数字数据类型转换

使用 CoreAudio 中的 AudioQueue 从网络播放原始 pcm

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

CoreAudio AUGraph 没有声音

CoreAudio AudioQueue 回调函数从未调用过,没有报错