WAV格式的文件,无非就是一个头,后面全部都是二进制数。
//wave文件头
typedef struct WaveHeader
{
char riff[4]; //资源交换文件标志
int size; //从下个地址开始到文件结尾的字节数
char wave_flag[4]; //wave文件标识
char fmt[4]; //波形格式标识
int fmt_len; //过滤字节(一般为00000010H)
short tag; //格式种类,值为1时,表示PCM线性编码
short channels; //通道数,单声道为1,双声道为2
int samp_freq; //采样频率
int byte_rate;//数据传输率 (每秒字节=采样频率×每个样本字节数)
short block_align;//块对齐字节数 = channles*bit_samp/8
short bit_samp; //bits per sample (又称量化位数)
}wave_header_s;
typedef struct WaveStruct
{
FILE *fp; //file pointer
wave_header_s stHeader; //header
char data_flag[4]; //数据标识符
int length; //采样数据总数
int *pData; //data
}wave_s;
以上是WAV文件头的内容,切割WAV文件生成子文件时,主要需要修改的部分是采样数据总数和head中的size
/* 读取wav文件头信息 */
fread(stWave.stHeader.riff, sizeof(char), 4, stWave.fp);
fread(&stWave.stHeader.size, sizeof(int), 1, stWave.fp);
fread(stWave.stHeader.wave_flag, sizeof(char), 4, stWave.fp);
fread(stWave.stHeader.fmt, sizeof(char), 4, stWave.fp);
fread(&stWave.stHeader.fmt_len, sizeof(int), 1, stWave.fp);
fread(&stWave.stHeader.tag, sizeof(short), 1, stWave.fp);
fread(&stWave.stHeader.channels, sizeof(short), 1, stWave.fp);
fread(&stWave.stHeader.samp_freq, sizeof(int), 1, stWave.fp);
fread(&stWave.stHeader.byte_rate, sizeof(int), 1, stWave.fp);
fread(&stWave.stHeader.block_align, sizeof(short), 1, stWave.fp);
fread(&stWave.stHeader.bit_samp, sizeof(short), 1, stWave.fp);
do
{
fread(&temp, sizeof(char), 1, stWave.fp);
}
while('d' != temp);
stWave.data_flag[0] = temp;
fread(&stWave.data_flag[1], sizeof(char), 3, stWave.fp);
fread(&stWave.length, sizeof(int), 1, stWave.fp);
/* 根据时间算出新文件大小 */
newFileDataSize = byte_rate * 新文件时长time;
根据新文件大小,计算新文件个数
/* 根据源文件生成新文件的首部 */
memcpy (&stNewWave, &stWave, sizeof(stNewWave));
stNewWave.length = newFileDataSize;
stNewWave.stHeader.size = stWave.stHeader.size - (stWave.length - stNewWave.length);
下面就根据data中的内容,一点一点封装到新文件的data中
for(int i=1; i<=newFileNumber; i++)
{
/* 拼装新文件名 */
sprintf(buffer,"output/%s%d.wav",filename, i);
/* 写方式打开文件 */
newfp=fopen(buffer,"wb");
/* 写入新文件文件头 */
tmp = ((char *)&stNewWave + 8);
for(int j=0;j < (sizeof(stNewWave) - 4 - 4); j++)
{
fputc(*tmp,newfp);
tmp ++;
}
/* 写入新文件采样内容 */
for(int t=0; t< newFileDataSize; t++)
{
fputc(fgetc(stWave.fp), newfp);
}
fflush(newfp);
fclose(newfp);
printf("%s\n",buffer);
}
全部代码已上传到CSDN,gcc编译后就可以运行。