Android 播放指定頻率正弦波聲音
用Android裝置來播放指定頻率的純音,首先考慮到純音是一種固定頻率的聲波,其實也就是正弦聲波了。其實所有聲音都是有正弦波組成,只不過純音是固定頻率的正弦波。那麼要實現Andoird播放純音,那麼首先就應該繪製出正弦波來。 那麼看下面這段程式碼:
public class SinWave { /** 正弦波的高度 **/ public static final int HEIGHT = 127; /** 2PI **/ public static final double TWOPI = 2 * 3.1415; /** * 生成正弦波 * @param wave * @param waveLen 每段正弦波的長度 * @param length 總長度 * @return */ public static byte[] sin(byte[] wave, int waveLen, int length) { for (int i = 0; i < length; i++) { wave[i] = (byte) (HEIGHT * (1 - Math.sin(TWOPI * ((i % waveLen) * 1.00 / waveLen)))); } return wave; } }
首先正弦波的高度設定為127,因為這裡只打算使用8位的取樣率,2的8次方就應該是256,所以正弦波的波峰就應該是127了。sin(byte[] wave, int waveLen, int length)方法就是根據波的長度還有整個聲波的總長度來生成正弦波的值。最後可以根據陣列下標將值打印出來,就是正弦波的形狀了(只是不是很規則啦。。。)
生成正弦波的方法有了,那麼接下來就該實現播放正弦波的方法了。Android給我們實現了這個介面,那麼就是AudioTrack這個類了。將正弦波資料傳入這個類的write方法中,就可以播放正弦波了。。。很簡單吧 ,那就直接看程式碼吧。
初始化AudioTrack首先傳入一個指定頻率,這裡先將聲音總頻率設定為44100,然後計算出單個正弦波(也就是2PI)的長度,最後將單個正弦波的長度乘以頻率取得聲波的實際頻率,這樣的是為了避免聲波最後出現一段空的聲波。 然後將引數傳入剛才SinWave類的sin方法中取得正弦波。AudioFormat.ENCODING_PCM_8BIT就是指定AudioTrack使用8位取樣率。
/** * 設定頻率 * @param rate */ public void start(int rate){ if(rate>0){ Hz=rate; waveLen = 44100/ Hz; length = waveLen * Hz; audioTrack=new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, // CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT,length,AudioTrack.MODE_STREAM); //生成正弦波 wave=SinWave.sin(wave, waveLen, length); if(audioTrack!=null){ audioTrack.play(); } }else{ return; } }
這裡注意,AudioTrack.play()是還不能播放聲音的,因為這個時候AudioTrack裡面還沒有聲波資料。下面這段程式碼才是真的播放聲音:
audioTrack.write(wave, 0, length);
將剛才生成的正弦波資料寫入AutioTrack中,那麼聲音也就播放出來了。。。。
下面是我寫的一個例子。只需要修改指定頻率,那麼就可以播放你想要播放的聲音了。(注:手機聲音關小點哦!!特別是3000Hz以上的聲音特別刺耳。。。切記切記)
原始碼地址: