c - 写入 16 位原始 PCM 文件时出现问题

标签 c wav pcm 16-bit

作为一个小型实验音乐作品,我正在尝试用标准 C 编写一首歌曲。该代码输出一个可以导入 Audacity 的原始 PCM 文件。目前一切都按预期工作,但我在尝试将每个示例编写为 16 位而不是我当前使用的 8 位时遇到了问题。

在写入之前,当前样本被计算为 float ,其边界几乎保持在带符号的 8 位整数的范围内。然后在对下一个样本重复该过程之前将其写为 8 位整数。这工作正常并正常播放。当我尝试将其写为 16 位原始 PCM 文件时出现问题 - 我将 float 乘以 256 并将结果复制到一个整数,于是我使用 fwrite 写入生成的 16 位整数。这在导入时没有给出预期的结果,导致我所期望的版本高度失真。

我在下面添加了有效代码,因为问题只发生在编写阶段。

工作 8 位代码:

if (out<-127) {out=-128;} else if (out>126) {out=127;}
putc(out,fo);

16 位代码无效:

if (out<-127) {out=-128;} else if (out>126) {out=127;}
pcm=out*256;
fwrite(&pcm,2,1,fo);

我可能只是遗漏了一些明显的东西,但我已经尝试了好几个小时。提前致谢!

最佳答案

如果没有看到代码,我无法确定您的代码到底出了什么问题,但这将使您成为一个可在 Audacity 中打开的漂亮的 1 KHz 正弦波 16 位 PCM:

#include <stdio.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358
#endif

int main(void)
{
  FILE* f = fopen("sinewave.pcm", "wb");
  double t;
  for (t = 0; t < 1; t += 1./8000) // 8000 is the sample rate in Hz
  {
    double sample = 15000 * sin(2 * M_PI * 1000 * t); // 1000 Hz sine wave
    short s16 = (short)sample;
    unsigned char c;
    c = (unsigned)s16 % 256;
    fwrite(&c, 1, 1, f);
    c = (unsigned)s16 / 256 % 256;
    fwrite(&c, 1, 1, f);
  }
  fclose(f);
  return 0;
}

在 Audacity 中浏览文件->导入->原始数据:

编码:带符号的 16 位 PCM
字节顺序:小端
channel :1 channel (单声道)
采样率:8000

导入。

关于c - 写入 16 位原始 PCM 文件时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3325403/

相关文章:

ffmpeg - 如何在python中将wav音频文件转换为aac?

audio - OpenAL:设置源类型时出错

从 PCM 数据创建 .wav 文件

c - if-else 或 switch-case 的最快替代方案

c - 如何在C中使用FTP协议(protocol)?

c - 在 C 中将大括号放在字符串中

javascript - 为什么 WAV 格式在不同的浏览器中没有相同的 mimetype?

java - 如何从 wav 文件中获取 PCM 数据?

html5-audio - 如何通过 HTML5 音频元素直播原始 PCM

c - 编写获取下一个标记函数