Android音頻介紹

這個世界音頻設備變幻無窮,Android也不可能爲每種設備都提供支持。Android定義了一個框架,這個框架來適配底層的音頻設備。該適配層的定義位於:java

hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.hlinux

要想視頻底層的音頻設備必需要繼承該文件中定義的AudioStreamOut,AudioStreamIn,AudioHardwareInterface等類,並實現createAudioHardware函數。android

下面咱們看一下Android建立音頻設備的代碼,代碼位於:app

frameworks/base/libs/audioflinger/AudioHardwareInterface.cpp框架

該文件有以下代碼:ide

AudioHardwareInterface * AudioHardwareInterface::create()函數

{佈局

/*性能

*FIXME:This code needs to instantiate thecorrect audio device網站

*interface.For now-we use compile-timeswitches.

*/

AudioHardwareInterface*hw=0;

char value[PROPERTY_VALUE_MAX];

#ifdef GENERIC_AUDIO

hw=new AudioHardwareGeneric();

#else

//if running in emulation-use the emulatordriver

if(property_get("ro.kernel.qemu",value,0)){

LOGD("Running in emulation-usinggeneric audio driver");

hw=new AudioHardwareGeneric();

}

else{

LOGV("Creating Vendor Specific AudioHardware");

hw=createAudioHardware();

}

#endif

if(hw->initCheck()!=NO_ERROR){

LOGW("Using stubbed audio hardware.Nosound will be produced.");

delete hw;

hw=new AudioHardwareStub();

}

#ifdef WITH_A2DP

hw=new A2dpAudioInterface(hw);

#endif

#ifdef ENABLE_AUDIO_DUMP

//This code adds a record of buffers in afile to write calls made by AudioFlinger.

//It replaces the currentAudioHardwareInterface object by an intermediateone which

//will record buffers in a file(aftersending them to hardware)for testing purpose.

//This feature is enabled by definingsymbol ENABLE_AUDIO_DUMP.

//The output file is set withsetParameters("test_cmd_file_opening PCM dump

interface");

hw=new AudioDumpInterface(hw);//replaceinterface

#endif

return hw;

}

從代碼中咱們能夠看出若是定義了GENERIC_AUDIO的宏,則會建立AudioHardwareGeneric,若是是模擬器的話,AudioHardwareGeneric會不能初始化,進而建立AudioHardwareStub。這兩個類都是Audio設備的適配層,是Android默認提供的模擬器都是用AudioHardwareStub,不會有聲音輸出設備都是用AudioHardwareGeneric,由於默認GENERIC_AUDIO是設置的通常咱們只關心AudioHardwareGeneric實現,誰會去給模擬器去調試聲音呢,反正我沒這個閒心。

首先說明一下這個音頻適配層是Android自帶的,能夠保證你的音頻設備正常運行,可是不能發揮設備的最佳性能。

經過後面的描述你將會了解AudioHardwareGeneric的定義位於:

frameworks/base/libs/audioflinger/AudioHardwareGeneric.cpp

查看源碼你會發現這個適配層須要實現設備/dev/eac,而且該設備只輸出44.1khz採樣率的音頻數據給/dev/eac設備,若是不是44.1khz的採樣率的數據,AudioHardwareGeneric會通過Resample過程把它轉換成44.1kHZ的音頻數據,而後再輸出給音頻設備。44.1kHZ音頻數據是最廣泛的音頻採樣率,大部分Mp3都是以這個採樣率壓縮的,因此選擇這個採樣率作爲默認採樣率仍是有必定的合理性的。

AudioHardwareGeneric是軟件實現Resample過程是,效率會比較低。不少音頻設備支持不一樣採樣率的數據,能夠理解成硬件實現Resample過程。經過上面的描述咱們能夠知道這個通用音頻適配層只是讓你的設備能夠用而已,不能發揮設備的性能優點,若是你的設備對音頻質量有更高的要求,必需要本身實現音頻適配層。谷歌只能保證你的音頻能夠播放,可是不能保證效率(他也沒有辦法保證效率)。

所支持的音頻格式

對於播放,Android支持各類各樣的音頻文件格式和編解碼。對於錄音的支持少一些。

之後咱們學到錄音部分將會討論這點。

AAC:

高級音頻編碼(以及其擴展:HEAAC)編解碼,.m4a,.3gp文件.AAC是一個流行的標準,IPOD和其餘便攜式媒體播放器都使用它。Android在MPEG4音頻文件和3GP文件內(都是基於MPEG4格式)支持這種音頻格式。最近AAC的附加規範HE AAC也被支持了。

MP3:

MPGE-1音頻層3,.mp3文件。Android支持MP3,MP3多是使用最普遍的音頻編解碼,這容許Android經過各類網站和音樂商店來使用大部分在線音頻。

AMR:

自適應多速率編解碼(AMR-NB,AMR-WB),.3gp,.amr文件。AMR音頻編解碼已經被標準化了,主要被3GPP(第三代合做夥伴項目)用於語音音頻編解碼。3GPP是一個爲其合做夥伴建立規範的電信行業機構。換句話說,AMR編解碼主要用於現代移動電話的語音呼叫程序,而且手機廠商和手機攜帶者廣泛都支持這個格式。AMR這格式通常對語音編碼頗有用,但對更復雜的類型表現的不夠好,好比音樂。

Ogg:

Ogg Vorbis,.ogg文件。Ogg Vorbis是個開源的,無專利費的音頻編解碼。其品質可媲美商業性的,需繳納專利費的編解碼好比MP3,AAC它由一羣自願者開發,當前由Xiph.Org基金會負責維護。

PCM:

脈衝編碼調製一般被用在WAVE,WAV文件,.wav文件。PCM這技術主要用於音頻在電腦和其餘電子音頻設備上的存儲。它一般是個未壓縮的音頻文件,其數據表明隨着時間流逝一段音頻的振幅。「採樣率」是多長時間一次一個振幅讀取被存儲起來。「位深度」是指多少位被用來表明一個單獨的樣本。一段16KHZ採樣率,32位位深度的音頻數據是指它包含每秒鐘16000個的32位的數據用來表示音頻振幅。採樣率和位深度越高,數字化音頻越精準。採樣率和位深度也決定了音頻文件的大小。Android在WAV文件內支持PCM音頻數據。WAV是PC上的一個長期存在的標準音頻格式。

經過Intent使用內建的音頻播放器

正如使用攝像頭,在一個應用程序裏提供播放音頻文件的能力,最容易的方法就是:使用內建的「音樂」程序的功能。這個程序有個用戶熟悉的界面,能播放全部Android支持的格式,而且能經過一個intent,被觸發去播放一個指定的文件。普通的android.content.Intent.ACTION_VIEW intent,其數據設置爲一個音頻文件的Uri,並指定其MIME類型,這樣Android會自動選擇一個合適的應用程序來播放。這個程序應該是內建的音樂播放程序,但用戶可能被提供其餘的選項,若是他/她安裝了其餘的音頻播放軟件。

1.Intent intent=newIntent(android.content.Intent.ACTION_VIEW);

2.intent.setDataAndType(audioFileUri,"audio/mp3");

3.startActivity(intent);

註解:MIME全稱是MultipurposeInternet Mail Extension(s多用途互聯網郵件擴展)。它起初專門用來幫助電子郵件客戶端發送和接收附件。但它的使用範圍從電子郵件極大地擴展到其餘的通信協議,包括HTTP,標準萬維網服務。Android使用MIME類型來解析intent,而且用它來決定應該選擇哪一個應用程序來處理intent.

每一個文件類型都有特定的(有時候不止一個)MIME類型。MIME類型經過至少由2部分組成,由斜槓分開的字符來指定。第一部分是更通用的類型,好比「audio」.第二部分是更具體的類型,好比"mpeg".一個通用的類型"audio"和一個更具體的類型"mpeg"將產生一個「audio/mpeg"MIME類型字符,這個MIME類型一般用於MP3文件。

Android音頻實例分析

這裏有個經過一個intent觸發內建的音頻播放程序的完整例子。

1.packagecom.apress.proandroidmedia.ch5.intentaudioplayer;

2.import java.io.File;

3.import android.app.Activity;

4.import android.content.Intent;

5.import android.net.Uri;

6.import android.os.Bundle;

7.import android.os.Environment;

8.import android.view.View;

9.importandroid.view.View.OnClickListener;

10.import android.widget.Button;

咱們的activity在觸發音頻播放以前會一直監聽一個Botton是否被按下。

1.public class AudioPlayer extendsActivity implements OnClickListener{

2.Button playButton;

3.@Override

4.public void onCreate(BundlesavedInstanceState){

5.super.onCreate(savedInstanceState);

6.setContentView(R.layout.main);

咱們將content view設置爲咱們的XML後,咱們能獲得一個Button的引用,並將咱們的activity(this)設爲OnClickListener.

1.playButton=(Button)this.findViewById(R.id.Button01);

2.playButton.setOnClickListener(this);

3.}

當咱們的Button被點擊,OnClick方法會被調用。在這個方法裏,咱們用一個普通的android.content.Intent.ACTION_VIEW來構建intent,而後建立一個文件對象,這個對象是SD卡上已經存在的音頻文件的索引。這種狀況下,這個音頻文件被手動放置到SD卡的「Music"目錄下,這個目錄一般放置和音樂相關的音頻文件。

1.public void onClick(View v){

2.Intent intent=new Intent(android.content.Intent.ACTION_VIEW);

3.Filesdcard=Environment.getExternalStorageDirectory();

4.File audioFile=newFile(sdcard.getPath()+"/Music/goodmorningandroid.mp3");

接下來,咱們設置intent的數據爲來源於音頻文件的Uri並將其類型設置爲MIME類型,audio/mp3.最後傳遞咱們的intent給startActivity來觸發內建的音樂播放程序。

1.intent.setDataAndType(Uri.fromFile(audioFile),"audio/mp3");

2.startActivity(intent);

3.}

下面是一個簡單的XML佈局文件,其中Button的文本爲"Play Audio",前面所述的

activity會用到這個Button.

1.<?xmlversion="1.0"encoding="utf-8"?>

2.<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

3.android:orientation="vertical"

4.android:layout_width="fill_parent"

5.android:layout_height="fill_parent"

6.>

7.<Button android:text="Play Audio"android:id="@+id/Button01"

8.android:layout_width="wrap_content"android:layout_height="wrap_content"

></Button>

9.</LinearLayout>

Android支持的視頻格式

先簡要說明下Android支持的視頻格式,以下:

因爲硬件的不一樣,不一樣的手機支持的編解碼方式有些不同,在T-Mobile G1實際設備中增長了對WMA,WMV,H.264 AVC格式解碼的支持。Android支持的音/視頻編碼方式僅包括:AMR-NB,H.263,輸出的視頻格式也只*.3gp或者*.mp4,這點在之後的開發中須要注意。對Android的編解碼有了一些瞭解後,咱們再去研究下如何在Android上來播放/錄製視頻,打開Android SDK中關於媒體方面的說明,摘要其主要部分以下:

首先注意的就是:MediaPlayer,MediaRecoder,主要是用來播放視頻與錄製視頻的類。

來自:http://www.linuxidc.com/Linux/2011-09/42419.htm

相關文章
相關標籤/搜索