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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

音频WAV详解

發布時間:2023/12/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 音频WAV详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

WAV是最常見的聲音文件格式之一,是Microsoft 和 IBM 為 PC 開發的一種聲音文件格式,該文件能記錄各種單聲道或立體聲的聲音信息,并能保證聲音不失真。它符合資源互換文件格式(RIFF)規范,用于保存Windows平臺的音頻信息資源,被Windows平臺及其應用程序所廣泛支持。

?

但WAV文件有一個致命的缺點,就是它所占用的磁盤空間太大(每分鐘的音樂大約需要12兆磁盤空間)。

WAVE文件支持很多不同的比特率、采樣率、多聲道音頻。WAVE是PC機上存儲PCM音頻最流行的文件格式,基本上可以等同于原始數字音頻。

WAVE文件為了與IFF保持一致,數據采用“chunk”來存儲。因此,如果想要在WAVE文件中補充一些新的信息,只需要在新chunk中添加信息,而不需要改變整個文件。這也是設計IFF最初的目的。WAVE文件是很多不同的chunk集合,但是對于一個基本的WAVE文件而言,以下三種chunk是必不可少的。

?文件中第一個chunk是RIFFchunk,然后是fmtchunk,最后是datachunk。對于其他的chunk,順序沒有嚴格的限制。可參考下圖:

WAV 格式定義?

RIFF頭chunk表示如下:

typedef struct {char ChunkID[4]; //內容為"RIFF"unsigned long ChunkSize; //存儲文件的字節數(不包含ChunkID和ChunkSize這8個字節)char Format[4]; //內容為"WAVE“ } WAVE_HEADER;

第二個塊是fmt chunk,它用來描述WAVE文件的特性,例如比特率、聲道數。可以使用結構體來描述fmt chunk.

typedef struct {char Subchunk1ID[4]; //內容為"fmt"unsigned long Subchunk1Size; //存儲該子塊的字節數(不含前面的Subchunk1ID和Subchunk1Size這8個字節)unsigned short AudioFormat; //存儲音頻文件的編碼格式,例如若為PCM則其存儲值為1。unsigned short NumChannels; //聲道數,單聲道(Mono)值為1,雙聲道(Stereo)值為2,等等unsigned long SampleRate; //采樣率,如8k,44.1k等unsigned long ByteRate; //每秒存儲的bit數,其值 = SampleRate * NumChannels * BitsPerSample / 8unsigned short BlockAlign; //塊對齊大小,其值 = NumChannels * BitsPerSample / 8unsigned short BitsPerSample; //每個采樣點的bit數,一般為8,16,32等。 } WAVE_FMT;

最后,描述包含實際聲音數據的data chunk:

typedef struct {char Subchunk2ID[4]; //內容為“data”unsigned long Subchunk2Size; //接下來的正式的數據部分的字節數,其值 = NumSamples * NumChannels * BitsPerSample / 8 } WAVE_DATA;

WAV 文件頭解析

這里是一個 WAVE 文件的開頭 72 字節:

52 49 46 46 | 24 08 00 00 | 57 41 56 45 66 6d 74 20 | 10 00 00 00 | 01 00 02 00 22 56 00 00 | 88 58 01 00 | 04 00 10 00 64 61 74 61 | 00 08 00 00 | 00 00 00 00 24 17 1E F3 | 3C 13 3C 14 | 16 F9 18 F9 34 E7 23 A6 | 3C F2 24 F2 | 11 CE 1A 0D

字段解析如下圖:?

WAV 開發實踐

PCM格式轉為WAV格式?

typedef struct WAVE_HEADER{ char fccID[4]; unsigned long dwSize; char fccType[4]; }WAVE_HEADER; typedef struct WAVE_FMT{ char fccID[4]; unsigned long dwSize; unsigned short wFormatTag; unsigned short wChannels; unsigned long dwSamplesPerSec; unsigned long dwAvgBytesPerSec; unsigned short wBlockAlign; unsigned short uiBitsPerSample; }WAVE_FMT; typedef struct WAVE_DATA{ char fccID[4]; unsigned long dwSize; }WAVE_DATA; int simplest_pcm16le_to_wave(const char *pcmpath,int channels,int sample_rate,const char *wavepath) {if(channels==0||sample_rate==0){channels = 2;sample_rate = 44100;}int bits = 16;WAVE_HEADER pcmHEADER; WAVE_FMT pcmFMT; WAVE_DATA pcmDATA; unsigned short m_pcmData;FILE *fp,*fpout; fp=fopen(pcmpath, "rb");if(fp == NULL) { printf("open pcm file error\n");return -1; }fpout=fopen(wavepath, "wb+");if(fpout == NULL) { printf("create wav file error\n"); return -1; } //WAVE_HEADERmemcpy(pcmHEADER.fccID,"RIFF",strlen("RIFF")); memcpy(pcmHEADER.fccType,"WAVE",strlen("WAVE")); fseek(fpout,sizeof(WAVE_HEADER),1); //WAVE_FMTpcmFMT.dwSamplesPerSec=sample_rate; pcmFMT.dwAvgBytesPerSec=pcmFMT.dwSamplesPerSec*sizeof(m_pcmData); pcmFMT.uiBitsPerSample=bits;memcpy(pcmFMT.fccID,"fmt ",strlen("fmt ")); pcmFMT.dwSize=16; pcmFMT.wBlockAlign=2; pcmFMT.wChannels=channels; pcmFMT.wFormatTag=1; fwrite(&pcmFMT,sizeof(WAVE_FMT),1,fpout); //WAVE_DATA;memcpy(pcmDATA.fccID,"data",strlen("data")); pcmDATA.dwSize=0;fseek(fpout,sizeof(WAVE_DATA),SEEK_CUR);fread(&m_pcmData,sizeof(unsigned short),1,fp);while(!feof(fp)){ pcmDATA.dwSize+=2;fwrite(&m_pcmData,sizeof(unsigned short),1,fpout);fread(&m_pcmData,sizeof(unsigned short),1,fp);} pcmHEADER.dwSize=44+pcmDATA.dwSize;rewind(fpout);fwrite(&pcmHEADER,sizeof(WAVE_HEADER),1,fpout);fseek(fpout,sizeof(WAVE_FMT),SEEK_CUR);fwrite(&pcmDATA,sizeof(WAVE_DATA),1,fpout);fclose(fp);fclose(fpout);return 0; }

注意聲道數和采樣率,一般采樣率有44100/16000/8000,另外聲道是1還是2,這兩個參數要設置好才會有正確的轉換結果。?

總結

以上是生活随笔為你收集整理的音频WAV详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。