C ++はWavファイルを読み取ります



C Read Wav File



C ++の初心者は、アルゴリズムを開始し、KaldiがC ++を開始して以来、訪問されていない多くのピットがあります。最近、手元にあるmatlabプログラムをC ++に変換する必要があります。これには、wavオーディオファイルの読み取りが含まれますが、これは非常に頭痛の種です。そこで、インターネットを検索して、自分で書き直してみました。私は自分のバージョンを書きました。ここでの主な記録は、レッスンと経験を理解しましょうです。

まず、この問題を実行する前に、wavファイルのサンプリングレートとビット数を知っていることを確認してください。ここでは、最も一般的な16kおよび16ビットのwavファイルを使用して説明します。大部分の人が考えています。バイナリストリームを使用して暴力的に読むことはできますか。クラスメートのアイデアは良いですが、逸脱があります。 Auditonをプレイしたことがあるかどうかはわかりませんが、プレイしたことがなくても、2つのオーディオ編集ソフトウェアであるクールな編集について聞いたことがあるはずです。あなたがwav、mp3および他のフォーマットのファイルをそれに投げ込むとき、彼はあなたに何も尋ねません、そして彼はサンプリングレートとチャンネル数を知っています。そして、pcm形式のオーディオを投入すると、彼はこの質問をします。以下は、Adobeオーディションのスクリーンショットです。



では、なぜあなたは思いますか?同じ2種類のファイルが1つについてすべてを知っていて、1つについて何も知らないのはなぜですか?よく考えてみると、思いつくのは難しいことではありません。wav(mp3)などのファイルにはロゴの特定の部分があり、特定の標準になっているので、特定のデコードに従って解釈すると、関連するコンテンツ。そして、pcmには何もありません。次に、wavに識別ビットが含まれていることは明らかです。識別ビットを要求せずに直接激しく読むことは明らかに間違っています。このアイデアに従って、wavフラグの内容についてオンラインで検索し、次の図を見つけました。



ここでの位置はすべてバイトなので注意してください。次に、各バイトが何を識別しなければならないかを確認し、プログラムの設計を開始します。この構造体は16ビットであるため、構造体を使用してこの構造体を識別します。整数型の場合は2バイトで読み取るため、int16_tを使用して最小読み取り単位(charを除く)を表します。次に、プログラムを以下に示します。

#include #include #include #include using namespace std struct WavData{ public: int16_t* data long size WavData(){ data=NULL size=0 } } void loadWavFile(const char* fname,WavData *ret){ FILE* fp=fopen(fname,'rb') if(fp){ char id[5] int32_t size int16_t format_tag,channels,block_align,bits_per_sample int32_t format_length,sample_rate,avg_bytes_sec,data_size fread(id,sizeof(char),4,fp) id[4]='' if(!strcmp(id,'RIFF')){ fread(&size,sizeof(int16_t),2,fp) fread(id,sizeof(char),4,fp) id[4]='' if(!strcmp(id,'WAVE')){ fread(id,sizeof(char),4,fp) fread(&format_length,sizeof(int16_t),2,fp) fread(&format_tag,sizeof(int16_t),1,fp) fread(&channels,sizeof(int16_t),1,fp) fread(&sample_rate,sizeof(int16_t),2,fp) fread(&avg_bytes_sec,sizeof(int16_t),2,fp) fread(&block_align,sizeof(int16_t),1,fp) fread(&bits_per_sample,sizeof(int16_t),2,fp) fread(id,sizeof(char),4,fp) fread(&data_size,sizeof(int16_t),2,fp) ret->size=data_size/sizeof(int16_t) // Dynamically allocated space, remember to release ret->data=(int16_t*)malloc(data_size) fread(ret->data,sizeof(int16_t),ret->size,fp) } else{ cout<<'Error: RIFF File but not a wave file ' } } else{ cout

結果は検証できますので、皆様のお役に立てれば幸いです。