如何将字节数组中的pcm样本转换为-1.0到1.0范围内的浮点数并返回?

我使用的重采样算法期望 数组包含 范围内的输入样本。音频数据是 PCM,采样

我想将音频从22khz下采样到8khz,如何将字节数组中的样本表示为浮点数 并返回字节数组?

回答:

您问两个问题:

  1. 如何将采样率从22kHz下调至8kHz?

  2. 如何从float [-1,1]转换为16位int并返回?

请注意,该问题已更新,以指示#1已在其他地方处理,但如果有帮助,我将保留我的部分答案。

回答:

一个评论者暗示这可以通过FFT解决。这是不正确的(重新采样的第一步是过滤。如果您感兴趣,我在这里提到了为什么不使用FFT进行过滤:http : //blog.bjornroche.com/2012/08/when-to-not-use

-fft.html)。

对信号进行重采样的一种非常好的方法是使用多相滤波器。但是,即使对于有信号处理经验的人来说,这也相当复杂。您还有其他几种选择:

  • 使用实现高质量重采样的库,例如libsamplerate
  • 快速而肮脏地做某事

听起来您已经采用第一种方法,这很棒。

快速而肮脏的解决方案听起来不那么好,但是由于您将频率降至8 kHz,因此我认为音质不是您的首要任务。一种快速而肮脏的选择是:

  • 对信号应用低通滤波器。尝试消除4 kHz以上的音频。您可以使用此处描述的过滤器(尽管理想情况下,您想要比这些过滤器更陡峭的东西,但至少比没有要好)。
  • 从原始信号中选择每个第2.75个采样,以产生新的,重新采样的信号。当您需要非整数样本时,请使用线性插值。如果您需要线性插值方面的帮助,请在此处尝试。

对于语音应用来说,这种技术应该已经足够好了。但是,我还没有尝试过,所以我不确定,因此我强烈建议您使用其他人的库。

如果您真的想实现自己的高质量采样率转换(例如多相滤波器),则应该对其进行研究,然后在https://dsp.stackexchange.com/上提出任何问题,而不是在此处提出。

回答:

这已经由c.fogelklou开始,但是让我修饰一下。

首先,16位整数的范围是-32768到32767(通常对16位音频进行签名)。要将int转换为float,请执行以下操作:

float f;

int16 i = ...;

f = ((float) i) / (float) 32768

if( f > 1 ) f = 1;

if( f < -1 ) f = -1;

通常,您不需要执行额外的“边界”操作(实际上,如果确实使用的是16位整数,则不需要这样做),但是如果您出于某些原因拥有一些> 16位整数,就可以使用它。

要转换回来,请执行以下操作:

float f = ...;

int16 i;

f = f * 32768 ;

if( f > 32767 ) f = 32767;

if( f < -32768 ) f = -32768;

i = (int16) f;

在这种情况下,通常有必要注意超出范围的值,尤其是大于32767的值。您可能会抱怨说,这会导致f =

1产生一些失真。有关此问题的一些(不完整的)讨论,请参阅此博客文章。

这不仅仅是“足以胜任政府工作”。换句话说,除非您担心最终的声音质量,否则它将正常工作。由于您将达到8kHz,因此我认为事实并非如此,因此此答案很好。

但是,为了完整起见,我必须添加一点:如果您要使事情绝对原始,请记住,这种转换会导致失真。为什么?因为从float转换为int时的误差与信号相关。事实证明,该错误的相关性非常糟糕,即使它很小,您实际上也可以听到。(幸运的是,它很小,以至于对于语音和低动态范围的音乐来说,它并不重要)。要消除此错误,必须在从float到int的转换中使用dither。同样,如果您对此很在意,请进行研究并在https://dsp.stackexchange.com/上提出相关的特定问题,而不是在此处。

您可能也对我在数字音频编程基础上的幻灯片中的幻灯片感兴趣,该幻灯片也有关于此主题的幻灯片,尽管它基本上说的是同一件事(甚至比我刚才说的要少):http://

blog .bjornroche.com / 2011/11 / slides-from-fundamentals-of-

audio.html

以上是 如何将字节数组中的pcm样本转换为-1.0到1.0范围内的浮点数并返回? 的全部内容, 来源链接: utcz.com/qa/424384.html

回到顶部