我正在文件 @ 16KBps 上写一些无声PCM数据。此文件是.wav格式。为此,我有以下代码:
#define DEFAULT_BITRATE 16000
long LibGsmManaged:: addSilence ()
{
char silenceBuf[DEFAULT_BITRATE];
if (fout) {
for (int i = 0; i < DEFAULT_BITRATE; i++) {
silenceBuf[i] = '\0';
}
fwrite(silenceBuf, sizeof(silenceBuf), 1, fout);
}
return ftell(fout);
}
更新: 这是我写标题的方法
void LibGsmManaged::write_wave_header( )
{
if(fout) {
fwrite("RIFF", 4, 1, fout);
total_length_pos = ftell(fout);
write_int32(0);
fwrite("WAVE", 4, 1, fout);
fwrite("fmt ",4, 1, fout);
write_int32(16);
write_int16(1);
write_int16(1);
write_int32(8000);
write_int32(16000);
write_int16(2);
write_int16(16);
fwrite("data",4,1,fout);
data_length_pos = ftell(fout);
write_int32(0);
}
else {
std::cout << "File pointer not correctly initialized";
}
}
void LibGsmManaged::write_int32( int value)
{
if(fout) {
fwrite( (const char*)&value, sizeof(value), 1, fout);
}
else {
std::cout << "File pointer not correctly initialized";
}
}
我使用NSTimer在我的iOS设备上运行此代码,间隔为1.0秒。所以AFAIK,如果我运行60秒,我应该得到一个file.wav,当播放时应该显示60秒作为其持续时间(再次AFAIK)。但在实际测试中,它显示几乎两倍的持续时间,即2分钟。 (约)。我还测试过,当我将DEFAULT_BITRATE更改为8000时,文件持续时间几乎是正确的。
我无法确定这里发生了什么。我在这里遗漏了什么吗?我希望我的代码没有错。
答案 0 :(得分:3)
您要做的事情(编写自己的WAV文件)应该完全可行。这是个好消息。但是,我对你的确切参数和约束感到有些困惑,正如评论中的许多其他人一样,这就是为什么他们一直试图充实细节。
您希望将原始的,未压缩的静音PCM写入WAV文件。好的。 PCM数据需要有多宽?您正在创建要写入文件的字符数组。 char是一个8位字节。那是你要的吗?如果是这样,那么您需要使用静默中心点0x80(128)。 WAV文件中的8位PCM是无符号的,即0..255,而128是无声的。
如果您打算存储静默的16位数据,那将是签名数据,因此中心点(-32768和32767之间)为0.此外,它将以小端字节格式存储。但由于它是沉默(全0),这无关紧要。
您的问题标题表明您想以16 kbps的速度写入数据(并且第一句重申)。 您确定要原始16 kbps音频吗?这是每秒16千比特,或每秒16000比特。根据您是在写8位还是16位PCM样本,只允许2000或1000 Hz音频,这可能不是您想要的。 您的意思是16 kHz音频吗? 16 kHz音频转换为每秒16000个音频样本,这与您的代码更加一致。然后,你的代码提到GSM(LibGsmManaged
),所以你可能正在寻找16 kbps的音频。但我会假设我们正沿着原始PCM路线前进。
您是否事先知道需要写多少秒的音频?这使得这个过程非常简单。您可能已经注意到,WAV标头需要一些位置的长度信息。您可以提前写(如果您知道值)或稍后填写(如果您写的是不确定的金额)。
假设您正在为WAV文件写入2秒的原始,单声道,16000 Hz,16位PCM。中心点是0x0000。
WAV写作过程:
'RIFF'
'WAVEfmt '
(带空格)'data'
如果您需要编写动态数量的音频数据,请将步骤2和12中的长度字段保留为0,然后在完成写入后再搜索并填写。我不相信您的原始代码正在写长度字段。有些回放软件可能会忽略这些,有些则可能没有,因此您可能会得到不同的结果。
希望有所帮助!如果您了解Python,那么我回答的另一个问题是如何write a WAV file using Python's struct library(我在编写上述步骤时大量提到了代码片段)。