Javaで音声出力する

Javaを使って、音を出力するプログラムを作成します。

作成するプログラムの内容としては

  1. 周波数を入力する
  2. 入力した周波数を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ならステレオです。

著者:安井 真人(やすい まさと)