Javaで音声出力する
2014年2月7日:Java
Javaを使って、音を出力するプログラムを作成します。
作成するプログラムの内容としては
- 周波数を入力する
- 入力した周波数を1秒間鳴らす
というものです。
プログラムの作成
では、以下のようにプログラムを組んでください。
import javax.sound.sampled.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Hello extends JFrame { private JLabel lb; private JTextField tf; public static void main(String[] args) { Hello hl=new Hello(); } public Hello() { super("音再生ソフト"); lb=new JLabel("周波数[Hz]を入力してください。"); tf=new JTextField(); add(lb,BorderLayout.NORTH); add(tf,BorderLayout.SOUTH); tf.addActionListener(new SampleActionListener()); setSize(400,100); setVisible(true); } class SampleActionListener implements ActionListener { //テキストフィールドでEnterを押されたさいの処理 //1秒、入力された周波数の音を流す public void actionPerformed(ActionEvent e) { //テキストの値が正常か調べる JTextField tmp=(JTextField)e.getSource(); double a; try{ a=2*Math.PI/(44100.0/Double.parseDouble(tmp.getText())); }catch(Exception er){ System.out.println("error:"+er); return; } try{ byte[] data=new byte[44100*1]; //sin波の作成: for(int i=0;i<data.length;i++){ data[i]=(byte)(120*Math.sin(i*a)); } AudioFormat frmt=new AudioFormat(44100,8,1,true,false); //1秒あたりのサンプル数は44100個、 //音のビット数は8bit=256、 //チャネル数は1、 //値は正負型、 //bigEndianはfalse=リトルエンディアン DataLine.Info info=new DataLine.Info(Clip.class,frmt); Clip clip=(Clip)AudioSystem.getLine(info); clip.open(frmt,data,0,data.length); //再生を開始する clip.start(); //再生が終わるまでループする while(clip.isRunning()){ Thread.sleep(100); } }catch(Exception er){ System.out.println("error:"+er); } } } }
すると、以下のようなフォームが出てきて、
周波数を入力してEnterを押すと
指定した周波数の音がなります。もし、入力が不適切ならエラーを表示します。
このプログラムで大事な部分は
AudioFormat frmt=new AudioFormat(44100,8,1,true,false);
です。ここでは、一秒あたりのサンプル数を44100ことしています。つまり、1/44100秒刻みで音を記述していることになります。
そして、音の大きさを8bit=256で分割して設定しています。4番目がtrueなので、-128~128の正負で音を設定します。
128のギリギリだと怖いので
data[i]=(byte)(120*Math.sin(i*a));
と120でふっています。第三引数の1なのでモノラルで再生します。もし2ならステレオです。
著者:安井 真人(やすい まさと)
@yasui_masatoさんをフォロー