AudioTrackで音を鳴らす
Luaridaのユーザさんから、Beep音が欲しいという要望がありました。おぉぉ、Beep音、これは懐かしい。BASICなどで、ピーとなる音です。
これは作るしかないということで、Androidでピーって鳴らすプログラムを作ってみました。エイヤッとBeepCommandクラスを作りました。中身は、sin波を使ってwave波形データを作り、配列に入れてAudioTrackに渡すというものです。いろいろと参考になるサイトがたくさんありまして、それほど苦労せずに作ることができました。
修正版を次のブログに書きました。
BeepCommand
Beep音の周波数は最大10kHzとしました。そこで、サンプリング周波数は20kHz固定にしました。また、Beep音なので量子化ビットは8ビットとし、繰り返し鳴らすことも考えないことにしました。
引数には、鳴らす時間(sec)と周波数(Hz)が取れるようにしました。そして、stop()したら必ずリリースします。
public class BeepCommand { private static double prRegion = 0.5; //振幅の幅 -0.5 から 0.5 private byte[] prSoundData = null; //波形データ private static int prSampleRate = 20000; // サンプリング周波数20kHz private AudioTrack prAudioTrack = null; public void start(float sec, float hz){ //**** sin波形を生成 **** int dsu = (int)( (long)(sec*1000.0f)*5000L/250L); prSoundData = new byte[dsu]; for (int i = 0; i < dsu; i++) { double d = prRegion * Math.sin(2.0 * Math.PI * hz*sec * i /dsu); prSoundData[i] = (byte)(d * 127.0); } //*********************** if( prAudioTrack!=null ){ prAudioTrack.release(); } prAudioTrack = new AudioTrack( AudioManager.STREAM_MUSIC, prSampleRate, //サンプリング周波数 AudioFormat.CHANNEL_CONFIGURATION_MONO, //モノラル AudioFormat.ENCODING_PCM_8BIT, //量子化ビット8ビット prSoundData.length, //データ長 AudioTrack.MODE_STATIC ); prAudioTrack.setPlaybackPositionUpdateListener( new AudioTrack.OnPlaybackPositionUpdateListener() { public void onPeriodicNotification(AudioTrack track) { } // 再生完了時のコールバック public void onMarkerReached(AudioTrack track) { if(track.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){ track.stop();// 再生完了したので発声停止 } } } ); prAudioTrack.reloadStaticData(); //stop()後に再び再生するときに必要 prAudioTrack.write(prSoundData, 0, prSoundData.length); //再生するデータをセット prAudioTrack.setNotificationMarkerPosition(prSoundData.length); //コールバックタイミング指定 prAudioTrack.play(); } public void stop(){ if( prAudioTrack!=null ){ if(prAudioTrack.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){ prAudioTrack.stop();// 発声中なら停止 } prAudioTrack.release(); } } }
Beep音なので、これで多めに見てもらうということで、Luaridaの次のバージョンに入れたいと思います。