2013-04-18 56 views
10

私は現在非常に重要な学校プロジェクトを行っています。 C/C++でWAVEファイルの情報を抽出し、この情報を使って音声信号のLPCを取得する必要があります。しかし、そのためには、ゼロクロスやエネルギー解析など、シグナルの前処理をいくつか行う必要があります。つまり、私はサインと本当の価値が必要です。問題は、私が有用な情報を入手する方法とその正しいフォーマットを知らないことです。私はすでにファイル内のすべてのフィールドを読み込んでいますが、私はそれを正しくやっているかどうかはわかりません。提案してください。 C/C++でのWAVファイルデータの読み込みと処理

これは私が現時点でファイルを読み込む方法である:

readI =のfread(& BPS、1、2、オーディオ)。 printf( "サンプルあたりのビット数=%d \ n"、bps)。

ありがとうございます。

+3

http://www.mega-nerd.com/libsndfile/ http://ccrma.stanford.edu/software/snd/sndlib/は、WAVでの作業に役立つ2つのライブラリです – Patashu

答えて

15

私の最初のお勧めは、あなたを助けるために何らかの種類のライブラリを使用することです。ほとんどのサウンドソリューションは過剰であると思われるので、単純なライブラリ(あなたの質問のコメントに推奨されているもの、libsndfileなど)はこのトリックを行うべきです。

WAVファイルを読む方法を知りたい場合は、自分で書くことができます(学校では他の一般の人と同様にライブラリを使用することができます)ので、すばやくGoogle検索であなたが必要とするすべての情報plus some people who have already wrote many tutorials on reading the .wav format

それでもそれが得られない場合は、データチャンクに到達するまで、ヘッダとWAV/RIFFデータファイルの他のすべてのチャンクを読んでください。それは、exclusively off the WAV Format Specificationに基づいています。実際のサウンドデータを抽出することはあまり難しいことではありません。生データをそのまま使用したり、生データを使用したり、内部的に(32ビットPCMの非圧縮データなど)より快適なフォーマットに変換できます。

reader.Read...(...)freadに置き換えて、指定された型の整数値とバイトサイズを呼び出します。 WavChunksはWAVファイルチャンクの内部IDのリトルエンディアン値で列挙され、そしてformat変数はWAVファイル形式に含めることができるWAV形式の種類のタイプのいずれかです:

enum class WavChunks { 
    RiffHeader = 0x46464952, 
    WavRiff = 0x54651475, 
    Format = 0x020746d66, 
    LabeledText = 0x478747C6, 
    Instrumentation = 0x478747C6, 
    Sample = 0x6C706D73, 
    Fact = 0x47361666, 
    Data = 0x61746164, 
    Junk = 0x4b4e554a, 
}; 

enum class WavFormat { 
    PulseCodeModulation = 0x01, 
    IEEEFloatingPoint = 0x03, 
    ALaw = 0x06, 
    MuLaw = 0x07, 
    IMAADPCM = 0x11, 
    YamahaITUG723ADPCM = 0x16, 
    GSM610 = 0x31, 
    ITUG721ADPCM = 0x40, 
    MPEG = 0x50, 
    Extensible = 0xFFFE 
}; 

int32 chunkid = 0; 
bool datachunk = false; 
while (!datachunk) { 
    chunkid = reader.ReadInt32(); 
    switch ((WavChunks)chunkid) { 
    case WavChunks::Format: 
     formatsize = reader.ReadInt32(); 
     format = (WavFormat)reader.ReadInt16(); 
     channels = (Channels)reader.ReadInt16(); 
     channelcount = (int)channels; 
     samplerate = reader.ReadInt32(); 
     bitspersecond = reader.ReadInt32(); 
     formatblockalign = reader.ReadInt16(); 
     bitdepth = reader.ReadInt16(); 
     if (formatsize == 18) { 
      int32 extradata = reader.ReadInt16(); 
      reader.Seek(extradata, SeekOrigin::Current); 
     } 
     break; 
    case WavChunks::RiffHeader: 
     headerid = chunkid; 
     memsize = reader.ReadInt32(); 
     riffstyle = reader.ReadInt32(); 
     break; 
    case WavChunks::Data: 
     datachunk = true; 
     datasize = reader.ReadInt32(); 
     break; 
    default: 
     int32 skipsize = reader.ReadInt32(); 
     reader.Seek(skipsize, SeekOrigin::Current); 
     break; 
    } 
} 
+1

なぜ16進数でRIFFが後方に書き込まれていますか?リトル/ビッグエンディアンについては知っていますが、私が使用したヘキサエディタはすべて、FFIRの代わりにRIFFとして表示しています。何か変わった変換をやっているのですか? – MarcusJ

+0

私は@MarcusJがRIFFを読むべきだと信じています、ここで波のフォーマットhttp://soundfile.sapp.org/doc/WaveFormat/の記述ですので、RiffHeader = 0x52494646でなければならないと信じています終点 – alexm

関連する問題