14

私は現在、非常に重要な学校のプロジェクトを行っています。C/C++ で WAVE ファイルの情報を抽出し、その情報を使用して音声信号の LPC を取得する必要があります。しかし、そのためには、信号に対して前処理を行う必要があります。たとえば、ゼロクロッシングやエネルギー分析などです。つまり、符号と実数値が必要です。問題は、有用な情報を取得する方法とその正しい形式がわからないことです。ファイル内のすべてのフィールドを既に読み取っていますが、正しく行っているかどうかはわかりません。提案をお願いします。

これは、現時点でファイルを読み取る方法です。

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

前もって感謝します。

4

1 に答える 1

19

私の最初の推奨事項は、何らかのライブラリを使用して支援することです。ほとんどの健全なソリューションはやり過ぎに見えるので、単純なライブラリ(質問のコメントで推奨されているlibsndfileなど)でうまくいくはずです。

WAV ファイルを読み込んで独自のファイルを作成する方法を知りたいだけの場合 (学校は、一般の人と同じようにライブラリを使用するように要求する可能性があるため)、簡単な Google 検索ですべての情報が得られます。さらに、.wav 形式の読み取りに関する多くのチュートリアルを既に書いている人も必要です。

それでもわからない場合は、データ チャンクに到達するまで WAV/RIFF データ ファイルのヘッダーと他のすべてのチャンクを読み取る独自のコードをいくつか示します。これは、WAV フォーマット仕様のみに基づいています。実際のサウンド データを抽出することはそれほど難しくありません。生で読み取って生で使用するか、内部的に使いやすい形式 (32 ビット PCM 非圧縮データなど) に変換することができます。

以下のコードを見て、指定された型の整数値とバイト サイズのreader.Read...( ... )同等の呼び出しに置き換えます。は、WAV ファイル チャンク内の ID のリトルエンディアン値である列挙型であり、変数は、WAV ファイル フォーマットに含めることができる Wav フォーマット タイプのタイプの 1 つです。freadWavChunksformat

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;
    }
}
于 2013-04-18T06:26:50.057 に答える