这个世界音频设备变幻无穷,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,主要是用来播放视频与录制视频的类。