循环通过WAV文件在C(或C + +)
我想复制一个WAV声音C.原始文件是一个2秒的文件,但我想复制目标文件中的数据多次,以便它打得更久。例如,如果我复制它3次,它应该播放6秒...对吗?循环通过WAV文件在C(或C + +)
但由于某些原因,即使目标文件大于原始文件,它仍然播放2秒... 任何人都可以帮忙吗?
这里是我的代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct header_file
{
char chunk_id[4];
int chunk_size;
char format[4];
char subchunk1_id[4];
int subchunk1_size;
short int audio_format;
short int num_channels;
int sample_rate;
int byte_rate;
short int block_align;
short int bits_per_sample;
char subchunk2_id[4];
int subchunk2_size;
} header;
typedef struct header_file* header_p;
int main()
{
FILE * infile = fopen("../files/man1_nb.wav","rb"); // Open wave file in read mode
FILE * outfile = fopen("../files/Output.wav","wb"); // Create output (wave format) file in write mode
int BUFSIZE = 2; // BUFSIZE can be changed according to the frame size required (eg: 512)
int count = 0; // For counting number of frames in wave file.
short int buff16[BUFSIZE]; // short int used for 16 bit as input data format is 16 bit PCM audio
header_p meta = (header_p)malloc(sizeof(header)); // header_p points to a header struct that contains the wave file metadata fields
int nb; // variable storing number of byes returned
if (infile)
{
fread(meta, 1, sizeof(header), infile); // Read only the header
fwrite(meta,1, sizeof(*meta), outfile); // copy header to destination file
int looper = 0; // number of times sound data is copied
for(looper=0; looper <2; looper++){
while (!feof(infile))
{
nb = fread(buff16,1,BUFSIZE,infile); // Reading data in chunks of BUFSIZE
count++; // Incrementing Number of frames
fwrite(buff16,1,nb,outfile); // Writing read data into output file
}
fseek(infile, 44, SEEK_SET); // Go back to end of header
}
}
fclose(infile); fclose(outfile);
return 0;
}
当您更改数据大小时,还需要更新输出标题。
long total_bytes_written_to_outfile = ftell(outfile);
// correct chunk_size and subchunk2_size just before closing outfile:
fseek(outfile, 0, SEEK_SET);
int size = total_bytes_written_to_outfile - sizeof(*meta);
meta->chunk_size = sizeof(header) - sizeof(meta->chunk_id) - sizeof(meta->chunk_size) + size;
meta->subchunk2_size = size;
fwrite(meta, 1, sizeof(*meta), outfile);
fclose(outfile);
此外,为确保您正在阅读正确的文件检查man1_nb.wav的meta->chunk_size
==文件大小 - 8
帕维尔,在你的代码,为什么“36”?在第六行 – PhoenixBlue
@PhoenixBlue这是通过chunk_size字段的字节数。 36是'sizeof(header) - sizeof(meta-> chunk_id) - sizeof(meta-> chunk_size)' – Pavel
非常感谢!有效! – PhoenixBlue
的你都读,写代码的部分是错误的。
wav文件有RIFF
format,由tlv块组成。每个块由标题和数据组成。通常wav文件由3个块组成:格式块与FOURCC
代码,格式块与PCMWAVEFORMAT
结构和数据块与声音数据。另外,由于每个块的大小受到32位长度保存字段的限制,所以通过将wav文件连接在一起构成大文件。
您需要逐块分析文件,并逐块写入目标块,并相应地更新标头。
谢谢,看看 – PhoenixBlue
你不做任何changements输出文件的标题。查看[这里](http://soundfile.sapp.org/doc/WaveFormat/)的格式描述。你应该关注'Subchunk2Size'字段。 –
我没有在标题中做任何更改。尽管如此,即使我改变了样本数量并复制一次音频,它仍然会播放。当然,有些字段必须保持不变(例如采样率,频道数量等)。 – PhoenixBlue
我不知道细节,但看起来很明显,标题必须以某种方式适应以适应新的长度。 –