Android之 AudioTrack学习

AudioTrack主要是用来播放声音的,AudioTrack贯穿了JAVA层,JNI层和Native层。

AudioTrack JAVA层:

framework\base\media\java\android\media\AudioTrack.java

以AudioTrack的使用方法举例:pp]

// 得到一个满足最小要求的缓冲区的大小  
int bufsize = AudioTrack.getMinBufferSize(8000,//采样率 = 每秒8K个点  AudioFormat.CHANNEL_CONFIGURATION_STEREO,//双声道  AudioFormat.ENCODING_PCM_16BIT);//采样精度 = 一个采样点16比特 = 2个字节  //创建AudioTrack  
AudioTrack trackplayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,  AudioFormat.CHANNEL_CONFIGURATION_ STEREO,  AudioFormat.ENCODING_PCM_16BIT,  bufsize,  AudioTrack.MODE_STREAM);//  trackplayer.play() ;//开始  trackplayer.write(bytes_pkg, 0, bytes_pkg.length) ;//往track中写数据  //...  trackplayer.stop();//停止播放  trackplayer.release();//释放底层资源  
AudioTrack Native层:

// 得到一个满足最小要求的缓冲区的大小  
int bufsize = AudioTrack.getMinBufferSize(8000,//采样率 = 每秒8K个点  AudioFormat.CHANNEL_CONFIGURATION_STEREO,//双声道  AudioFormat.ENCODING_PCM_16BIT);//采样精度 = 一个采样点16比特 = 2个字节  
getMinBufferSize实际调用了JNI通过Native代码来实现。

framework/base/core/jni/android_media_track.cpp

static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env,  jobject thiz,  
jint sampleRateInHertz, jint nbChannels, jint audioFormat)  
{//注意我们传入的参数是:  
//sampleRateInHertz = 8000  
//nbChannels = 2;  
//audioFormat = AudioFormat.ENCODING_PCM_16BIT  int afSamplingRate;  int afFrameCount;  uint32_t afLatency;  if (AudioSystem::getOutputSamplingRate(&afSamplingRate) != NO_ERROR) {  return -1;  }  if (AudioSystem::getOutputFrameCount(&afFrameCount) != NO_ERROR) {  return -1;  }  if (AudioSystem::getOutputLatency(&afLatency) != NO_ERROR) {  return -1;  }  //音频中最常见的是frame,解释:一个frame就是1个采样点的字节数*声道。  // Ensure that buffer depth covers at least audio hardware latency  uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSamplingRate);  if (minBufCount < 2) minBufCount = 2;  
uint32_t minFrameCount =  (afFrameCount*sampleRateInHertz*minBufCount)/afSamplingRate;  //下面根据最小的framecount计算最小的buffersize     int minBuffSize = minFrameCount  * (audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1)  * nbChannels;  return minBuffSize;  }  

MODE_STREAMMODE_STATIC

STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,然后write到audiotrack。这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。

In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using one of thewrite() methods. These are blocking and return when the data has been transferred from the Java layer to the native layer and queued for playback.

MODE_STREAM模式终使用Write方法,该方法是阻塞的,当数据从Java层到Native层执行播放完毕后才返回。

而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用


AudioTrack的构造函数
public 
AudioTrack (int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)
AudioTrack
的构造函数
中有一个变量用来指定buffer的大小bufferSizeInBytes。 

AudioTrack在Native层会对这个变量的值进行有效性判断。首先,它至少要等于或者大于getMinBufferSize返回的值,然后它必须是frame大小的整数倍


举例说明,MODE_STREAM模式下,在JAVA层构造AudioTrack时,bufferSizeInBytes的大小设定为9600,在Native层调用Write方法拷贝数据至Hardware进行回放,每次拷贝的大小为320.则需要拷贝到30次,声卡才发出声音。即需要将数据填满缓冲区才进行播放。(320*30=9600)




  view plai  copy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术分享 | CodeReview主要Review什么?

源宝导读&#xff1a;Code Review, 意即代码审查,是指一种有意识和系统的召集其他程序员来检查彼此的代码是否有错误的地方. 在敏捷团队中推行CodeReview, 可以帮助团队快速成长.本文将分享在"天际-建模平台"如何推行&实践CodeReview。一、为什么要 Code Review?…

Oracle中的USEREVN()

1.USEREVN() 返回当前用户环境的信息,opt可以是: ENTRYID,SESSIONID,TERMINAL,ISDBA,LABLE,LANGUAGE,CLIENT_INFO,LANG,VSIZE 1.ISDBA 查看当前用户是否是DBA如果是则返回true SQL> select userenv(isdba) from dual; USEREN ------ FALSE 2.SESSION 返回会话标志 SQL>…

你尿尿的时长是不是21秒?2次登上Nature封面的他,靠研究拉尿获得“诺贝尔奖”.........

全世界只有3.14 % 的人关注了爆炸吧知识男人的快乐就是这么朴实无华为什么蚊子不会被雨滴砸死&#xff1f;这个发在知乎上会被质疑患有十年脑血栓的问题&#xff0c;获得了2015年的中国搞笑诺贝尔奖——菠萝科学奖。获奖者结束获奖感言的方式也很搞笑&#xff1a;这个直接在“诺…

SQL优化总结

SQL 的优化主要涉及几个方面&#xff1a; &#xff08;1&#xff09; 相关的统计信息缺失或者不准确 &#xff08;2&#xff09; 索引问题 &#xff08;3&#xff09; SQL 的本身的效率问题&#xff0c;比如使用绑定变量&#xff0c;批量DML 采用bulk等&#xff0c;这…

php curl用法

2019独角兽企业重金招聘Python工程师标准>>> curl 是使用URL语法的传送文件工具&#xff0c;支持FTP、FTPS、HTTP HTPPS SCP SFTP TFTP TELNET DICT FILE和LDAP。curl 支持SSL证书、HTTP POST、HTTP PUT 、FTP 上传&#xff0c;kerberos、基于HTT格式的上传、代理、…

Ubuntu之12.04常用快捷键——记住这些你就是高手啦!

桌面 ALT F1: 聚焦到桌面左侧任务导航栏&#xff0c;可按上下键导航。 ALT F2: 运行命令 ALT F4: 关闭窗口 ALT TAB: 切换程序窗口 ALT 空格: 打开窗口菜单 PRINT: 桌面截图 SUPER: 打开Dash面板&#xff0c;可搜索或浏览项目&#xff0c;默认有个搜索框&#xff0c;按“…

Zabbix RCE with API JSON-RPC

测试脚本: #!/usr/bin/env python # -*- coding: utf-8 -*- # Software Link: http://www.zabbix.com/download.php # Version: 2.2 - 3.0.3import requests import json import sysdef verify(url,hostid):url url /api_jsonrpc.php ### Dont editlogin Admin ##…

类的进阶

apply的两个参数分别是上下文和参数组成的数组。 function.apply(this, [1, 2, 3]); call的两个参数是多个&#xff0c;也就是不用数组包裹参数。 function.call(this, 1, 2, 3); 常常会遇到事件内部没有this的情况&#xff0c;怎么处理呢&#xff1f; 低级方法&#xff1a; $(…

探索 dotnet core 为何在 Windows7 系统需要补丁的原因

在一些 Windows 7 系统上&#xff0c;根据 dotnet 官方文档&#xff0c;需要安装上 KB2533623 补丁&#xff0c;才能运行 dotnet core 或 .NET 5 等应用。尽管非所有的设备都需要安装此&#xff0c;但这也让应用的分发不便&#xff0c;安装包上都需要带上补丁给用户安装。此补丁…

oracle 性能优化--索引总结

索引是建立在表的一列或多个列上的辅助对象&#xff0c;目的是加快访问表中的数据&#xff1b; Oracle存储索引的数据结构是B*树&#xff0c;位图索引也是如此&#xff0c;只不过是叶子节点不同B*数索引&#xff1b; 索引由根节点、分支节点和叶子节点组成&#xff0c;上级索引…

Android之在ubuntu过滤日志以及ps总结

第一步:得到Pid 如果我们不知道TAG的情况下,先得到进程的PID adb shell ps | grep call 会显示出进程关于call的出来 比如得到pid 是1123 第二步:过滤Pid adb logcat | grep 1123 就可以看到过滤的日志了 常见的命令 杀死进程 adb shell kill pid adb shell am force-s…

Centos6.3下DRBD+HeartBeat+NFS配置笔记

--------------闲 扯------------------ 这里首先感谢酒哥的构建高可用的Linux服务器的这本书&#xff0c;看了这本书上并参考里面的配置让自己对DRBDHeartBeatNFS思路清晰了许多。drbd简单来说就是一个网络raid-1,一般有2到多个node节点&#xff0c;各个节点创建的磁盘块会…

解决centos ping不通外网

先确认三件事&#xff1a; 一。ip 二。网关 三。dns 一就不说了&#xff0c;设置好本地ip和掩码就行了&#xff0c;二网关 添加默认网关&#xff0c;命令&#xff1a;route add defaule gw 192.168.1.1 这是 你用route命令查看最下面会有一条默认路由&#xff0c;走192.168.1…

如何在单个测试中同时执行多个断言

前言虽然&#xff0c;推荐做法是每次测试只断言一件事&#xff0c;但是&#xff0c;在实际工作中&#xff0c;我们可能需要对同一个对象同时执行多个断言。例如&#xff0c;微软官方示例项目eShopOnContainers有一个测试用例的实现代码如下&#xff1a;[Fact] public async Tas…

jquery如何获取元素的滚动高度

获取浏览器显示区域&#xff08;可视区域&#xff09;的高度 &#xff1a; $(window).height(); 获取浏览器显示区域&#xff08;可视区域&#xff09;的宽度 &#xff1a; $(window).width(); 获取页面的文档高度 $(document).height(); 获取页面的文档宽度 &a…

TCP/IP模型的各层的作用

第一种总结&#xff1a; TCP/IP模型&#xff1a;以无缝方式实现各种网络之间互连的网络体系结构。 TCP/IP模型共分四层&#xff0c;分别为应用层、传输层、互联网层和主机到网络层。 各层实现特定的功能&#xff0c;提供特定的服务和访问接口&#xff0c;并具有相对的独立性。 …

JAVA解决山脉数组的峰顶索引问题

JAVA解决山脉数组的峰顶索引问题 01 题目 符合下列属性的数组 arr 称为 山峰数组&#xff08;山脉数组&#xff09; &#xff1a; arr.length > 3 存在 i&#xff08;0 < i < arr.length - 1&#xff09;使得&#xff1a;arr[0] < arr[1] < ... arr[i-1] <…

php设计模式之单例(多例),注册器,观察者模式

单例(Singleton)模式和不常见的多例(Multiton)模式控制着应用程序中类的数量。如模式名称&#xff0c;单例只能实例化一次&#xff0c;只有一个对象&#xff0c;多例模式可以多次实例化。 基于Singleton的特性&#xff0c;我们经常用Singleton配置应用程序并定义应用程序中可能…