uwp audioGraph 将 32 位转换为 16 位 pcm

uwp audioGraph convert 32 bit to 16 bit pcm

我需要将录音从麦克风传递到缓冲区,然后从缓冲区传递到扬声器(我通过网络发送缓冲区)。 我的配置:Mic->AudioFrameOutput->Network->AudioFrameInput->Speakers.

我需要使用 16 bits/sample PCM(用于网络)进行录制。 AudioGraph 的文档提到它仅支持 32 位浮点格式。 如何将32位录音转换为16位录音,然后播放录音?

谢谢, 托尼

如何将 32 位浮点数转换为 16 位整数是流音频世界中一个非常普遍的愿望...在这里我们将 32 位浮点缓冲区(数组)的一个元素转换为有损(32 位不不适合 16 位)无符号 16 位整数 ... 输入浮点数从 -1 到 +1

my_16_bit_unsigned_int = ((input_32_bit_floats[index] + 1.0) * 32768) - 1;

在这种最直接的水平上播放音频数据时,您会面临许多基本的设计决策:

  • 是输入音频波的浮点数,从-1到+1,或-0.5到+0.5,或从0到+1或其他
  • 我希望我的输出 16 位 PCM 是有符号的还是无符号的(通常是无符号的)
  • 我是在处理大端字节序还是小端字节序,这在通过线路发送内存缓冲区(通常是小端字节序)时很重要,特别是当您可能需要将 16 位整数缓冲区折叠成字节流时

了解这些问题并在仔细考虑以上等式的数据后得到答案确实假设音频波的输入 32 位浮点表示在 -1.0 到 +1.0(典型值)之间变化

你问32768这个值是从哪里来的? ...嗯,16 位整数有 2^16 个不同的值,范围从 0 到(2^16 - 1),所以如果你的输入浮点数从 -1 到 +1 不等,我们首先加 1 使其从 0 到 +2 不等这使得我们的输出无符号(无负数),然后我们将该范围内的值乘以 32768,然后减去 1 以适应 0 的起始下限,这样整数的输出范围从 0 到(2^16 - 1)不等。 . 或 0 到 65537 这给你总共 2^16 个不同的整数值

让我们用具体的例子来分解它

  • 这次输入的 32 位浮点数从 -1.0 到 +1.0 不等...实际范围是 -1 < 值 < 1

例子A

inputA = -0.999   #   close to minimum possible value

outputA = int((input_32_bit_floats[index] + 1.0) * 32768) - 1;

outputA = int(( -0.999 + 1.0) * 32768) - 1;
outputA = int( 0.001 * 32768) - 1;
outputA = int( 32.768) - 1;    
outputA = 33 - 1;
outputA = 32;     #    close to min possible value of 0

示例 B

inputB = 0.999   #   almost max possible value 

outputB = int((input_32_bit_floats[index] + 1.0) * 32768) - 1;
outputB = int((0.999  + 1.0) * 32768) - 1;
outputB = 65503 - 1;
outputB = 65502  #   close to our max possible value of 65537

您可以将乘法运算速度加快 32768,方法是将其替换为左移一位...您移动的位数由您的移位运算所替换的 2 的幂决定...

outputA = int((input_32_bit_floats[index] + 1.0) * 32768) - 1;

会变成

outputA = ( int(input_32_bit_floats[index] + 1.0)  << 15) - 1;