C - 将缓冲区写为二进制文件(wav)

时间:2016-07-14 10:38:02

标签: c binary buffer

我正在读取一个wav文件作为二进制文件,将它放在缓冲区中,我想再次编写完全相同的wav文件。

到目前为止,这是我的代码:

file = fopen("tone1.wav", "rb");
file3 = fopen("outout.wav","wb"); 
fseek(file, 0, SEEK_END);
fileLen=ftell(file);
fseek(file, 0, SEEK_SET);
buffer=(char *)malloc(fileLen+1);
buffer3=(char *)malloc(fileLen+1);
fread(buffer, fileLen, 1, file);
for (int i=0;i<fileLen+1;++i){
    buffer3[i]=buffer[i];
    fwrite(buffer3,sizeof(buffer3),1,file3);
}
fclose(file);
fclose(file3);
free(buffer);
free(buffer3);

问题是outout wav文件是空的并且无法播放。 我不确定我做错了什么。如果我将fwrite(buffer3,sizeof(buffer3),1,file3);替换为fwrite(buffer3,sizeof(buffer3),1048,file3);(让我们说1048),我会得到一些可玩的东西但不是整个wav中有一个循环。

谁能告诉我这是什么问题?也许这是for循环长度错了也许我不应该把fileLen作为限制呢?我该怎样替换1?

提前致谢

3 个答案:

答案 0 :(得分:1)

请注意以下事项:

  • 文件是&#34; raw&#34;并且有一个&#34; .wav&#34;如你所说,扩展并不意味着它是一个wav文件,也不会生成一个wav文件。为了成为wav文件,它需要一个有效的WAV标头,并且需要适当的音频文件API来进行读写。您正在阅读和复制的内容是未知格式和未知字节序的无头数据。
  • 如果你想使用标准库C函数将内容从一个文件复制到另一个文件,你可以在字节级别上进行,而无需解释内容,这就是你所做的。

在这种情况下,您的代码中几乎没有问题:

  1. 缓冲区的冗余填充并在C:中转换malloc的返回值 buffer = malloc(fileLen);应该有用。
  2. 模棱两可的逻辑:为什么你在一次传递中读取源文件时,复制缓冲区并在循环内写入目标文件的每字节字节数?
  3. 即使如此,您仍然向freadfwrite函数传递错误的参数,请检查 man 页面。
    fread(buffer, 1, fileLen, file);应该修复阅读。 (1等于sizeof (char))。
  4. 如果您不解释文件内容,为什么还需要冗余缓冲区buffer3
  5. 即使如此,您仍然会在循环内向函数传递不正确的参数。这应该做的修复:

    for (int i=0; i<fileLen; i++){
        buffer3[i]=buffer[i];
        fwrite(&(buffer3[i]),1,1,file3);
    }
    
  6. 在打开源文件之前,通常不会事先知道文件的大小。因此,一个分配合理大小的缓冲区,然后读取和写入由缓冲区大小决定的块。在这种情况下,您的读取例程也应该处理缓冲区下溢情况。

答案 1 :(得分:0)

不要在循环内写字。
或者每次都写不同的字符(并不总是buffer3[0])。

fread(buffer, fileLen, 1, file);
for (int i = 0; i < fileLen; ++i) {
    // transform and copy
    buffer3[i] = transform(buffer[i]);
    //fwrite(buffer3 + i, 1, 1, file3); // write 1 character only
}
fwrite(buffer3, fileLen, 1, file3); // write all the new buffer

答案 2 :(得分:0)

我通过将fwrite(buffer3,sizeof(char),78000,file3);置于for循环之外来解决它,其中78000是file1的大小。但我的问题是,我如何通过代码知道它的大小是什么?