Visual Studio 2010 C# を使って生のwaveファイルデータを読みだし

森下功啓製作所 ONLINE


Microsoft社が無料で配布しているVisual Studio 2010 Express C#を使って生のwaveファイルデータを読みだすことを可能にするクラスライブラリを作ってみました。 どうぞ使ってみて下さい。 設計思想的には、「簡単WAVEデータの利用」を目指しています。 世に数多ある全てのWAVEフォーマットに対応しているわけではありませんが、8, 16, 24, 32 bit ステレオ・モノラル 無圧縮リニアPCMに対応していますので汎用性は高いと思います。


プログラムパッケージのダウンロード

[最新版の開発環境]
使用言語:VC#
マシン:Windows 7 Pro x64, Visual Studio 2010 Pro

リリース日 プログラムパッケージ 更新内容 開発言語
2013/3/30 Sound_20130330.7z データファイルによってはdataチャンクの前に独自のデータチャンクが追加されますが、これを読み飛ばすアルゴリズムを若干変更した。 これで普通のWAVEフォーマットのファイルならコード変更なしに読み込めるようになったはずです。 Microsoft VC# 2010
2012/11/3 SpectrogramWithFft_20121103.zip

WAVEファイルを一定のフレーム数だけ呼び出してFFTを行い、それを画像化してスペクトログラムを作るサンプルプロジェクトファイルです。 できるだけソースコード数を減らすように心がけましたので、読みやすいと思います(たぶん)。 なお、本プロジェクトファイルはビルド済みなのでbinフォルダ内にある*.exeを起動させれば即実行可能です(セキュリティのため、ソースコードをビルドしてから実行することを勧めます)。 プロジェクトファイルを開いた後にライブラリファイルの参照設定でエラーが出るようなら、binフォルダ内にあるdllを参照するように設定し直して下さい。

ちなみに、単にスペクトログラムが欲しい場合は既存のソフトを使うかMATLABを使う方が綺麗で早いと思います。
スペクトログラム
将来的にはリアルタイムスペクトログラム作成クラスも作りたい所です。
Microsoft VC# 2010
2012/07/13 Sound_20120713.zip

再び指摘を受けて、コメントと実装の不一致を解消しましたw。 また、ライブラリの追加方法についてちょっとだけ追記しています。 機能的には変更ありません。 ただし、WaveBaseクラスのインスタンスを作れないようにabstruct修飾子を付けています。 WaveBaseクラスは継承専用で、インスタンスを作っても使い道がありませんので影響はないと思います。

[追記]ライセンスファイルを同梱し忘れていましたので同梱して再アップしました。
Microsoft VC# 2010
2012/07/12 Sound_20120712.zip 指摘を受けて、MusicDataクラスのインデクサにあったバグを修正しました。

[2012/7/13 追記]ライセンスファイルを同梱し忘れていましたので同梱して再アップしました。
Microsoft VC# 2010
2012/05/07 Sound_20120507.zip クラスライブラリを作ることを覚えましたので、クラスライブラリ(dll)にしてみました。
以下、更新内容です。
  • 名前空間をSound.WAVEへ変更
ライブラリプロジェクトのファイル構成
図 ライブラリプロジェクトのファイル構成
ライブラリの利用方法は、プロジェクトの参照設定にdllを追加するか、以下の解説サイトにあるようにプロジェクトごと追加するかの2通りあります。
クラスライブラリの作成と使用方法(外部リンク)
前者の場合、そのままではコードを書いているときにメソッドの説明が表示されません。 表示させるためにはbinフォルダ内のXMLファイルもプロジェクトに追加してください。 なお、エラーを追っかけたい場合は後者の方法を採用してください。
Microsoft VC# 2010
2012/02/01 WaveReaderChecker_20120201.7z 最新のサンプルとクラスソースコードです。
本サンプルプログラムは、ここで公開しているWAVEファイル読み込みクラスで指定したWAVEファイルを取り扱い可能かどうかをチェックするツールです。 フォルダを指定することでそのフォルダ内のWAVEファイルを全てチェックして結果を報告・ログに残します。 WAVEファイルを読み込むのに使用するクラスのソースも同梱されています。
Microsoft VC# 2010
2011/12/02 FFT_WAVEfile_test_project3.zip
FFTandWaveClass.chm
最新のサンプルプログラムとそのヘルプファイルです。
中にWaveファイルを取り扱うwaveクラスのヘルプを含んでいるので参考にされて下さい。 ここに書きながら気が付いたのですが、クラス名の頭文字は大文字が原則でしたね。。。 その内変更します。
Microsoft VC# 2010
2011/10/08 wave_file_class_v2.zip 24/32 ビットのファイルにも対応しました。
また、FLLRチャンクがあっても処理できるようにしました。
さらに、ファイル名やパスを指定することでもファイル名を開けるようになりました。
さらに^2、今まではdouble型の配列にいちいちfor文で要素をコピーしていましたが、これをメソッドを呼び出すことで処理できるように変更しました。
サンプルプログラムはこちら
Microsoft VC# 2010
2011/2/23 wave_file_class.cs waveファイルを指定して、生データを取得することが出来るクラスライブラリです。
サンプルプログラムはこちら
Microsoft VC# 2010

最新版の使い方

[注意]2011/10/8リリース版でデータを受け取る仕様が変更されています。
先ずは開発中のプロジェクトにクラスファイルを追加して下さい。 追加後に、メインソースで使用できるようにusingを使用して名前空間を登録します。

using WAVE_file;

後は図1の様に宣言を行い、ファイルオブジェクトを開きます。 ここではOpenFileDialogを渡していますが、これはファイルの指定が確実にできるためです。 この他にも、例えば「this.wave_file.Open("hoge.wave")」とファイル名を指定してもOKです。 正常にファイルを開くことが出来ればいつでもRead()メソッドを介してバイナリデータを得られます。 Read()メソッドの引数は、int型で読み込むデータ数を直接指定する方法と、double型で読み込む時間を指定する2つの方法があります。 全てのデータを読み込むと、ReadLimitプロパティがtrueを返しますので、EOFを判断できます。 最後には、一応Close()メソッドを呼び出してリソースを解放しておいて下さい。

        wave wave_file = new wave();                                                // 宣言&実態確保
        
        /*------------------------------------------
         * waveファイル選択ボタンが押された時の動作
         *  ファイルを選択し、可能なら開く
         * --------------------------------------------*/
        private void wave_set_button_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK) {
                this.wave_file.Open(openFileDialog1);
            }
        }
        /*------------------------------------------
         * タイマーで定期的に実行される
         * 
         * --------------------------------------------*/
        private void FFTtimer_Tick(object sender, EventArgs e)
        {
            wave.MusicData data;                                                    // 音声ファイルから読み込んだデータ列が格納される。

            if (this.wave_file.IsOpen && this.wave_file.ReadLimit == false)         // 読めるなら、読み込む
            {
                // read
                data = this.wave_file.Read(0.58);                                   // クラスメソッドを使用してファイルから0.58秒間読み込み。実行の度に更新される。
                ほげほげ;
            }
        }
		
図1 基本的なコード

サンプルコードの簡単な紹介

2011/10/08にリリースしたサンプルコードについて説明します。 サンプルプログラムは、waveファイルを読み出してFFTを実施するものです。 以下にスクリーンショットを示します。 ボタンは2つしかありません。 waveファイルの読み込みボタンを押せばダイアログが開いてファイルを指定できるようになっています。 その後にFFTボックスにチェックを入れて「FFTを実行」ボタンでFFTが実行されます。

サンプルプログラム
図2 サンプルのスクリーンショット

コードの一部を図3に示します。 waveのデータをMusicDataクラスに格納させています。 この後にFFTを行うため、MusicDataクラスからdouble型配列を取得しています。

waveデータの取得コード例

図3 サンプルコードからwaveファイルのデータを受け取る部分を抜粋したもの

クラスメンバ

最新のクラスのメンバを図4に示します。 鍵マークがついているのはプライベートメンバとなっており、外部からはアクセスできません。 詳細についてはソースコードをご覧になってください。 コメントをたっぷり入れていますので困ることはないはずです。

WaveReaderクラスのクラスダイアグラム
図 WaveReaderクラスのクラスダイアグラム

参考文献

inserted by FC2 system