日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

c语言 文件 long double 读取,读取*.wav音频文件

發(fā)布時(shí)間:2025/3/21 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言 文件 long double 读取,读取*.wav音频文件 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、wav音頻文件的格式

wav文件由文件頭和采樣數(shù)據(jù)2部分組成。

文件頭又分為RIFF(Resource Interchange File Format)、WAVE文件標(biāo)識(shí)段 和 聲音數(shù)據(jù)格式說(shuō)明段組成。

各段的起始地址分別由RIFF標(biāo)識(shí)符、WAVE標(biāo)識(shí)符、以及波形格式標(biāo)識(shí)符(FMT)標(biāo)定。

(1)文件頭格式

注意:下面的地址是連續(xù)的

(2)數(shù)據(jù)格式

雖然上圖給出的數(shù)據(jù)標(biāo)識(shí)符起始地址剛好是文件頭的末地址+1,但并不代表總是這樣。

因此,我們?cè)谧x取數(shù)據(jù)時(shí)最好是找到數(shù)據(jù)標(biāo)識(shí)符,該標(biāo)識(shí)符的4個(gè)字節(jié)剛好是'd'、‘a(chǎn)’、‘t’、‘a(chǎn)’。

2、C語(yǔ)言讀取wav文件

首先對(duì)一些類(lèi)型使用了重定義

typedef unsigned char uchar;

typedef unsigned char uint8;

typedef unsigned short uint16;

typedef unsigned long uint32;

typedef char sint8;

typedef short sint16;

typedef long sint32;

typedef float fp32;

typedef double fp64;

typedef enum BOOLEAN

{

TRUE = 1,

FALSE = 0

} boolean;

(1)wav結(jié)構(gòu)體定義

//wave文件頭

typedef struct WaveHeader

{

uint8 riff[4]; //資源交換文件標(biāo)志

uint32 size; //從下個(gè)地址開(kāi)始到文件結(jié)尾的字節(jié)數(shù)

uint8 wave_flag[4]; //wave文件標(biāo)識(shí)

uint8 fmt[4]; //波形格式標(biāo)識(shí)

uint32 fmt_len; //過(guò)濾字節(jié)(一般為00000010H)

uint16 tag; //格式種類(lèi),值為1時(shí),表示PCM線性編碼

uint16 channels; //通道數(shù),單聲道為1,雙聲道為2

uint32 samp_freq; //采樣頻率

uint32 byte_rate; //數(shù)據(jù)傳輸率 (每秒字節(jié)=采樣頻率×每個(gè)樣本字節(jié)數(shù))

uint16 block_align; //塊對(duì)齊字節(jié)數(shù) = channles * bit_samp / 8

uint16 bit_samp; //bits per sample (又稱(chēng)量化位數(shù))

} wave_header_t;

typedef struct WaveStruct

{

FILE *fp; //file pointer

wave_header_t header; //header

uint8 data_flag[4]; //數(shù)據(jù)標(biāo)識(shí)符

uint32 length; //采樣數(shù)據(jù)總數(shù)

uint32 *pData; //data

} wave_t;

wave_t wave;

(2)讀取文件頭信息

/*

* open *.wav file

*/

void WaveOpen(char *file, int raw, int mono_stereo)

{

uchar temp = 0;

uint8 read_bytes = 0;

char *channel_mappings[] = {NULL,"mono","stereo"};

uint32 total_time = 0;

struct PlayTime //播放時(shí)間

{

uint8 hour;

uint8 minute;

uint8 second;

} play_time;

if(NULL == (wave.fp=fopen(file, "rb"))) /* open file */

{

printf("file %s open failure!\n", file);

}

/* read heade information */

if(4 != fread(wave.header.riff, sizeof(uint8), 4, wave.fp)) /* RIFF chunk */

{

printf("read riff error!\n");

return;

}

if(1 != fread(&wave.header.size, sizeof(uint32), 1, wave.fp)) /* SIZE : from here to file end */

{

printf("read size error!\n");

return;

}

if(4 != fread(wave.header.wave_flag, sizeof(uint8), 4, wave.fp)) /* wave file flag */

{

printf("read wave_flag error!\n");

return;

}

if(4 != fread(wave.header.fmt, sizeof(uint8), 4, wave.fp)) /* fmt chunk */

{

printf("read fmt error!\n");

return;

}

if(1 != fread(&wave.header.fmt_len, sizeof(uint32), 1, wave.fp)) /* fmt length */

{

printf("read fmt_len error!\n");

return;

}

if(1 != fread(&wave.header.tag, sizeof(uint16), 1, wave.fp)) /* tag : PCM or not */

{

printf("read tag error!\n");

return;

}

if(1 != fread(&wave.header.channels, sizeof(uint16), 1, wave.fp)) /* channels */

{

printf("read channels error!\n");

return;

}

if(1 != fread(&wave.header.samp_freq, sizeof(uint32), 1, wave.fp)) /* samp_freq */

{

printf("read samp_freq error!\n");

return;

}

if(1 != fread(&wave.header.byte_rate, sizeof(uint32), 1, wave.fp)) /* byte_rate : decode how many bytes per second */

{ /* byte_rate = samp_freq * bit_samp */

printf("read byte_rate error!\n");

return;

}

if(1 != fread(&wave.header.block_align, sizeof(uint16), 1, wave.fp)) /* quantize bytes for per samp point */

{

printf("read byte_samp error!\n");

return;

}

if(1 != fread(&wave.header.bit_samp, sizeof(uint16), 1, wave.fp)) /* quantize bits for per samp point */

{ /* bit_samp = byte_samp * 8 */

printf("read bit_samp error!\n");

return;

}

/* jump to "data" for reading data */

do

{

fread(&temp, sizeof(uchar), 1, wave.fp);

}

while('d' != temp);

wave.data_flag[0] = temp;

if(3 != fread(&wave.data_flag[1], sizeof(uint8), 3, wave.fp)) /* data chunk */

{

printf("read header data error!\n");

return;

}if(1 != fread(&wave.length, sizeof(uint32), 1, wave.fp)) /* data length */

{

printf("read length error!\n");

}

/* jduge data chunk flag */

if(!StrCmp(wave.data_flag, "data", 4))

{

printf("error : cannot read data!\n");

return;

}

total_time = wave.length / wave.header.byte_rate;

play_time.hour = (uint8)(total_time / 3600);

play_time.minute = (uint8)((total_time / 60) % 60);

play_time.second = (uint8)(total_time % 60);

/* printf file header information */

printf("%s %ldHz %dbit, DataLen: %ld, Rate: %ld, Length: %2ld:%2ld:%2ld\n",

channel_mappings[wave.header.channels], //聲道

wave.header.samp_freq, //采樣頻率

wave.header.bit_samp, //每個(gè)采樣點(diǎn)的量化位數(shù)

wave.length,

wave.header.byte_rate,

play_time.hour,play_time.minute,play_time.second);

//fclose(wave.fp); /* close wave file */

}

按結(jié)構(gòu)體一點(diǎn)點(diǎn)的讀出文件頭的信息,請(qǐng)注意

/* jump to "data" for reading data */

的那一段,“先識(shí)別data標(biāo)識(shí)符,再接著往下讀取”。

(3)讀數(shù)據(jù)

在讀完數(shù)據(jù)長(zhǎng)度之后就全是數(shù)據(jù)了,直接使用fread按uint32格式讀取數(shù)據(jù)即可,我這里每次讀取1152個(gè)數(shù)據(jù)(即一幀)。

/*

* get wave data

*/

uint32* GetWave(void)

{

static uint32 buffer[1152] = {0};

uint16 n = 0;

uint16 p = 0;

p = fread(buffer, sizeof(uint32), n, wave.fp);

if(!p)

{

return 0;

}

else

{

for(; p

{

buffer[p] = 0;

}

return buffer;

}

}

上面程序中注意幾點(diǎn),

(1)不要定義大容量的局部變量,因?yàn)榫植孔兞看娣旁诙褩V小H绻欢ㄒx,要定義成static類(lèi)型。

(2)不要返回局部變量的的地址,因?yàn)樵诙褩V械牡刂分凳遣淮_定的。

上面的程序返回局部數(shù)組的指針,前提是 已經(jīng)將數(shù)據(jù)存放在靜態(tài)數(shù)據(jù)存儲(chǔ)區(qū)。

但不管怎樣,返回局部變量的地址總是不好的。

總結(jié)

以上是生活随笔為你收集整理的c语言 文件 long double 读取,读取*.wav音频文件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。