将 PCM 16 位 LE 转换为 WAV

Posted

技术标签:

【中文标题】将 PCM 16 位 LE 转换为 WAV【英文标题】:Coverting PCM 16bit LE to WAV 【发布时间】:2012-12-14 15:27:09 【问题描述】:

我正在尝试用 C 语言编写一个程序,将捕获的 Raw 16kHz PCM 16 位 文件转换为 16 位 WAV

我读过一些帖子,有人推荐使用libsox。安装了它,现在我真的很难理解man-page。

到目前为止(通过阅读源 dist 中的示例)我发现 structs:

sox_format_t sox_signalinfo_t

大概可以用来描述我输入的数据。如果有必要,我还知道我正在处理多少信息(时间)?

感谢一些指导!

【问题讨论】:

如果您想要的唯一输出格式是 WAV,我会跳过学习任何第三方 API 并自己编写。 WAV 的file format 真的很简单。 似乎值得一试。我试试看! 【参考方案1】:

嗯,问题得到了解答。不过我会在这里发布代码,以便人们可以对其进行分析或仅在他们自己的项目中使用它。

“simonc”和“Nickolay O”提供的链接。被使用。在网络上搜索有关各个字段的更多信息。

struct wavfile

    char        id[4];          // should always contain "RIFF"
    int     totallength;    // total file length minus 8
    char        wavefmt[8];     // should be "WAVEfmt "
    int     format;         // 16 for PCM format
    short     pcm;            // 1 for PCM format
    short     channels;       // channels
    int     frequency;      // sampling frequency, 16000 in this case
    int     bytes_per_second;
    short     bytes_by_capture;
    short     bits_per_sample;
    char        data[4];        // should always contain "data"
    int     bytes_in_data;
;

//Writes a header to a file that has been opened (take heed that the correct flags
//must've been used. Binary mode required, then you should choose whether you want to 
//append or overwrite current file
void write_wav_header(char* name, int samples, int channels)
    struct wavfile filler;
    FILE *pFile;
    strcpy(filler.id, "RIFF");
    filler.totallength = (samples * channels) + sizeof(struct wavfile) - 8; //81956
    strcpy(filler.wavefmt, "WAVEfmt ");
    filler.format = 16;
    filler.pcm = 1;
    filler.channels = channels;
    filler.frequency = 16000;
    filler.bits_per_sample = 16;
    filler.bytes_per_second = filler.channels * filler.frequency * filler.bits_per_sample/8;
    filler.bytes_by_capture = filler.channels*filler.bits_per_sample/8;
    filler.bytes_in_data = samples * filler.channels * filler.bits_per_sample/8;    
    strcpy(filler.data, "data");
    pFile = fopen(name, "wb");
    fwrite(&filler, 1, sizeof(filler), pFile);
    fclose(pFile);

【讨论】:

【参考方案2】:

我建议手动编写 WAV 标头和数据,PCM 真的非常简单: https://web.archive.org/web/20080706175634/https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

更新:原链接https://ccrma.stanford.edu/courses/422/projects/WaveFormat/失效。

【讨论】:

stanford.edu 是最不可靠的链接网站。链接显然断开了。您能否提供替代资源? 你可以一直使用 webarchive:web.archive.org/web/20080706175634/https://ccrma.stanford.edu/…

以上是关于将 PCM 16 位 LE 转换为 WAV的主要内容,如果未能解决你的问题,请参考以下文章

怎么将8位的WAV声音文件转换为16位?

无法将语音转换为文本

将原始PCM数据转换为RIFF WAV

使用 NAudio 将 PCM S16 LE (s16l) 转换为 GSM610

将 PCM 16 位音频转换为 PCM 8 位

将音频转换为 8 位签名 PCM