audio - uwp audioGraph 将 32 位转换为 16 位 PCM

标签 audio uwp pcm

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

我需要以 16 位/样本 PCM 进行录制(对于网络)。 AudioGraph的文档提到它只支持32位浮点格式。 如何将32位录音转换为16位然后播放录音?

谢谢, 托尼

最佳答案

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

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

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

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

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

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

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

  • 这次输入的32位 float 从-1.0到+1.0变化...实际上范围是从-1 < value < 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;

关于audio - uwp audioGraph 将 32 位转换为 16 位 PCM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42062856/

相关文章:

java - 交错式立体声 PCM 线性 Int16 大端音频是什么样的?

ios - 从麦克风获取音频并将其写入iOS上的插槽

android - 如何在 Android 应用程序中录制声音

C++读取16位Wav文件

c# - XAML UWP 单选按钮图标居中对齐

android - Android中如何使用 `MediaElement`播放声音?

c# - 将图像转换为 Base64 字符串

Android AudioRecord 问题?

java - Java 中的麦克风级别

audio - FFmpeg - 从 AV_SAMPLE_FMT_FLTP 重采样到 AV_SAMPLE_FMT_S16 音质非常差(缓慢、走调、噪音)