AudioTrackで音を鳴らす(修正)
昨日、AudioTrackで音を鳴らすプログラムを紹介したのですが、OS-1.6だと、minFrameCountエラーが出るようです。そこで、プログラムを修正しました。
AudioTrackをnewするときに、データ長の設定でminFrameCountよりも小さい値を設定すると、このエラーが出るようなので、強引に大きな値(今回は800)をセットするようにしました。後、エラートラップも付けました。AudioTrack#write時に実際のデータ長を入力しているので、音が鳴る時間には影響ないです。
修正したものは以下です。
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){ int framecount = 800; //minFrameCountエラーが出るので、仮に800を入れるように修正した 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(); } if( prSoundData.length>framecount ){ framecount = prSoundData.length; } try{ prAudioTrack = new AudioTrack( AudioManager.STREAM_MUSIC, // prSampleRate, //サンプリング周波数 AudioFormat.CHANNEL_CONFIGURATION_MONO, //モノラル AudioFormat.ENCODING_PCM_8BIT, //量子化ビット8ビット framecount, //データ長 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(); }catch (Exception e) { } } public void stop(){ if( prAudioTrack!=null ){ if(prAudioTrack.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){ prAudioTrack.stop(); } prAudioTrack.release(); } } }