WAVEファイルの読込み/再生に関するページです。
WAVEファイルのフォーマット例の紹介とC言語の例題を以下のように準備しました。
以下に示すフォーマットは簡易的なWAVEファイルのフォーマットですので、詳細は他のサイトを参考にして下さい(ex. The Programmer's File Format Collection, WAVE PCM soundfile format)。
バイト数 | 説明 | |
ヘッダ | ||
4Bytes (DWORD) | 文字列"RIFF"(AVIと共通) | |
4Bytes (DWORD) | ファイルサイズ-8 | |
音声データ情報 | WAVEFORMATEX (in mmsystem.h) | |
4Bytes (DWORD) | 文字列"WAVE"(AVIの場合は"AVI ") | |
4Bytes (DWORD) | 文字列"fmt "(最後は半角スペース) | |
4Bytes (DWORD) | 音声データ情報のバイト数(PCM:16) | |
2Bytes (WORD) | フォーマットID(PCM:1) | WORD wFormatTag |
2Bytes (WORD) | チャンネル数(モノラル:1 ステレオ:2) | WORD nChannels |
4Bytes (DWORD) | サンプリング周波数(11025、22050、44100..) | DWORD nSamplesPerSec |
4Bytes (DWORD) | 1秒あたりの音声データのバイト数(Byte/sec) | DWORD nAvgBytesPerSec |
2Bytes (WORD) | 1サンプルあたりのバイト数(Byte/sample×チャンネル数) | WORD nBlockAlign |
2Bytes (WORD) | サンプルあたりのビット数(Bit/sample) | WORD wBitsPerSample |
拡張部分 | ||
2Bytes (WORD) | 拡張部分のバイト数 = n | WORD cbSize |
nBytes (DWORD) | 拡張データバイト | |
音声データ | ||
4Bytes (DWORD) | 文字列"data" | |
4Bytes (DWORD) | 音声データのバイト数(mとします) | |
mBytes | 音声データ(波形の変位のデータが順番に並びます。 ステレオの場合はLRLRの順に並びます。8bitデータは 0〜255, 16bitのデータは-32768〜+32767の範囲で値を とります。 |
|
コメント | ||
残りの部分 | コメント文字列 |
Gami[84]% dump ding.wav ding.wav: Addr 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 2 4 6 8 A C E -------- ---- ---- ---- ---- ---- ---- ---- ---- ---------------- 00000000 5249 4646 d03b 0100 5741 5645 666d 7420 RIFFP;..WAVEfmt 00000010 1000 0000 0100 0200 2256 0000 8858 0100 ........"V...X.. 00000020 0400 1000 6461 7461 7c3b 0100 f8ff 0100 ....data|;..x... 00000030 ffff feff 0500 0200 0500 0300 0300 fdff ..~...........}. 00000040 0100 0000 0200 faff ffff fdff fcff fbff ......z...}.|.{. 00000050 fbff faff f9ff f9ff f9ff f9ff f4ff f9ff {.z.y.y.y.y.t.y. 00000060 f8ff f7ff f5ff fbff f8ff fcff f7ff fdff x.w.u.{.x.|.w.}. 00000070 fbff 0300 0000 0500 fdff 0100 0300 0b00 {.......}....... 00000080 0500 0800 0700 0e00 0600 0a00 0900 0f00 ................ 00000090 0900 1000 0f00 1200 0700 0f00 0d00 1000 ................ 000000a0 0b00 1200 0a00 0e00 0a00 0c00 0900 0e00 ................ 000000b0 0700 0900 0500 0800 0600 0700 fcff 0000 ............|... 000000c0 0400 0400 fbff fcff faff fdff fbff fcff ....{.|.z.}.{.|. 000000d0 faff fcff faff fbff f9ff faff f5ff f6ff z.|.z.{.y.z.u.v. 000000e0 f6ff f7ff f6ff f8ff f4ff f7ff fbff f9ff v.w.v.x.t.w.{.y. 000000f0 f8ff fbff 0000 ffff f9ff faff 0800 0600 x.{.....y.z..... |
Windows XPに標準で付属の(ding.wav)というファイルを読み込んで表示した様子です。
Gami[948]% ./wave_info.exe ding.wav FILE: ding.wav **FILE HEAD FILE ID: RIFF FILE SIZE: 80[kByte] **WAVE FORMAT FORMAT ID: WAVE FORMAT TYPE: fmt FORMAT SIZE: 16 **WAVE INFO. WAVE TAG: 1 CHANNEL: 2 SAMPLE/SEC: 22050 BYTE/SAMPLE*CHANNEL: 4 BIT/SAMPLE: 16 **WAVE DATA INFO. DATA ID: data DATA SIZE: 80[kByte] Gami[949]% |
MCI(Media Control Interface)はWindows APIに付属のライブラリの中でマルチメディア関連の入出力を扱うものです。MCIを利用すると比較的簡単に音声・画像等を扱うことができます。
下記のソースは、MCIを利用したWAVE再生の例です。 cygwin/gcc でのコンパイル時にはMCIを利用可能にするよう、"windows.h"と"mmsystem.h"のインクルードと、libwinmm.aへのリンクが必要になります。
Gami[84]% gcc -o wav_p wav_p.c -lwinmm |
//----------------------------------------------------------------- // wav_p.cpp: // MCIデバイスのWAVE再生の例 // Last Update: <2005/01/27 04:07:20 A.Murakami> //----------------------------------------------------------------- #include <stdio.h> #include <windows.h> #include <mmsystem.h> //----------------------------------------------------------------- int InitMciDev(char* wav_file); void TermMciDev(); int PlayMciDev(); int MCILength(); //----------------------------------------------------------------- int main() { int mLen; char wav_file[] = "samp.wav"; // WAVの指定 if(InitMciDev(wav_file)){ fprintf(stderr,"MCIデバイスオープン失敗\n"); return -1; } // 演奏時間の取得 mLen = MCILength(); if(mLen <= 0){ fprintf(stderr,"演奏時間取得失敗\n"); } // 演奏開始 if(PlayMciDev()){ fprintf(stderr,"再生にエラーが発生しました\n"); return -1; } // 演奏時間の間停止。 printf("**%s:\n",wav_file); printf(" 演奏時間[%d]秒\n",mLen); if(!mLen) mLen+=5; sleep(mLen); printf("**演奏終了\n"); // 終了 TermMciDev(); return 0; } //----------------------------------------------------------------- // MCIデバイスのオープン //----------------------------------------------------------------- int InitMciDev(char* wav_file) { char cmd[256]; memset(cmd,0,sizeof(char)*256); sprintf(cmd,"open %s type waveaudio alias wav1",wav_file); return mciSendString(cmd,NULL,0,0); } //----------------------------------------------------------------- // MCIデバイスを閉じる //-----------------------------------------------------------------*/ void TermMciDev() { mciSendString("stop wav1",NULL,0,0); } //----------------------------------------------------------------- // MCIデバイスを再生する //----------------------------------------------------------------- int PlayMciDev() { return mciSendString("play wav1",NULL,0,0); } //----------------------------------------------------------------- // 演奏時間の取得 //----------------------------------------------------------------- int MCILength() { int ret; char status[30]; mciSendString("set wav1 time format milliseconds",NULL,0,0); ret = mciSendString("status wav1 length",status,30,0); if(ret) return 0; return atoi(status)/1000; } |