Android音频驱动开发

合集下载

android中音频视频开发教程(含代码)

android中音频视频开发教程(含代码)

本文简介媒体包提供了可管理各种媒体类型的类。

这些类可提供用于执行音频和视频操作。

除了基本操作之外,还可提供铃声管理、脸部识别以及音频路由控制。

本文说明了音频和视频操作。

范围:本文旨在针对希望简单了解Android编程的初学者而设计。

本文将指导你逐步开发使用媒体(音频和视频)的应用程序。

本文假定你已安装了可开发应用程序的Android和必要的工具,同时还假定你已熟悉Java 或掌握面向对象的编程概念。

如欲查询更多有关Android的详情,请参阅三星移动创新者园地(SMI)知识库网站。

/cn/platform.main.do?platformId=1简介通过“android.media”包支持音频和视频操作。

除了基本操作之外,还可以提供用于铃声管理、脸部识别以及音频路由控制的各种类。

Android通过MediaPlayer类支持播放音频和视频。

MediaPlayer类处于Android media包的核心位置。

除了MediaPlayer类之外,SoundPool和JetPlayer类也可提供用来播放音频文件。

播放音频文件MediaPlayer是播放媒体文件最为广泛使用的类。

MediaPlayer已设计用来播放大容量的音频文件以及同样可支持播放操作(停止、开始、暂停等)和查找操作的流媒体。

其还可支持与媒体操作相关的监听器。

通过以下方式可完成播放MediaPlayer中的音频和视频:·从源文件播放。

·从文件系统播放。

·从流媒体播放。

MediaPlayer监听器定义了部分监听器,如OnCompletionListener、OnPrepareListener、OnErrorListener、OnBufferingUpdateListener、OnInfoListener,OnVideoSizeChangedListener和OnSeekCompleteListener。

当在播放过程中到达媒体源末端时,可调用OnCompletionListener onCompletion(MediaPlayer mp)事件。

android驱动开发和移植详解

android驱动开发和移植详解

android驱动开发和移植详解本文出处:《Android 底层开发技术实战详解——内核、移植和驱动》我们开发的Android 驱动程序是基于Linux 内核的,本文首先介绍移植Android 系统的基本知识和基本原理,这也是为驱动开发打下坚实基础,知其然也知其所以然;最后我们将通过深入浅出的案例学习驱动开发过程。

1.1 驱动开发需要做的工作Android 作为当前最流行的手机操作系统之一,受到了广大开发人员和商家的青睐。

Android正在逐渐形成一个蓬勃发展的产业,带来了无限商机。

既然Android 这么火爆,我们程序员可以学习它的哪一方面的内容呢?本书的驱动开发又属于哪一领域呢?接下来将为读者奉上这两个问题的答案。

Android 是一个开放的系统,这个系统的体积非常庞大,开发人员无须掌握整个Android 体系中的开发知识,只需熟悉其中某一个部分即可收获自己的未来。

从具体功能上划分,Android 开发主要分为如下三个领域。

1. 移植开发移动电话系统移植开发的目的是构建硬件系统,并且移植Android 的软件系统,最终形成手机产品。

2. Android 应用程序开发应用程序开发的目的是开发出各种Android 应用程序,然后将这些应用程序投入Android 市场,进行交易。

Android 的应用程序开发是Android 开发的另一个方面。

从开发的角度来看,这种形式的开发可以基于某个硬件系统,在没有硬件系统的情况下也可以基于Linux 或者Windows 下的Android模拟器来开发。

这种类型的开发工作在Android 系统的上层。

事实上,在Android 软件系统中,第3 个层次(Java 框架)和第4 个层次(Java 应用)之间的接口也就是Android 的系统接口(系统API)。

这个层次是标准的接口,所有的Android 应用程序都是基于这个层次的接口开发出来的。

Android 系统的第4 个层次就是一组内置的Android应用程序。

android系统开发(十)-audio移植一

android系统开发(十)-audio移植一

android系统开发(十)-audio移植一android系统开发(十)-audio移植一1,移植基础:(1)内核声音驱动和alsa驱动(2)alsa-lib和alsa-utils库移植这两部分上一节已经介绍过了。

2,android的audio最核心的部分是audioflinger,audioflinger向上处理来自于应用程序的声音相关的所有请求向下通过AudioHardwareInterface访问硬件,android的audio架构如下所示:Applications|Frameworks|JNI|AudioFlinger|AudioHardwareInterface| | |专有audio库| alsa用户库| |/dev/eac /dev/snd/*| |内核eac驱动内核alsa驱动AudioHardwareInterface是audioflinger和硬件驱动之间的桥梁,android默认编译的是generic audio,此时AudioHardwareInterface直接指向了/dev/eac驱动,它通过eac驱动来操作声卡,android audio移植就是要让AudioHardwareInterface直接或者间接指向我们自己定义的声音驱动,一般都采用alsa声音体系,所以我们的目的就是要让AudioHardwareInterface指向alsa用户库。

下面的内容开始移植alsa-audio3,修改vendor/ardent/merlin/BoardConfig.mk文件内容如下:BOARD_USES_GENERIC_AUDIO := falseBOARD_USES_ALSA_AUDIO := trueBUILD_WITH_ALSA_UTILS := true上面配置的目的就是为了让要让AudioHardwareInterface指向alsa用户库4,下面来添加audio库的编译在vendor/ardent/merlin目录下新建一个libaudio目录,修改AndroidBoard.mk文件,添加编译路径如下:LOCAL_PATH := $(call my-dir)L_PATH := $(LOCAL_PATH)include $(L_PATH)/libaudio/Mdroid.mk5,vendor/ardent/merlin/libaudio目录下新建一个Mdroid.mk 文件,内容如下:LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := libaudioLOCAL_SHARED_LIBRARIES := \libcutils \libutils \libmedia \libhardwareLOCAL_SRC_FILES += AudioHardwareMerlin.cpp LOCAL_CFLAGS +=LOCAL_C_INCLUDES +=LOCAL_STATIC_LIBRARIES += libaudiointerface include $(BUILD_SHARED_LIBRARY)6,android audio的实现方法,我们现看看接口部分,上面有说道audioflinger是通过AudioHardwareInterface指向驱动的AudioHardwareInterface类的代码在frameworks/base/libs/audioflinger/AudioHardwareInterface .cpp文件中该文件中的create函数中定义了AudioHardwareInterface 指向驱动的代码如下:AudioHardwareInterface* hw = 0;char value[PROPERTY_VALUE_MAX];#ifdef GENERIC_AUDIOhw = new AudioHardwareGeneric();#else// if running in emulation - use the emulator driverif (property_get("ro.kernel.qemu", value, 0)) {LOGD("Running in emulation - using generic audio driver");hw = new AudioHardwareGeneric();}else {LOGV("Creating Vendor Specific AudioHardware");hw = createAudioHardware();}#endifreturn hw;当系统为generic audio的时候此函数返回的是一个指向AudioHardwareGeneric对象的指针,其实是返回一个指向AudioHardwareInterface对象的指针,因为AudioHardwareGeneric是AudioHardwareInterface的子类,继承关系如下:AudioHardwareInterface->AudioHardwareBase->Au dioHardwareGeneric如果系统不是generic audio,则通过调用createAudioHardware函数来返回一个指向一个指向AudioHardwareInterface对象的指针,所以,简单的将,我们要做的事情就是实现这个函数以及它相关的内容即可。

android驱动的开发流程

android驱动的开发流程

一、android驱动的开发流程1:写LINUX驱动2:写LINUX应用测试程序3:写JNI接口,用来包装第二步写的应用(要用NDK来编译)生成一个.SO文件,相当于CE下的DLL4:写JAVA程序,专门写一个类包含.SO文件,然后在JAVA里调用.SO里的函数。

例子,可以看NDK里面的Sample文件夹,里面有一些例子二、需要安装的环境编译Android的LINUX交叉编译工具编译LINUX驱动的交叉编译工具(4.3.1)编译JNI的工具包:NDK(在LINUX下)编译JAVA程序:esclips+ADT+SDK三、NDK安装1、下载NDK包,下载地址:/android/ndk/android-ndk-r4b-linux-x86.zip2、解压到/home/workspace/目录3、编辑环境变量sudo gedit /etc/profile在末行加入#set NDK envNDKROOT=/home/workspace/android-ndk-r4bexport PATH=$NDKROOT:$PATH更新修改source /etc/profile此时,系统就能识别ndk-build命令了4、编译例子进入sampleshello-jni 目录,编译cd samples/hello-jniaulyp@ubuntu:/home/workspace/android-ndk-r4b/samples/hello-jni$ ndk-build就能看到编译信息了,如果编译成功,会在该目录多生成2个子目录libs,obj目录四、安装JDK到Sun官方网站下载JDK6,选择JDK 6 Update 20下载页面地址: /technetwork/java/javase/downloads/index.html INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET下载完后,双击进行安装安装成功,在cmd下输入java –version,会有JAVA的版本信息出来C:/Users/Aulyp>java -versionjava version "1.6.0_21"Java(TM) SE Runtime Environment (build 1.6.0_21-b07)Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)五、Esclips安装Linux:官方下载:/downloads/到Eclipse官方网站下载Ecplise For Java EE的最新版本我选择下载的是eclipse-java-helios-SR1-linux-gtk.tar解压到指定目录:/optaulyp@ubuntu:/opt$ sudo tar zxvf eclipse-java-helios-SR1-linux-gtk.tar.gz得到eclipse文件夹在桌面上创建启动图标;在桌面(右键单击桌面->创建启动器);然后选择名称:Eclipse命令:eclipse (点Browse 进去选择)图标:/opt/eclipse/icon.xpm(Ubuntu 10.04 上面有个图标,点击之后,选择路径)在桌面得到一个图标,这样可以双击该图标,打开Eclipse。

Android音视频开发(三):使用AudioTrack播放PCM音频

Android音视频开发(三):使用AudioTrack播放PCM音频

Android⾳视频开发(三):使⽤AudioTrack播放PCM⾳频⼀、AudioTrack 基本使⽤AudioTrack 类可以完成Android平台上⾳频数据的输出任务。

AudioTrack有两种数据加载模式(MODE_STREAM和MODE_STATIC),对应的是数据加载模式和⾳频流类型,对应着两种完全不同的使⽤场景。

MODE_STREAM:在这种模式下,通过write⼀次次把⾳频数据写到AudioTrack中。

这和平时通过write系统调⽤往⽂件中写数据类似,但这种⼯作⽅式每次都需要把数据从⽤户提供的Buffer中拷贝到AudioTrack内部的Buffer中,这在⼀定程度上会使引⼊延时。

为解决这⼀问题,AudioTrack就引⼊了第⼆种模式。

MODE_STATIC:这种模式下,在play之前只需要把所有数据通过⼀次write调⽤传递到AudioTrack中的内部缓冲区,后续就不必再传递数据了。

这种模式适⽤于像铃声这种内存占⽤量较⼩,延时要求较⾼的⽂件。

但它也有⼀个缺点,就是⼀次write的数据不能太多,否则系统⽆法分配⾜够的内存来存储全部数据。

1.1 MODE_STATIC模式MODE_STATIC模式输出⾳频的⽅式如下(注意:如果采⽤STATIC模式,须先调⽤write写数据,然后再调⽤play。

):public class AudioTrackPlayerDemoActivity extends Activity implementsOnClickListener {private static final String TAG = "AudioTrackPlayerDemoActivity";private Button button;private byte[] audioData;private AudioTrack audioTrack;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);super.setContentView(yout.main);this.button = (Button) super.findViewById(R.id.play);this.button.setOnClickListener(this);this.button.setEnabled(false);new AsyncTask<Void, Void, Void>() {@Overrideprotected Void doInBackground(Void... params) {try {InputStream in = getResources().openRawResource(R.raw.ding);try {ByteArrayOutputStream out = new ByteArrayOutputStream(264848);for (int b; (b = in.read()) != -1;) {out.write(b);}Log.d(TAG, "Got the data");audioData = out.toByteArray();} finally {in.close();}} catch (IOException e) {Log.wtf(TAG, "Failed to read", e);}return null;}@Overrideprotected void onPostExecute(Void v) {Log.d(TAG, "Creating track...");button.setEnabled(true);Log.d(TAG, "Enabled button");}}.execute();}public void onClick(View view) {this.button.setEnabled(false);this.releaseAudioTrack();this.audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT,audioData.length, AudioTrack.MODE_STATIC);Log.d(TAG, "Writing audio data...");this.audioTrack.write(audioData, 0, audioData.length);Log.d(TAG, "Starting playback");audioTrack.play();Log.d(TAG, "Playing");this.button.setEnabled(true);}private void releaseAudioTrack() {if (this.audioTrack != null) {Log.d(TAG, "Stopping");audioTrack.stop();Log.d(TAG, "Releasing");audioTrack.release();Log.d(TAG, "Nulling");}}public void onPause() {super.onPause();this.releaseAudioTrack();}}1.2 MODE_STREAM模式MODE_STREAM 模式输出⾳频的⽅式如下:byte[] tempBuffer = new byte[bufferSize];int readCount = 0;while (dis.available() > 0) {readCount = dis.read(tempBuffer);if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {continue;}if (readCount != 0 && readCount != -1) {audioTrack.play();audioTrack.write(tempBuffer, 0, readCount);}}⼆、AudioTrack 详解2.1 ⾳频流的类型在AudioTrack构造函数中,会接触到AudioManager.STREAM_MUSIC这个参数。

详解Android开发录音和播放音频的步骤(动态获取权限)

详解Android开发录音和播放音频的步骤(动态获取权限)

详解Android开发录⾳和播放⾳频的步骤(动态获取权限)步骤:配置权限:<manifest xmlns:android="/apk/res/android" package="com.work.mediaplay"><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission><uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>代码步骤:public class MainActivity extends AppCompatActivity implements View.OnClickListener{private Button btn_start, btn_stop;private ListView lv_content;private File sdcardfile = null;private String[] files;private MediaRecorder recorder=null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);initView();getSDCardFile();getFileList();}/*** ①实例化控件*/private void initView() {btn_start = (Button) findViewById(R.id.btn_stat);btn_stop = (Button) findViewById(R.id.btn_stop);lv_content = (ListView) findViewById(R.id.lv_content);//⑤给按钮添加监听事件btn_start.setOnClickListener(this);btn_stop.setOnClickListener(this);//设置起始状态开始按钮可⽤,停⽌按钮不可⽤btn_start.setEnabled(true);btn_stop.setEnabled(false);}/*** ②获取内存卡中⽂件的⽅法*/private void getSDCardFile() {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//内存卡存在sdcardfile=Environment.getExternalStorageDirectory();//获取⽬录⽂件}else {Toast.makeText(this,"未找到内存卡",Toast.LENGTH_SHORT).show();}}/*** ③获取⽂件列表(listView中的数据源)* 返回指定⽂件类型的⽂件名的集合作为数据源*/private void getFileList(){if(sdcardfile!=null){files=sdcardfile.list(new MyFilter());lv_content.setAdapter(new ArrayAdapter<String>(this,yout.simple_list_item_1,files));//⑥给ListView中的元素添加点击播放事件lv_content.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//⑩定义播放⾳频的⽅法play(files[position]);}}}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_stat://⑧申请录制⾳频的动态权限if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.RECORD_AUDIO},1);}else {startRecord();}break;case R.id.btn_stop:stopRcecord();break;}}/*** ④定义⼀个⽂件过滤器MyFilter的内部类,实现FilenameFilter接⼝* 重写⾥边accept⽅法*/class MyFilter implements FilenameFilter{@Overridepublic boolean accept(File pathname,String fileName) {return fileName.endsWith(".amr");}}/*** ⑦给两个按钮定义开始和暂停的⽅法**/private void startRecord(){if(recorder==null){recorder=new MediaRecorder();}recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置⾳频源为⼿机麦克风recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置输出格式3gprecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置⾳频编码为amr格式 //获取内存卡的根⽬录,创建临时⽂件try {File file=File.createTempFile("录⾳_",".amr",sdcardfile);recorder.setOutputFile(file.getAbsolutePath());//设置⽂件输出路径//准备和启动录制⾳频recorder.prepare();recorder.start();} catch (IOException e) {e.printStackTrace();}//启动后交换两个按钮的可⽤状态btn_start.setEnabled(false);btn_stop.setEnabled(true);}private void stopRcecord(){if(recorder!=null){recorder.stop();recorder.release();recorder=null;}btn_start.setEnabled(true);btn_stop.setEnabled(false);//刷新列表数据getFileList();}/*** ⑨重写onRequestPermissionsResult⽅法* 获取动态权限请求的结果,再开启录制⾳频@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if(requestCode==1&&grantResults[0]==PackageManager.PERMISSION_GRANTED){startRecord();}else {Toast.makeText(this,"⽤户拒绝了权限",Toast.LENGTH_SHORT).show();}super.onRequestPermissionsResult(requestCode, permissions, grantResults);}/*** ⑩定义播放⾳频的⽅法*/private void play(String fileName){Intent intent=new Intent(Intent.ACTION_VIEW);//播放⾳频需要uri,从⽂件中获取,⽂件中需要路径Uri uri=Uri.fromFile(new File(sdcardfile.getAbsoluteFile()+File.separator+fileName));//设置播放数据和类型intent.setDataAndType(uri,"audio/*");startActivity(intent);}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

基于Android的智能车载音频系统设计与实现

基于Android的智能车载音频系统设计与实现

基于Android的智能车载音频系统设计与实现随着智能手机和车载设备的普及,人们对于车载音频系统的需求也越来越高。

传统的车载音频系统功能单一,用户体验较差,无法满足现代人对于高品质音乐享受的需求。

因此,基于Android系统的智能车载音频系统应运而生。

本文将介绍基于Android的智能车载音频系统的设计与实现。

一、系统架构设计智能车载音频系统主要由硬件和软件两部分组成。

硬件部分包括主控板、音频输入输出设备、显示屏等;软件部分则是基于Android 系统开发的应用程序。

1. 主控板主控板是整个系统的核心,负责控制各个硬件设备的协同工作。

主控板需要具备较高的计算性能和稳定性,以确保系统运行流畅。

2. 音频输入输出设备音频输入输出设备包括扬声器、麦克风、耳机插口等,负责音频信号的输入和输出。

为了提供更好的音质体验,这些设备需要具备良好的声音处理能力。

3. 显示屏显示屏用于显示系统界面和音乐信息,用户可以通过触摸屏幕进行操作。

显示屏的分辨率和色彩表现力对用户体验有重要影响。

4. Android应用程序Android应用程序是整个系统的灵魂,通过应用程序用户可以选择音乐、调节音量、设置播放模式等。

应用程序需要具备良好的交互性和美观的界面设计。

二、功能设计智能车载音频系统应具备以下功能:1. 音乐播放功能用户可以通过系统选择本地存储或在线音乐进行播放,支持多种格式的音频文件,并提供均衡器等调节功能。

2. 蓝牙连接功能用户可以通过蓝牙连接手机或其他蓝牙设备,实现无线传输音乐和通话功能。

3. 导航功能系统集成导航功能,用户可以通过系统进行导航操作,并实时播报路况信息。

4. 语音助手功能系统内置语音助手,用户可以通过语音指令控制系统进行操作,提升驾驶安全性。

三、实现步骤1. 硬件选型根据系统需求选择适合的主控板、音频输入输出设备和显示屏,并进行硬件连接测试。

2. 系统搭建搭建Android开发环境,编写应用程序代码,实现各项功能,并进行调试优化。

android radio开发 原理

android radio开发 原理

android radio开发原理Android Radio开发原理什么是Android Radio开发?Android Radio开发是指在Android系统下开发无线电应用程序的过程。

通过Android Radio开发,用户可以使用手机、平板电脑等设备收听广播电台、播放音乐等。

Android Radio开发的基本原理Android Radio开发的基本原理主要涉及以下几个方面:1. Android设备中的无线电芯片在Android设备中,一般会集成有一颗无线电芯片,用于接收和发送无线信号。

这颗无线电芯片由硬件厂商提供,并通过驱动程序与Android系统进行交互。

2. 系统层的Radio接口Android系统为无线电芯片提供了一组标准的接口,开发者可以使用这组接口来实现无线电应用程序。

这些接口属于系统层级别,开发者在应用程序中无法直接使用。

3. 应用层的Radio API为了让开发者能够方便地开发无线电应用程序,Android系统还提供了一组应用层的Radio API。

开发者可以使用这组API来访问系统层的Radio接口,并完成各种操作,如搜索和调谐广播电台、播放和控制音频等。

Android Radio开发的流程Android Radio开发的一般流程如下:1.配置权限:在文件中添加必要的权限,如访问无线网络状态、访问网络、读取外部存储等权限。

2.获取RadioManager对象:通过调用系统API获取RadioManager对象,用于管理无线电功能。

3.搜索广播电台:调用RadioManager对象的搜索方法,开始搜索附近的广播电台。

搜索结果以事件的形式返回,开发者可以监听到这些事件并做相应的处理。

4.选择广播电台:根据搜索结果,开发者可以选择一个合适的广播电台进行收听。

5.控制播放:通过RadioManager对象提供的方法,可以控制收听广播电台的状态,如开始播放、暂停、停止等。

Android Radio开发的注意事项在进行Android Radio开发时,需要注意以下几个问题:•权限:为了访问无线电芯片和音频功能,需要在文件中正确配置权限。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

底层开发之Android底层开发之
音频开发初探
袁祖刚
版权
❝华清远见嵌入式培训中心版权所有;
❝未经华清远见明确许可,不能为任何目的以任何形式复制或传播此文档的任何部分;
❝本文档包含的信息如有更改,恕不另行通知;
❝保留所有权利。

内容
❝Android底层开发前景展望
❝Android底层开发之深度定制
音频开发在实际项目中应用举例❝
❝如何进行音频开发
❝硬件架构分析
❝软件架构分析
Android底层开发前景展望
声纹识别对话导航
Android底层开发前景展望体感游戏
Android底层开发前景展望体感游戏
Android底层开发之深度定制
> 改进音频处理
软解码能力的改善,如浮点处理部分用汇编进行优化
软解码能力的改善如浮点处理部分用汇编进行优化
> 触摸屏和传感器(重力,陀螺仪等)的灵敏度优化
mems传感器,把三轴加速计,陀螺仪,磁力计等整合,进行偏差矫正
> 摄像头交叉识别,动作捕捉
快速多次采集的图像,进行差异对比,进行动作判断,核心是算法
> 横竖屏,开机等动画切换流畅,无缝,生动有趣
>横竖屏开机等动画切换流畅
> 电池续航能力
主要是电管如对亮度等进行合的优化利用好省电模式主要是电源管理,如对CPU,wifi, lcd屏亮度等进行合理的优化,利用好省电模式降低频率等。

关键是看芯片手册,设置好寄存器参数。

音频开发在实际项目中应用举例故障排查
插入耳机到手机的2秒内,
speaker的声音切换到耳机,
k的声音切换到耳机
之后又回到的speaker
音频开发在实际项目中应用举例
故障排查简要过程:
> 查看信息了解设备的情况
cd /proc/asound 查看音频设备信息
logcat 查看android应用信息
d demsg 查看开机信息
> 利用第三方工具
如用命令amixer aplay 测试基本功能(如切换headset和speaker的)
> 源码上溯跟踪,逐渐找到问题所在
在HeadsetObserver.java中有查询DEVPATH=/devices/virtual/switch/h2w的状态,在板子上有查看该位置,h2w 的state是有根据耳机插入与否变化的
但是上传h2w 的state到应用成功后,应用没有回应
h2t t到应用成功后应用没有回应
可能是上层没事收到uevent
AudioPolicyManagerALSA.cpp
HeadsetObserver.java
SystemServer.java
S t S j
原因:switch_gpio.c中state状态反了
音频开发在实际项目中应用举例
故障:音频慢半拍,有噪音
推断:
推断可能是采集的帧有误,丢帧或帧时间定位有错误等
排查:
> 检测音频帧正常否
方法:相同的采集后的音频帧,分别和主从片视频帧合并成不同文件(音视频文件是由音频线程,视频线程独立的按先到先得原则,顺序写入的)。

是由音频线程视频线程独立的按先到先得原则顺序写入的)
结论:与主片合并的文件正常。

采集的音频帧无问题。

> 检测是否丢帧
方法对常和异常文件统计,,的个数
方法:对比正常和异常文件。

统计FD,FC,F0
FD 关键帧头中包含时间信息。

F0 音频帧G711协议里根据一帧数据的长度,就可知该帧的播放时间。

FD,F0按时间顺序存储
F0以FD为时间基点
结论: 个数相同,无丢帧
> 找出正常和异常文件的二进制帧数据的差异
尽据改序使头信尽存方法: 单纯化,尽量减少需对比的数据(改程序使生成的头信息尽量一致,不存储FC非关键帧). 用数据说话,对比找出异常所在
结论:异常的文件帧率被设为了20.正常的应是25
如何进行音频开发
> 首先需熟悉音频相关的硬件架构原理
> 熟悉android中音频软件架构
>> 熟练运用第三方提供的工具
进行调试或错误定位
> android代码庞大,需跟踪代码,分析打印信息elipse 断点跟踪
> 如果是驱动开发,还需熟悉linux驱动开发
硬件架构分析
手机
Audio Codec
I2C
访问寄存器ADC mixer main mic 手机话筒
Headset mic
CPU
DAI
DSP 耳机话筒音频输入
DAI 音频数据DAC switch
Speaker
手机外响
Receiver
音频输出耳机听筒ASLA -Advanced Sound Linux Architecture linux2.6中默认的声音子系统,用于替换老的OSS(Open Sound System) ,
ALSA 相对于OSS 提供了更多,也更为复杂的API 接口,因而开发难度相对来讲加大了一些。

为此,
ALSA 专门提供了一个供开发者使用的工具库,以帮助他们更好地使用ALSA 的API
Android4.1以后采用廋身了的tinyalsa (externl/tinyalsa)
Mixer -Mixes several analogtinyalsa
DAI -Digital Audio Interface 就是I2S/PCM/AC97(Codec 与CPU 间音频的通信协议/接口/总线)
SRC -Sample Rate Converter 采样频率转换
I2S -飞利浦制定的音频设备标准SCLK LRCK(帧时钟用于切换左右声道)SDATA PCM Pulse Code Modulation 脉码调制录音所谓录音就是将声音等模拟信号变成符号化的脉冲列再予以记录
PCM -Pulse Code Modulation 脉码调制录音。

所谓PCM 录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。

PCM 信号是由[1]、[0]等符号构成的数字信号
软件架构分析
APP 如SoundRecorder 音频录制应用(自代的)packages/apps/SoundRecorder onClick->
应用AudioManager
packages/apps/SoundRecorder onClick
Recorder.java startRecording-> MediaRecorder frameworks/base/media/libmedia/mediarecorder.cpp frameworks/base/media/java/android/media/AudioManager.java
音频控制接口
AudioFlinger
标准化插件模块
如AudioMixer[混音器]、AudioResampler[重采样,类似SRC]等子模块
ALSA HAL
硬件抽象层
linux驱动要加入到android中,需完成的过渡层
ALSA LIB
音频库
对linux音频驱动访问接口的封装
Linux Audio Driver 音频驱动linux-3.0/sound/soc/sun5i 音频编解码驱动soc(片上系统),表示音频编解码是集成在CPU上的
linux-3.0/sound/core (包含了中间层,ALSA的核心驱动)
Q&A。

相关文档
最新文档