在 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 的转换的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 10 上使用 C++ 将连续的原始音频数据记录到循环缓冲区中?