[Java8] PSGぽい音を出す。
JavaでPSGぽい音を出すサンプルです。タイトルでJava8って書いてるけど、古いのでもいけると思います。(どのバージョンから出来るのかは確認してない)
package jp.hemohemo.testaudio; import java.util.logging.Level; import java.util.logging.Logger; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; public class TestAudio { /** * @param args the command line arguments */ public static void main(String[] args) { int SAMPLING_RATE = 44100; // 44.1kHz(CDと同じ) // オーディオフォーマットを準備 AudioFormat format = new AudioFormat( SAMPLING_RATE, // サンプリング周波数 16, // 16ビット 2, // ステレオ true, // 符号 true // ビッグエンディアン ); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); SourceDataLine line; try { // データラインを取得 line = (SourceDataLine)AudioSystem.getLine(info); // ラインを開く line.open(); } catch (LineUnavailableException ex) { Logger.getLogger(TestAudio.class.getName()).log(Level.SEVERE, null, ex); return; } // 1秒間の波形データを準備 int freq = 440; // ラ(A)の周波数(440Hz) int vol = 2000; // 音量 byte[] datas = new byte[SAMPLING_RATE * 2 * 2]; // ステレオ、16ビットなので * 2 * 2なる int val; for(int i = 0; i < SAMPLING_RATE; i++) { int tmp = (int)(2 * i * freq / SAMPLING_RATE); if(tmp % 2 == 0) { val = vol; } else { val = -vol; } // 左チャンネル datas[i * 2 * 2 + 0] = (byte)((val >> 8) & 0xff); datas[i * 2 * 2 + 1] = (byte)(val & 0xff); // 右チャンネル datas[i * 2 * 2 + 2] = (byte)((val >> 8) & 0xff); datas[i * 2 * 2 + 3] = (byte)(val & 0xff); } line.start(); // 波形データを書き込む line.write(datas, 0, datas.length); // 鳴り終わるのを待つ line.drain(); line.stop(); line.close(); } }
まっ、見ればわかると思いますが、最初のほうでCDと同等の音質でデータラインを取得して、そこに440Hzの矩形波のデータを用意して書き込んでる。このfreqの値を変えると音程が変更でき、volを変更すると音量が変わる。
和音の出し方は別の音程の波形データを加算するだけでOK。ただし、オーバーフローしないようにしないといけない。
最近のコメント