質問: 音声データのrawファイルをcのプログラムで読み込み、引数で与えた開始と終了時間の音声波形をgnuplotかexcelで表示したいのですが、rawファイルをどう読み込めばいいのか、どう引数を与え音声波形を表示すればいいのかわかりません。 **追加情報** サンプリングで使うデータについて分かることは16KHzのデータで16bitです。チャンネルはモノラルでエンディアンについては申し訳ないのですがわかりません。 使用しているOSはRetHat Enterprise Linux5のUNIX系のOSです。 関数freadを使用して出来ないかと考えていたのですが、どうソースコードを書けばいいかよくわかりません。 構成のヒントを教えてくださると助かります。
回答: rawといってもPCMデータをヘッダ情報なしで生のまま格納したものということなので、まずその中にどんなデータが入っているかを知る必要があります。大抵の場合次のバリエーションを想定すればいいと思います。 * サンプルのbit幅(8/16) * 負号有無(singed/unsigned)=C言語のsigned/unsignedと同じ意味 * エンディアン(big/little)=16bitの場合下位バイトが先(little)か後(big)か * チャンネル数(モノラル、ステレオ)=ステレオならL,Rが交互に並ぶ * 周波数(CD品質なら44.1KHz)=波形には直接関係しませんが再生の際に関係しますね。 まずはCの標準ライブラリーを用いてファイルを読みその中身を上記のバリエーションのどれかを仮定して解析してみたらよいと思います。例えば16bit,signed,little-endian,ステレオなら次のように入っています。(ステレオの場合左右どちらが先か自分は正確に知りません。以下は左が先と仮定しています) ``` 0x00 - 左スピーカー用: 下位8bit(負号付き) 0x01 - 左スピーカー用: 上位8bit(負号付き) 0x00 - 右スピーカー用: 下位8bit(負号付き) 0xFF - 右スピーカー用: 上位8bit(負号付き) ==> 最初のサンプルデータは 左: 256 右:-256 以下同様 ``` 描画についてはExcelであれば上記をCSV形式として出力しそれをExcelで読み込んでとりあえず折れ線グラフとして表示すると波形が見えると思います。ただあまりサンプル数が多いとExcelで表示するのは厳しいかもしれません。gnuplotについては経験ないのでわかっていませんが、こういったサイトを参考にされてはいかがでしょう。 追記: endianは個人PCの世界ではインテル系の石が多い(?)ように思うのでひとまずlittle-endian, signedだと仮定し実際の波形を見たり再生すると見当がつくと思います。再生の際はイヤホンを耳からちょっと離したりvolumeを絞るようにした方が安全かも知れません。 読み込みについてはfreadでもfgetcでもよいと思います。CPUと同じエンディアン、shortの語長が2byteと仮定するならモノラルデータはshortの配列へ直接読み込むと簡単です。 (手元にCがないので間違いがあったらご容赦) ``` #define BYTES_PER_SAMPLE sizeof(short) #define NATIVE_ENDIAN TRUE // CPUと同じエンディアンか? int main(int argc, const char* argv[]) { FILE fp = fopen("...", "r"); size_t sample_length = 1000; // サンプル数:ファイル長から求めた方が柔軟 size_t buffer_size = sample_length * BYTES_PER_SAMPLE; short* buffer = (short*)malloc(buffer_size); size_t i; short temp; size_t samples = fread(buffer, BYTES_PER_SAMPLE, sample_length, fp); // これでsample_length分のPCMサンプルがbuffferに読み込めるはず // もしエンディアンがPCのプロセッサと逆ならバイト順を入れ替える if (!NATIVE_ENDIAN) { for (i = 0; i < samples; i++) { temp = buffer[i]; buffer[i] = (short)(((temp >> 8) & 0xff) | (temp << 8)); } } ... } ```