PCM转wav文件

标签 c audio

#include <stdio.h>
#include <string.h>

int main() {

    FILE *fin,*fout;
    char buffer[1028];


    int readcount=0;
    short NumChannels = 1;
    short BitsPerSample = 16;
    int SamplingRate =8000;
    short numOfSamples = 160;

    int ByteRate = NumChannels*BitsPerSample*SamplingRate/8;
    short BlockAlign = NumChannels*BitsPerSample/8;
    int DataSize = NumChannels*numOfSamples *  BitsPerSample/8;
    int chunkSize = 16;
    int totalSize = 36 + DataSize;
    short audioFormat = 1;

    if((fout = fopen("sample.wav", "w")) == NULL)
    {
        printf("Error opening out file ");
    }

    //totOutSample = 0;
    fwrite("RIFF", sizeof(char), 4,fout);
    fwrite(&totalSize, sizeof(int), 1, fout);
    fwrite("WAVE", sizeof(char), 4, fout);
    fwrite("fmt ", sizeof(char), 4, fout);
    fwrite(&chunkSize, sizeof(int),1,fout);
    fwrite(&audioFormat, sizeof(short), 1, fout);
    fwrite(&NumChannels, sizeof(short),1,fout);
    fwrite(&SamplingRate, sizeof(int), 1, fout);
    fwrite(&ByteRate, sizeof(int), 1, fout);
    fwrite(&BlockAlign, sizeof(short), 1, fout);
    fwrite(&BitsPerSample, sizeof(short), 1, fout);
    fwrite("data", sizeof(char), 4, fout);
    fwrite(&DataSize, sizeof(int), 1, fout);
    fclose(fout);
    fin=fopen("sample.raw","r");
    fout=fopen("sample.wav","a");

    while(!feof(fin))
    {
        fgets(buffer,sizeof(buffer),fin);
        fputs(buffer,fout);
    }

    fclose(fin);
    fclose(fout);
}

谁能帮我解决这段代码中的问题。标题是正确的,它甚至正确地写在文件上。但是每当打开 frhed .wav 文件时,它都会显示一个额外的字段。而且文件也没有播放。如果我尝试使用媒体信息打开文件,它会按预期显示属性,但持续时间除外

Format : Wave File size
: 8.29 KiB Duration : 20ms Overall bit rate mode : Constant Overall bit rate
: 3 394 Kbps

Audio Format : PCM Format settings, Endianness : Little Format settings, Sign
: Signed Codec ID : 1 Duration
: 20ms Bit rate mode : Constant Bit rate
: 128 Kbps Channel(s) : 1 channel Sampling rate : 8 000 Hz Bit depth
: 16 bits Stream size : 320 Bytes (4%)

最佳答案

我对文件格式一无所知,但我很难相信它们会有一个二进制头,后跟 ascii 数据。所以我觉得 fgets 和 fputs 的使用有问题,因为 fgets 寻找\n 终止符。因此,如果缓冲区在碰巧找到\n ( 0xa ) 字节之前就已满,则可能会丢失数据。

while(!feof(fin))
{
    fgets(buffer,sizeof(buffer),fin);
    fputs(buffer,fout);
}

这样的事情会更有意义

size_t n;
while((n = fread(buffer, 1, sizeof(buffer), fin)) > 0) {
   if(n != fwrite(buffer, 1, n, fout)) {
      perror("fwrite");
      exit(1);
   }
}
if(n < 0) {
   perror("fread");
   exit(1);
}

还有,为什么关闭fout然后再打开呢?

关于PCM转wav文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19897879/

相关文章:

java - C服务器和Java客户端之间的UDP连接

c++ - 是否有工具/解决方案来编写一个循环,其中仅在每 X 次迭代中检查条件?

数字的 Collat​​z 序列

c - 在 C 中使用 fwrite 时文件大小限制为 2GB?

android - 不支持的配置,采样率11025,格式1,ChannelMask 0x10

audio - FFmpeg 如何使用 alimiter 过滤器?

javascript - 更改 HTML5 音频元素的 src 属性

objective-c - 物镜

android - 点击声音无法播放android onClick

C编程: Basic fscanf issues with doubles