Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android高級音頻應用

Android高級音頻應用

編輯:關於Android編程

說到音頻應用,首先想到的就是音樂播放器。有些播放器可以播放流媒體,有些可以播放本地音樂文件。隨著Android平台的演變,需要更多高級的音頻API。好在谷歌新增了這方面的API,支持低延遲的音頻流媒體和錄制。

 

Android音頻API提供了一些高級的功能,開發者可以把它們集成到自己的應用中。有了這些API,現在可以更容易地實現VoIP應用程序,構建定制的流媒體音樂客戶端,實現低延遲的游戲音效。此外,還有提供文本到語音轉換以及語音識別的API,用戶可以直接使用音頻和應用交互,而不需要使用用戶界面或者觸控技術。

 

低延遲音頻


Android有四個用來播放音頻的API(算上MIDI的話一共五個)和三個用來錄音的API。接下來會簡要的介紹這些API,以及一些高級用法示例。

 

①音頻播放API


音樂播放默認使用MediaPlayer。該類適合播放音樂或者視頻,既能播放流式資源,還可以播放本地文件。每個MediaPlayer都有一個關聯的狀態機,需要在應用程序中跟蹤這些狀態。開發者可以使用MediaPlayer類的API在自己應用中嵌入音樂或者視頻播放功能,而無需額外處理或者考慮延遲要求。

 

第二個選擇是SoundPool類,它提供了低延遲支持,適合播放音效和其他比較短的音頻,比如可以使用SoundPool播放游戲聲音。但是,它不支持音頻流,所以不適合那些需要實時音頻流處理的應用,如VoIP。

 

第三個選擇是AudioTrack類,它允許把音頻流緩沖到硬件中,支持低延遲播放,甚至適合流媒體場景。AudioTrack類通常提供足夠低的延遲,可在VoIP或類似應用中使用。

 

下面的代碼展示了如何在VoIP應用中使用AudioTrack:

 

public class AudioTrackDemo {
    private final int mMinBufferSize;
    private final AudioTrack mAudioTrack;

    public AudioTrackDemo() {
        this.mMinBufferSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        this.mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, this.mMinBufferSize*2, AudioTrack.MODE_STREAM);
    }

    public void playPcmPacket(byte[] pcmData) {
        if (this.mAudioTrack != null && this.mAudioTrack.getState() == AudioTrack.STATE_INITIALIZED) {
            if (this.mAudioTrack.getPlaybackRate() != AudioTrack.PLAYSTATE_PLAYING) {
                this.mAudioTrack.play();
            }
            this.mAudioTrack.write(pcmData, 0, pcmData.length);
        }
    }

    public void stopPlayback() {
        if (this.mAudioTrack != null) {
            this.mAudioTrack.stop();
            this.mAudioTrack.release();
        }
    }
}

 

首先,確定音頻流的最小緩沖區大小。要做到這一點,需要知道采樣率,數據是單聲道還是立體聲,以及是否使用8位或者16位PCM編碼。然後以采樣率和采樣大小作為參數調用AudioTrack.getMinBufferSize(),該方法會以字節形式返回AudioTrack實例的最小緩沖區大小。

 

接下來,根據需要使用正確參數創建AudioTrack實例。第一個參數為音頻的類型,不同的應用使用不同的值。對VoIP應用來說,使用STREAM_VOICE_CALL,而對於流媒體音樂應用則使用STREAM_MUSIC。

 

具體的選擇有:

STREAM_ALARM:手機鬧鈴的聲音
STREAM_MUSIC:手機音樂的聲音
STREAM_DTMF:DTMF音調的聲音
STREAM_RING:電話鈴聲的聲音
STREAM_NOTFICATION:系統提示的聲音
STREAM_SYSTEM:系統的聲音
STREAM_VOICE_CALL:語音電話聲音

 

第二,第三,第四個參數根據使用場景會有所不同。這些參數分別表示采樣率,立體聲或者單聲道,以及采樣大小。一般而言,一個VoIP應用會使用16KHZ的16位單聲道,而常規的音樂CD可能采用44.1KHZ的16位立體聲。16位立體聲高采樣率需要更大的緩沖區以及更多的數據傳輸,但是音質會更好。所有的Android設備都支持PCM以8KHZ,16KHZ,44.1KHZ的采樣率播放8或者16位立體聲。

 

緩沖區大小參數應該是最小緩沖區的倍數,實際取決於具體的需求,有時網絡延遲等因素也會影響緩沖區大小。

任何時候都應該避免使用空的緩沖區,因為可能導致播放出現故障。

 

最後一個參數決定只發送一次音頻數據(MODE_STATIC)還是連續發送數據流(MODE_STREAM)。第一種情況需要一次發送整個音頻剪輯。對於持續發送音頻流的情況,可以發送任大小塊的PCM數據,處理流媒體音樂或者VoIP通話可以會使用這種方式。

 

②錄制API


談到錄制音頻,首先要考慮的API是MediaRecorder。和MediaPlayer類似,需要在應用代碼中跟蹤MediaRecorder類的內部狀態。由於MediaRecorder只能把錄音保存到文件中,所以它不適合錄制流媒體。

如果需要錄制流媒體,可以使用AudioRecord,和剛才展示的代碼非常類似。

 

下面的示例顯示了如何創建AudioRecord實例錄制16位單聲道16KHZ的音頻采樣:

 

public class AudioRecordDemo {
    private final AudioRecord mAudioRecord;
    private final int mMinBufferSize;
    private boolean mDoRecord = false;

    public AudioRecordDemo() {
        this.mMinBufferSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        this.mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, this.mMinBufferSize * 2);
    }

    public void writeAudioToStream(OutputStream stream){
        this.mDoRecord=true;
        this.mAudioRecord.startRecording();
        byte[] buffer=new byte[this.mMinBufferSize*2];
        while(this.mDoRecord){
            int byteWritten=this.mAudioRecord.read(buffer,0,buffer.length);
            try{
                stream.write(buffer,0,byteWritten);
            }catch(IOException e){
                this.mDoRecord=false;
            }
        }
        this.mAudioRecord.stop();
        this.mAudioRecord.release();
    }

    public void stopRecording(){
        this.mDoRecord=false;
    }


}

 

因為和AudioTrack的創建過程非常類似,在使用VoIP或者類似應用時可以很方便地把它們結合起來。

 

相信學過多媒體的人對采樣率等這些東西並不陌生,如果缺乏這方面的知識,可以適當的補充後在來看這段代碼。

如果看的認真的人會發現本文只介紹了三個播放API和兩個錄制API,說好的四個的三個呢?其實最後一個不是一兩句就能說清楚,還需要單獨列出一篇文章講解——OpenSL ES請關注本博客後續會講解到。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved