読者です 読者をやめる 読者になる 読者になる

bonar note

京都のエンジニア bonar の技術的なことや技術的でない日常のブログです。

Wavフォーマットと音の波

music Java

最近趣味で Java Sound API を弄ってます。外に出せるくらいのものになるまではまだまだ時間かかりそうですが、これがすごく面白い。Java Sound API を使うとすごく簡単に録音したり再生したりできます。ローカルのファイルを再生する場合はこんな感じですね。

        AudioInputStream in_stream = null;
        try {
            in_stream = AudioSystem.getAudioInputStream(audio_file);
            audio_fmt = in_stream.getFormat();
        }
        catch (IOException e) {
            System.err.println("IO error " + e.getMessage());
            System.exit(1);
        }
        
        ....
        int buffer_size = frame_size * 256;
        byte[] buffer   = new byte[buffer_size];

        try {
            int bytes_done = 0;
            while ((bytes_done = in_stream.read(buffer)) != -1) {
                line.write(buffer, 0, bytes_done);
            }
        }
        catch (IOException e) {
            System.err.println("stream IO error " 
                + e.getMessage());
        }

まずはもっとも単純な Wav形式のファイルを読んで再生するっていうのをやってます。

みての通り、ファイルをバッファに読み出してきて、それを出力ストリームに流し込むだけです。で、その受け渡しに使うバッファなのですが、これが普通のByte配列なんです。音声や音楽のファイルがByte配列で表現されているんです。

実際にWavファイルの組成を見ると、最初の44バイトがヘッダ情報で、その後は最後までずっと単なるByte配列になっています。CD音質ステレオのデータの場合、4バイトがひとつのフレームという単位で左右2バイトずつになっています。で、このセットが延々とつずいています。サンプリングレートが44.1MHzの場合、1秒間が44100個のフレームで表現されます。
#この数値が上がる程サンプリングの頻度があがりきめ細かい(音質のよい)データになります。

で、このそれぞれのバイトには単純に音圧が記録されており、連続することで波形を構成しています。ならべて見ると細かく振幅する波形(きめ細かい棒グラフの集合)になるわけですね。これらのデータが色々なサウンドデバイスに解釈され、スピーカーが空気を振動させて、それが音として知覚されるという感じです。途中かなりはしょってますが、そんな感じです。多分。

音が空気の振動だということは話としては知っていたのですが、このWavファイルのシンプルさを見て、正直軽く感動しました。これだけのことだったのかと。こんな風に音楽が表現されてて、それがByteの配列という非常に身近なものだなんて。それで、この巨大なByte配列をdumpしてみたり、音を出してみたり、音圧をグラフにして書き出したりしてそれっぽいものが出てくるのですが、なんかこうどうしても信じられないんですよね。

Byte配列っていう無機質なものが、チャットモンチーのシャングリラになるなんて。

  • 音声は空気の振動である
  • 空気の振動(アナログ信号)は定期的にプロットする(サンプリング)することでデジタルデータとして採取できる
  • それはByteの配列で表現できる
  • その配列をもとに空気を振動させると音が出る

とてもシンプル。シンプルすぎて神秘的。単なる巨大な配列が、あんなに複雑なメロディーやオシャレなリズムになるなんて、プログラムを実際に書いてみても信じられません。すごく不思議。音を出す部分もそうだし、それを認知するデバイス(鼓膜?脳?)もすごい。

これから、複数の波形を合成したり、特定の周波数を切り出したり、みたいのをやっていきたいなあ。あと、コード進行が与える心理的な効果(期待感、開放感、悲しさ、不安定感等)が先天的なもの(聴覚処理に始めからフックされてるフィルタなのか)なのか後天的なもの(学習の成果)なのかにも興味があります。これは調べれば結論でてるのかも。でもここから先は真剣に数学とむきあわなくちゃいけない予感。良い機会だからしっかり勉強しなおしたいなあ。


いや、でもなんか久々にトキメキました。