1. 程式人生 > >Android 播放指定頻率正弦波聲音

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以上的聲音特別刺耳。。。切記切記)

原始碼地址: