web-dev-qa-db-ja.com

C / C ++でのWAVファイルデータの読み取りと処理

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

これは私が現時点でファイルを読む方法です:

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

前もって感謝します。

13
Luxk

私の最初の推奨は、あなたを助けるためにある種のライブラリーを使用することです。ほとんどのサウンドソリューションはやり過ぎに見えるので、単純なライブラリ(質問のコメントで推奨されているライブラリ libsndfile など)でうまくいくはずです。

自分でWAVファイルを読み取って自分で書き込めるようにしたい場合(学校が他の一般の人と同じようにライブラリを使用するようになっていると、学校が邪魔になる可能性があるため)、簡単なGoogle検索ですべての情報が得られます必要 プラス.wav形式の読み取りに関する多くのチュートリアルをすでに書いている人もいます

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

以下のコードを見るときは、reader.Read...( ... )を、示された型の整数値とバイトサイズの同等のfread呼び出しに置き換えます。 WavChunksは、WAVファイルチャンク内のIDのリトルエンディアン値である列挙型であり、format変数は、に含めることができるWav形式タイプのタイプの1つです。 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;
    }
}
16
user1357649