将PCM转换为wav文件

时间:2013-11-11 02:20:49

标签: 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);
}

任何人都可以帮我解决此代码中的问题。标题是正确的,甚至正确写入文件。但每当打开.wav文件时,它会显示一个额外的字段。而且档案也没有播放。如果我尝试使用媒体信息打开文件,其显示属性按预期除了持续时间

  

格式:Wave文件大小
  :8.29 KiB持续时间:20ms整体位   速率模式:恒定总比特率
  :3 394 Kbps

     

音频格式:PCM格式设置,   字节顺序:小格式设置,标志
  :签名编解码器ID:1持续时间
  :20ms比特率模式:恒定比特率
  :128 Kbps通道:1通道   采样率:8 000 Hz位深度
  :16位流大小:320字节(4%)

1 个答案:

答案 0 :(得分:1)

我对文件格式一无所知,但我发现很难相信它们会有一个二进制头,后跟ascii数据。因此fgets和fput的使用我觉得有问题,因为fgets寻找终结器。因此,如果缓冲区在找到\ 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然后重新打开它?