作为一个小型实验音乐作品,我正在尝试用标准 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/