取消PCM(*.wav)立体声音频数据的交互
Deinterleaving PCM (*.wav) stereo audio data
我知道PCM数据存储为[left][right][left][right]...
。我正在尝试将立体声PCM转换为单声道Vorbis(*.ogg(,我知道这可以通过将左右声道减半((左+右(*0.5(来实现。我实际上已经通过修改libvorbis-sdk中的编码器示例来实现了,如下所示,
#define READ 1024
signed char readbuffer[READ*4];
并且PCM数据被读取从而
fread(readbuffer, 1, READ*4, stdin)
然后我把两个通道减半,
buffer[0][i] = ((((readbuffer[i*4+1]<<8) | (0x00ff&(int)readbuffer[i*4]))/32768.f) + (((readbuffer[i*4+3]<<8) | (0x00ff&(int)readbuffer[i*4+2]))/32768.f)) * 0.5f;
它工作得很好,但我不明白他们是如何从PCM数据中去交错左右声道的(即所有的移位和"与"answers"或"(。
.wav文件通常以little-endian格式存储其PCM数据,每个通道每个样本16位。对于通常的带符号的16位PCM文件,这意味着数据在物理上存储为
[LEFT LSB] [LEFT MSB] [RIGHT LSB] [RIGHT MSB] ...
使得每组4个字节构成单个立体声PCM采样。因此,您可以通过查看字节4*i
到4*i+3
(包括这些字节(来找到示例i
。
要从两个字节中解码单个16位值,您可以执行以下操作:
(MSB << 8) | LSB
因为您的读取缓冲区值存储为签名字符,所以您必须小心一点,因为MSB
和LSB
都将进行符号扩展。这对于LSB来说是不可取的;因此,代码使用
0xff & (int)LSB
以获得低字节的无符号版本(从技术上讲,这是通过向上转换为int并选择低8位来实现的;另一种公式是只写(uint8_t)LSB
(。
请注意,MSB位于索引1和3,LSB位于索引0和2。所以,
((readbuffer[i*4+1]<<8) | (0x00ff&(int)readbuffer[i*4]))
和
((readbuffer[i*4+3]<<8) | (0x00ff&(int)readbuffer[i*4+2]))
只是通过使用一些比特操作将字节组装成数字来获得作为16比特有符号值的左通道和右通道的值。
然后,将这些值中的每一个除以32768.0。请注意,带符号的16位值的范围为[-32768, 32767]
。因此,除以32768得到的范围大约为[-1,1]。将两个除法值相加,得到一个范围为[-2,2]的数字,然后将整数值乘以0.5,得到平均值(范围为[-1,1]的浮点值(。
- 捕获音频数据并保存到AudioFlinger中的原始PCM文件
- 如何将 cdparanoia 读取的 CD 音频数据移交给 ALSA 播放器?
- 如何将静默音频数据写入音频流
- 使用FFMPEG编写多线程视频和音频数据包
- 以选定的比特率发送音频数据 - 喊播
- 使用C 中的套接字通过网络发送音频数据
- C++将音频数据发送到Linux和Mac OS X上的扬声器输出
- 使用C++(基于C#程序)保存wav文件时,音频数据不正确
- FFmpeg:编码PCM 16音频数据分配错误
- 如何在Raspberry Pi上用C++将接收到的UDP音频数据正确写入ALSA
- 实时录制/转换音频数据到WAV
- 端口音频遍历音频数据
- 在 C++ 中使用 libsndfile 从 WAV 文件中提取原始音频数据
- 如何用音频数据填充AVFrame
- 如何获取 mp3 音频数据包以在 C/C++ 中流式传输
- OpenAL回放捕获的音频数据c++
- 如何从Tizen上的实时FFT中获得最准确的音频数据?
- 如何使用Windows内置的mp3解码器访问原始解码音频数据?
- 播放产生的音频数据在声音中有噪音和周期性的咔嗒声
- 音频数据?我需要一个典型的例子