Android進階音頻應用

來源:互聯網
上載者:User

標籤:android   audiotrack   audiorecord   

說到音頻應用,首先想到的就是音樂播放器。有些播放器可以播放流媒體,有些可以播放本地音樂檔案。隨著Android平台的演變,需要更多進階的音頻API。好在Google新增了這方面的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請關注本部落格後續會講解到。

Android進階音頻應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.