Graph M8

モノラル(monaural 8)の Sound Data をグラフで表示します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. サウンドを演奏してデータを確認することは難しいのでグラフにして表示します。
    ringin.wav は Windwos System に効果音として格納されているファイルです。
    このファイルは、モノラルで量子化ビットが8でサンプリングレートが 11025 で作成されています。
    音声データは "data" のチャンクに続いて、8ビットで格納されています。
    8ビットのデータは 0~255 で表現され、128 が無音で上下に離れるほど音量が大きくなります。
  2. グラフを表示するので Windows(Form) モードでプログラムします。
    フォーム&グラフの表示は Line を描画する を参照して下さい。
    メニューの設定は メニューを設定する を参照して下さい。
    グラフは上限を 200, 中央を 328, 下限を 456 の線を引いて、128 を中心に上下幅 128 で描画します。
    ringin.wav はベルを鳴らす簡単なサウンドですが、サンプリングされたデータ件数は 9981 になっています。
    これをそのままグラフにすると幅が広がりすぎるので、10件置きに抽出して 1000 件程度のグラフにします。
  3. ringin.wav を入力して、グラフで表示するコードです。
    //★ WAV FILE M8 のグラフを表示する    前田 稔
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.IO;
    
    public class MyForm : Form
    {
        static string file_name = "C:\\data\\test\\ringin.wav";
        static byte[] byt = new byte[20000000];
        static int    m_leng, m_idx, m_siz;
        public MyForm()
        {
            Width = 1200;
            Height = 700;
            Text = "Wave M8 Graph";
            MainMenu menu = new MainMenu();
            MenuItem item = menu.MenuItems.Add("ファイル(&F)");
            item.MenuItems.Add(new MenuItem("音量を下げる(&D)", new EventHandler(this.Level)));
            item.MenuItems.Add(new MenuItem("終了(&X)", new EventHandler(this.FileExit), Shortcut.CtrlQ));
            item = menu.MenuItems.Add("ヘルプ(&H)");
            item.MenuItems.Add(new MenuItem("バージョン情報(&A)...", new EventHandler(this.HelpAbout)));
            this.Menu = menu;
            Paint += new PaintEventHandler(MyHandler);
            m_siz = WavRead();
            if (m_siz==-1)  this.Close();
        }
        private void Level(object sender, EventArgs e)
        {   int i,idx,v;
            for (i = 0; i < m_siz; i++)
            {   idx = m_idx + i;
                v = byt[idx];
                if (v < 128) v = 128-(128-v)/2;
                else v = (v-128)/2+128;
                byt[idx] = (byte)v;
            }
            Invalidate();
        }
    
        // ファイル-終了メニューのイベントハンドラ
        private void FileExit(object sender, EventArgs e)
        {   this.Close();  }
    
        // ヘルプ-バージョン情報メニューのイベントハンドラ
        private void HelpAbout(object sender, EventArgs e)
        {   MessageBox.Show("Wave Graph  Ver 1.0    by Maeda Minoru");  }
    
        // ウインドウを描画
        private void MyHandler(object sender, PaintEventArgs e)
        {
            int i, idx, v;
            Graphics g = e.Graphics;
            g.DrawLine(new Pen(Color.Black),100,200,1100,200);
            g.DrawLine(new Pen(Color.Black,3),100,328,1100,328);
            g.DrawLine(new Pen(Color.Black),100,456,1100,456);
            for (i=0; i<1000; i++)
            {
                if (i * 10 > m_siz) break;
                idx = m_idx + i*10;
                v = byt[idx];
                if (v < 128) g.DrawLine(new Pen(Color.Red), 100 + i, 328 - (128 - v), 100 + i, 328);
                else g.DrawLine(new Pen(Color.Red), 100 + i, 328, 100 + i, 200 + v);
            }
        }
    
        private int WavRead()
        {   int siz;    //Data Size
    
            if (!File.Exists(file_name)) return -1; //ファイルの有無をチェック
            FileStream reader = File.Open(file_name,FileMode.Open);
            m_leng= reader.Read(byt,0,byt.Length);
            reader.Close();
    
            if (get_str(0)!="RIFF")
            {   MessageBox.Show("Header Error");
                return -1;
            }
            if (get_str(8)!="WAVE")
            {   MessageBox.Show("Header Error");
                return -1;
            }
            if (get_str(12)!="fmt ")
            {   MessageBox.Show("Header Error");
                return -1;
            }
            Console.WriteLine("len:" + get_int(16));
            if (get_short(20) != 1)
            {   MessageBox.Show("Format Error");
                return -1;
            }
            if (get_short(22) != 1)
            {   MessageBox.Show("Format Error");
                return -1;
            }
            m_idx = 12;
            m_idx = m_idx+get_int(m_idx+4)+8;
            if (get_str(m_idx) != "data")
            {   MessageBox.Show("Format Error");
                return -1;
            }
            siz = get_int(m_idx+4);
            m_idx = m_idx + 8;
            return siz;
        }
    
        //☆ get_str() 関数,  get_short() 関数, get_int() 関数の定義
    }
    
    class Draw
    {
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  4. メニューから[音量を下げる]を選択すると Level() 関数で音量を半分にします。
    FileExit() 関数はプログラムを終了する関数です。
    HelpAbout() 関数は Version を確認する関数です。
    MyHandler() 関数でグラフを表示します。
    WavRead() 関数で Wave File を入力します。
    "data" チャンクに続く4byte(int 型)がサンプリングデータの長さで、その後に8ビットで音声データが格納されています。
    64617461 data チャンク
    FD260000 データサイズ(9981)
    7B30658D...8ビットの音声データが続く
  5. 次の関数は Volume M8 を参照して下さい。
    get_str() 関数で byt[idx] から4文字を取り出します。
    get_short() 関数で byt[idx] から short データを取り出します。
    get_int() 関数で byt[idx] から int データを取り出します。

[Next Chapter ↓] Graph S16
[Previous Chapter ↑] Volume M8

超初心者のプログラム入門(C# Frame Work)