AudioTrackで音を鳴らす(修正2)
2011年3月2〜3日に、AudioTrackで音を鳴らすというブログを書いていますが、意外に検索してヒットしている方が多いので、更に修正したものをアップしておきます。
現在のLuarida 1.69Betaには、このバージョンが使われています。
修正した箇所は、onMarkerReached()にtry{}catch{}を追加しただけです。ここでエラーが出て落ちいてたので、エラーが出たときにはリリースするように修正しました。これでいいのかどうかは分かりません・・・(^^;。
//************************************************* // // ビープ音を鳴らすクラスを作ってみました // //************************************************* 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) { try{ if(track.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){ track.stop();// 再生完了したので発声停止 } } catch(Exception e){ //Log.e("Err",e.toString()); prAudioTrack.release(); } } } ); prAudioTrack.reloadStaticData(); // stop()後に再び再生するときに必要 prAudioTrack.write(prSoundData, 0, prSoundData.length); // ここで再生するデータをセット prAudioTrack.setNotificationMarkerPosition(prSoundData.length); // コールバックするタイミングを指定(再生データの最後) prAudioTrack.play(); }catch (Exception e) { //Log.e("Err",e.toString()); } } //************************************************* // // ビープ音を止めます // //************************************************* public void stop(){ if( prAudioTrack!=null ){ if(prAudioTrack.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){ prAudioTrack.stop();// 発声中なら停止 } prAudioTrack.release(); } } }