コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

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();
   }
 }
}