#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
//wave文件头
typedef struct WaveHeader
{
unsigned char riff[4]; //资源交换文件标志
unsigned long size; //从下个地址开始到文件结尾的字节数
unsigned char wave_flag[4]; //wave文件标识
unsigned char fmt[4]; //波形格式标识
unsigned long fmt_len; //过滤字节(一般为00000010H)
unsigned short tag; //格式种类,值为1时,表示PCM线性编码
unsigned short channels; //通道数,单声道为1,双声道为2
unsigned long samp_freq; //采样频率
unsigned long byte_rate; //数据传输率 (每秒字节=采样频率×每个样本字节数)
unsigned short block_align; //块对齐字节数 = channles * bit_samp / 8
unsigned short bit_samp; //bits per sample (又称量化位数)
} wave_header_t;
typedef struct WaveStruct
{
wave_header_t header; //header
unsigned char data_flag[4]; //数据标识符
unsigned long length; //采样数据总数
unsigned long *pData; //data
} wave_t;
void WaveOpen(FILE* fp, wave_t* wave)
{
int read_bytes = 0;
/* read heade information */
read_bytes = fread(wave->header.riff, 1, sizeof(wave->header.riff), fp);
assert(read_bytes == sizeof(wave->header.riff));
read_bytes = fread(&wave->header.size, 1, sizeof(wave->header.size), fp);
assert(read_bytes == sizeof(wave->header.size));
read_bytes = fread(wave->header.wave_flag, 1, sizeof(wave->header.wave_flag), fp);
assert(read_bytes == sizeof(wave->header.wave_flag));
read_bytes = fread(wave->header.fmt, 1, sizeof(wave->header.fmt), fp);
assert(read_bytes == sizeof(wave->header.fmt));
read_bytes = fread(&wave->header.fmt_len, 1, sizeof(wave->header.fmt_len), fp);
assert(read_bytes == sizeof(wave->header.fmt_len));
read_bytes = fread(&wave->header.tag, 1, sizeof(wave->header.tag), fp);
assert(read_bytes == sizeof(wave->header.tag));
read_bytes = fread(&wave->header.channels, 1, sizeof(wave->header.channels), fp);
assert(read_bytes == sizeof(wave->header.channels));
read_bytes = fread(&wave->header.samp_freq, 1, sizeof(wave->header.samp_freq), fp);
assert(read_bytes == sizeof(wave->header.samp_freq));
read_bytes = fread(&wave->header.byte_rate, 1, sizeof(wave->header.byte_rate), fp);
assert(read_bytes == sizeof(wave->header.byte_rate));
read_bytes = fread(&wave->header.block_align, 1, sizeof(wave->header.block_align), fp);
assert(read_bytes == sizeof(wave->header.block_align));
read_bytes = fread(&wave->header.bit_samp, 1, sizeof(wave->header.bit_samp), fp);
assert(read_bytes == sizeof(wave->header.bit_samp));
/* jump to "data" for reading data */
unsigned char temp = 0;
do
{
read_bytes = fread(&temp, 1, sizeof(temp), fp);
assert(read_bytes == sizeof(temp));
}
while('d' != temp);
wave->data_flag[0] = temp;
read_bytes = fread(&wave->data_flag[1], 1, sizeof(wave->data_flag)-1, fp);
assert(read_bytes == (sizeof(wave->data_flag)-1));
read_bytes = fread(&wave->length, 1, sizeof(wave->length), fp);
assert(read_bytes == sizeof(wave->length));
/* jduge data chunk flag */
if(strncmp((const char*)wave->data_flag, "data", 4))
{
printf("error : cannot read data!\n");
return;
}
const char *channel_mappings[] = {NULL,"mono","stereo"};
unsigned long total_time = wave->length / wave->header.byte_rate;
unsigned char hour = (unsigned char)(total_time / 3600);
unsigned char minute = (unsigned char)((total_time / 60) % 60);
unsigned char second = (unsigned char)(total_time % 60);
/* printf file header information */
printf("%s %ldHz %dbit, DataLen: %ld, Rate: %ld, Length: %02d:%02d:%02d\n",
channel_mappings[wave->header.channels], //声道
wave->header.samp_freq, //采样频率
wave->header.bit_samp, //每个采样点的量化位数
wave->length,
wave->header.byte_rate,
hour, minute, second);
}
int write_head(FILE* fp, wave_t* wav)
{
int bytes = fwrite(&wav->header, 1, sizeof(wav->header), fp);
assert(bytes == sizeof(wav->header));
bytes = fwrite(wav->data_flag, 1, sizeof(wav->data_flag), fp);
assert(bytes == sizeof(wav->data_flag));
bytes = fwrite(&wav->length, 1, sizeof(wav->length), fp);
assert(bytes == sizeof(wav->length));
return 0;
}
int main(int argc, char** argv)
{
if (argc != 3)
{
printf("Usage: \n");
return 0;
}
int i = 1;
FILE* src = fopen(argv[i], "rb");
if (!src)
{
printf("failed to open[%s]: %s\n", argv[i], strerror(errno));
return -1;
}
i++;
FILE* dst = fopen(argv[i], "w+");
if (!dst)
{
printf("failed to open[%s]: %s\n", argv[i], strerror(errno));
return -1;
}
wave_t wave;
memset(&wave, 0, sizeof(wave));
WaveOpen(src, &wave);
write_head(dst, &wave);
char buf[1024];
while(!feof(src))
{
memset(buf, 0, sizeof(buf));
int n = fread(buf, 1, sizeof(buf), src);
if (n > 0)
{
int bytes = fwrite(buf, 1, n, dst);
assert(n == bytes);
}
}
fclose(src);
fclose(dst);
return 0;
}
wav 文件头解析
最新推荐文章于 2022-03-13 17:13:58 发布