基本每种音频都会有它对应的头,里面包括的信息一般可以解析出播放总时间,采样率,比特率等信息;
本文章是解析WAV的头,然后计算播放的总时间,以及WAV如何计算当前播放时间;您看完后,应该可以很快地得到其他信息;
#include "stdio.h"
#include "fs.h"
typedef struct
{
INT8U RIFF_ID[4]; //= {'R','I','F','F'};
INT32U RIFF_len; //file size -8
INT8U type_ID[4]; // = {'W','A','V','E'};
INT8U fmt_ID[4]; // = {'f', 'm','t',' '};
INT32U fmt_len; //16 + extern format byte
INT16U format; // = 1; //pcm
INT16U channel; // = 1; // mono
INT32U sample_rate;// = 8000;
INT32U avg_byte_per_sec;// = 8000*2; //AvgBytesPerSec = SampleRate * BlockAlign
INT16U Block_align;// = (16 / 8*1) ; //BlockAlign = SignificantBitsPerSample / 8 * NumChannels
INT16U Sign_bit_per_sample;// = 16; //8, 16, 24 or 32
INT8U data_ID[4];// = {'d','a','t','a'};
INT32U data_len; //extern format byte
} AUD_ENC_WAVE_HEADER;
int main(int argc, char *argv[])
{
AUD_ENC_WAVE_HEADER wav_header;
char filename = "test.wav";
int fd = -1;
INT8U *ptr;
INT32U totaltime;
fd = open(filename, O_RDONLY);
if(fd < 0)
{
printf("open wav file fail\r\n");
return 0;
}
ptr = (INT8U *)(&wav_header);
read(fd, ptr, sizeof(AUD_ENC_WAVE_HEADER));
totaltime = wav_header.data_len/(wav_header.sample_rate * sample_rate.channel * sample_rate.Sign_bit_per_sample/8);
printf("file:%s totaltime = %d \r\n", filename, totaltime);
close(fd);
return 0;
}
int get_wav_curl_playtime(int fd, int totaltime)
{
struct sfn_info tmp_sfn_file;
INT32U position = 0;
INT32U curplaytime = 0;
sfn_stat(fd, &tmp_sfn_file);
position = lseek(fd , 0, SEEK_CUR);
curplaytime = totaltime * (position / tmp_sfn_file.f_size);
return curplaytime;
}
在main()函数中,是计算WAV总时间的方法,读回WAV Header后,用数据长度除以每秒的数据量就是总时间,每秒的数据量 = 采样率*通道数 * 每个采样点所占字节数;
get_wav_curl_playtime()是获取当前播放时间,假设在一开始open文件后,就一直没关闭句柄,播放的时候,需要不停地读WAV文件,则获取当前读档位置,再除以WAV文件大小,然后乘以总时间,大概就是当前播放时间;