5.2 拙作 DumpWave.java -- WAVE ファイルはこうやって読める

http://nalab.mind.meiji.ac.jp/~mk/program/sound/DumpWave.java

要点は
AudioInputStream ais = AudioSystem.getAudioInputStream(new File("sound.wav"));
byte [] data = new byte [ais.available()];
ais.read(data);
ais.close();
ということ。

(クラス・ライブラリィが使えるので、 readwave.c のような低レベルのことはする必要がない。)


以上はデータを一気に読む場合だが、 $ 1$ バイトずつ読んだり、 適当なサイズずつ読んだりする read() メソッドもある (ネットで検索すると簡単に見つかる)。


   1 /*
   2  * DumpWave.java
   3  */
   4 
   5 import java.io.IOException;
   6 import java.io.File;
   7 import javax.sound.sampled.*;
   8 
   9 public class DumpWave {
  10     public static void main(String [] args) {
  11         try {
  12             AudioInputStream ais =
  13                 AudioSystem.getAudioInputStream(new File(args[0]));
  14             // オーディオ入力ストリームからデータを読む (一気に読むバージョン)
  15             byte [] data = new byte [ais.available()];
  16             ais.read(data);
  17             ais.close();
  18             // ファイルのフォーマットを調べる
  19             AudioFormat af = ais.getFormat();
  20             System.out.println("#channels: "         + af.getChannels());
  21             System.out.println("#isBigEndian: "      + af.isBigEndian());
  22             System.out.println("#FrameSize: "        + af.getFrameSize());
  23             System.out.println("#SampleSizeInBits: " + af.getSampleSizeInBits());
  24             System.out.println("#SampleRate: "       + af.getSampleRate());
  25             if (af.getEncoding() == AudioFormat.Encoding.PCM_SIGNED) {
  26                 System.out.println("#符号付PCM");
  27             }
  28             else if (af.getEncoding() == AudioFormat.Encoding.PCM_UNSIGNED) {
  29                 System.out.println("#符号無PCM");
  30             }
  31             System.out.println("#サイズ: " + data.length + "バイト, "
  32                                + data.length / af.getSampleRate() + "秒");
  33             // ステレオ,16ビット,符号付PCM,リトルエンディアンのみ
  34             if (af.getChannels() == 2 &&
  35                 af.getSampleSizeInBits() == 16 &&
  36                 af.getEncoding() == AudioFormat.Encoding.PCM_SIGNED &&
  37                 (!af.isBigEndian())) {
  38                 short left, right;
  39                 for (int i = 0; i < data.length; i += 4) {
  40                     left  = (short)(data[i]   & 0xff | (data[i+1] << 8));
  41                     right = (short)(data[i+2] & 0xff | (data[i+3] << 8));
  42                     System.out.println("" + left + " " + right);
  43                 }
  44             }
  45             else {
  46                 System.out.println("#ステレオ,16ビット,符号付PCM,リトルエンディアンのみ対応");
  47             }
  48         } catch (Exception e) {
  49             e.printStackTrace();
  50             System.exit(1);
  51         }
  52     }
  53 }

コンパイル&実行
mathpc% javac DumpWave.java
mathpc% java DumpWave piano.wav
#channels: 2
#isBigEndian: false
#FrameSize: 4
#SampleSizeInBits: 16
#SampleRate: 44100.0
#符号付PCM
#サイズ: 1228068バイト, 27.847347秒
64 64
62 62
65 62
(後略)

桂田 祐史
2017-10-09