在 C++ 中处理音频缓冲区时,如何执行从 float -> double -> float 的转换

Posted

技术标签:

【中文标题】在 C++ 中处理音频缓冲区时,如何执行从 float -> double -> float 的转换【英文标题】:How can I perform conversion from float -> double -> float when processing an audio buffer in c++ 【发布时间】:2011-03-10 12:55:07 【问题描述】:

我目前正在开发一个应用程序,其中音频样本帧在以下回调中处理。

void Eav07AudioProcessor::processBlock (AudiosampleBuffer& buffer)


    for (int channel = 0; channel < getNumInputChannels(); ++channel)
    
        float* channelData = buffer.getSampleData (channel);        

        // ..do something to the data...
        DoSomeHeavyweightDSPon(&channelData[0]); // in the header, DoSomeHeavyweightDSPon(double data[somebignumber])
    

代替上述增益过程的函数期望 channelData 是双精度的。 channelData 参数是浮点精度。我是否需要以某种方式将 channelData 从 float 转换为 double ,然后在处理后从 double 转换为 float 或者我错过了一个技巧。

如果需要显式转换,考虑到此方法每秒调用 100 次,最有效的方法是什么。

【问题讨论】:

你能重新编译/重写增益方法来使用浮点数吗? 很遗憾,该函数的代码是从另一个软件包自动生成的,无法修改。 【参考方案1】:

不,将浮点数转换为 double 和 back 不会达到 gain() 函数所期望的效果。增益函数需要一个指向双精度数组的指针,并且没有任何类型的转换可以做到这一点。

您能做的最好的事情就是替换 gain() 函数。我只会使用您包含的“演示代码”(内部 for 循环)。

如果您需要调用 gain(double*) 函数,您可以执行以下任一操作:

创建第二个缓冲区,大小为:malloc(buffer.getNumSamples()*sizeof(double)),然后手动复制它们(memcpy 不起作用,因为它不会在每个浮点数之间生成您需要的四个零字节)。

[hack]:只需使用您拥有的缓冲区,但将每隔一个浮点数设置为 0,然后将另一个浮点数签名扩展至此。这有效地将您拥有的样本数量减半,但开销很小。

【讨论】:

(我描述的两种方法都足够快,可以轻松满足您的“每秒 100 次”要求。但是用您自己的演示代码替换增益函数是好多了)【参考方案2】:

上面提到的函数是double还是double*? 后一种情况总是需要将所有 channelData 复制到 double 缓冲区中,反之亦然。 如果您真的想要一种有效的方法,您将需要(复制和)更改有问题的函数以采用 float* 而不是 double*

如果函数只接受double,则不需要显式转换。

【讨论】:

也许把它做成一个模板函数,这样它就可以使用双精度或浮点数?

以上是关于在 C++ 中处理音频缓冲区时,如何执行从 float -> double -> float 的转换的主要内容,如果未能解决你的问题,请参考以下文章

使用 NAO 执行远程音频处理时出现问题

如何在 Windows 10 上使用 C++ 将连续的原始音频数据记录到循环缓冲区中?

如何从音频文件中获取样本的浮点数组

如何使用 Media Foundation 从 IMFSourceReader 播放音频缓冲区

OpenAL 从特定时间戳播放音频

libvorbis 音频从 C++ 中的内存解码