c - 将数据写入wav文件
我正在研究从wav文件读取数据的小工具。该工具首先提取标题,然后将音频数据分离为左右声道。音频文件只是采样频率为44100Hz,16Bit PCM和双声道的文件。c - 将数据写入wav文件
操作数据后,我想将数据写回输出文件并在每个通道上追加100个零。这里会出现这样的问题:首先,每个通道只追加一半所需样品。其次,附加“零”的前半部分是随机数据。
见我下面
#include <stdlib.h>
#include <stdio.h>
#define BUFFSIZE 1024
#define NUM_ZEROS 100
#include <stdio.h>
#include <stdlib.h>
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(int argc, char** argv){
if(argc != 3){
printf("Wrong number of input arguments. Aborting.\n");
return -1;
}
char *inputFile = argv[1];
char *outputFile = argv[2];
FILE * infile = fopen(inputFile, "r+");
FILE * outfile = fopen(outputFile, "w+");
int count = 0; // For counting number of frames in wave file.
short int buff16[2*BUFFSIZE]; // short int used for 16 bit as input data format is 16 bit PCM audio
short int buffLeft[BUFFSIZE], buffRight[BUFFSIZE];
header_p meta = (header_p)malloc(sizeof(header)); // header_p points to a header struct that contains the wave file metadata fields
int nb, cnt; // variable storing number of bytes returned
printf("Buffers initialized.\n");
if (infile)
{
fread(meta, 1, sizeof(header), infile);
meta->subchunk2_size = meta->subchunk2_size + 2 * NUM_ZEROS;
fwrite(meta,1, sizeof(*meta), outfile);
while (!feof(infile))
{
nb = fread(buff16,1,BUFFSIZE,infile); // Reading data in chunks of BUFSIZE
count++; // Incrementing Number of frames
for(cnt = 0; cnt < nb/2; cnt++){
buffLeft[cnt] = buff16[2*cnt];
buffRight[cnt] = buff16[2*cnt+1];
}
/*
* TODO: INSERT SIGNAL PROCESSING PART
*/
for(cnt = 0; cnt < nb/2; cnt++){
buff16[2*cnt] = buffLeft[cnt];
buff16[2*cnt+1] = buffRight[cnt];
}
fwrite(buff16,1,nb,outfile);
}
for(cnt = 0; cnt < 2*NUM_ZEROS; cnt++){
buff16[cnt] = 0;
}
fwrite(buff16,1, 2*NUM_ZEROS,outfile);
printf("Number of frames in the input wave file are %d.\n", count);
}
fclose(infile);
fclose(outfile);
return 0;
}
码某人是否有一个想法,我做错了什么?
你有
#define NUM_ZEROS 100
和
fwrite(buff16,1, 2*NUM_ZEROS,outfile);
目的:
我希望将数据写回一个输出文件,并在每个通道上追加100个零 。
我认为它应该是100个样本在每个通道。 由于你有16位PCM,每个采样是2个字节。 所以一个通道需要写入200个字节(零)。立体声意味着400字节。
你的fwrite只保存2 * NUM_ZEROS所以200字节 - 这是部分关于丢失样本的答案。
另外声明
短整型buff16 [2 * BUFFSIZE];
同时只读取其中的一半,并使用半数(nb/2)的一半进行处理。比完整的缓冲区(实际上是声明的一半)和上半部分充满随机垃圾的内存。
你确定只有一部分添加的零是垃圾吗?
你陷入困境的fread
数据大小和fwrite
你的缓冲区short int
:
short int buff16[2*BUFFSIZE]; // BUFFSIZE*2*sizeof(short) bytes
您仅读取尺寸的1/4:
nb = fread(buff16,1,BUFFSIZE,infile); // BUFFSIZE bytes
这读取BUFSIZE
bytes,因为您只能为每个元素指定大小1。 而不是BUFFSIZE*2
短裤,你只能读取BUFFSIZE
字节。 返回值是读取元素的数量,即字节数。 在您的缓冲区中,该数据量仅对nb/2
元素足够,但访问buff16[0]
.. buff16[nb-1]
其中后半部分未从文件中读取。 幸运的是,您也不会将后半部分写入新文件,因为 同样的长度错误也出现在那里。 最后,在将零值附加到文件时存在同样的问题。
TL;博士
更改尺寸参数fread
和fwrite
至sizeof(short int)
。