Android RakNet 系列之三 移植Portaudio

简介

PortAudio 是一个跨平台采集和播放音频的开源库,不过尚未支持Android平台,笔者决定让PortAudio支持Android。
Android上,处理音频的库是OpenSL ES,从API 9开始支持的技术,通过这个标准,Android已经完全可以在native层采集和播放音频。
换句话说,PortAudio支持Android,也就是支持OpenSL ES。

详情

Opensl es

penSL ES 是无授权费、跨平台、针对嵌入式系统精心优化的硬件音频加速API。它为嵌入式移动多媒体设备上的本地应用程序开发者提供标准化, 高性能,低响应时间的音频
功能实现方法,并实现软/硬件音频性能的直接跨平台部署,降低执行难度,促进高级音频市场的发展。

实现

Android Opensl es 实现可以直接通过官方的Demo了解。官方的demo提供了音频采集、音频缓存播放、音频url播放、音频文件播放、调整混合音效等等功能。

函数如下:

////////////////////////////////////////音频播放器操作
static int CreateAudioPlayer(SLObjectItf *playerObject, SLEngineItf engine, SLObjectItf mix, int numChannels, double sampleRate, PaSampleFormat sampleFormat );//建立音频
static int OpenAudioPlayer(PaOpenSLESStream* stream,unsigned long framesPerBuffer,PaSampleFormat outputSampleFormat);//打开音频播放器
static int SetAudioPlayerVolum(PaOpenSLESStream* stream,int millibel); //设置音频声量
static int PushAudioPlayerQueue(PaOpenSLESStream* stream);//向音频播放器输入数据
static int StartAudioPlayer(PaOpenSLESStream* stream);//开始音频
static int CloseAudioPlayer(PaOpenSLESStream* stream);//关闭音频
static int SetAudioPlayerMuteSolo(PaOpenSLESStream* stream,int chan,int muteSolo);//操作MuteSolo
///////////////////////////////////////麦克风操作
static int CreateAudioRecorder(SLObjectItf *recorderObject, SLEngineItf engine,int numChannels, double sampleRate, PaSampleFormat sampleFormat);
static int OpenAudioRecorder(PaOpenSLESStream* stream,unsigned long framesPerBuffer,PaSampleFormat inputSampleFormat);//打开麦克风
static int CloseAudioRecorder(PaOpenSLESStream* stream);//关闭麦克风
static int StartAudioRecorder(PaOpenSLESStream* stream);//开始麦克风
static int PopAudioRecorderQueue(PaOpenSLESStream* stream);//向音频播放器取出数据

PortAudio Opensl es实现

实现机制如下--------音频采集缓存、音频播放缓存然后回调实现数据处理便可。

代码按源码pa_hostapi_skeleton.c模版实现便可。

回调如下:

static int c_callback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
	const PaStreamCallbackTimeInfo* outTime, const PaStreamCallbackFlags statusFlags, void *userData) 
音频元素

涉及音频的元素挺多,记录如下:

OpenSLES 中
typedef struct SLDataFormat_PCM_ {
SLuint32 		formatType;
	数据格式定义 SL_DATAFORMAT_PCM
SLuint32 		numChannels;
	声道个数(跟channelMask 一致)
SLuint32 		samplesPerSec;
	每秒采集频率 hz
SLuint32 		bitsPerSample;
	采样比特(采样格式)
SLuint32 		containerSize;
	包含大小
SLuint32 		channelMask;
	通道面具//立体声、左声道、右声道
SLuint32		endianness;
	块的字节顺序 从16--32位
} SLDataFormat_PCM;

GUID-----
SL_IID_VOLUME  音量
SL_IID_PLAY  播放控制
SL_IID_BUFFERQUEUE  缓存接口
SL_IID_EFFECTSEND  音效
SL_IID_MUTESOLO   静音
SL_IID_RECORD  录音接口
SL_IID_PLAYBACKRATE 采样率控制
SL_IID_EQUALIZER 均衡器
SL_IID_PRESETREVERB 预设混响
SL_IID_ENVIRONMENTALREVERB 环境混响
SL_IID_3DLOCATION  3D定位
SL_IID_3DDOPPLER  多普勒效应
SL_IID_BASSBOOST  低音增强
SL_IID_PITCH     升降调
SL_IID_VIRTUALIZER  虚拟化
……

采集频率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使
用4000、8000等。

量化位数(数据位数):采样值或取样值,用来衡量声音波动变化的一个参数,也可以说是声卡的分辨率。
1 字节(也就是8bit) 只能记录 256 个数, 也就是只能将振幅划分成 256 个等级;
2 字节(也就是16bit) 可以细到 65536 个数, 这已是 CD 标准了;
4 字节(也就是32bit) 能把振幅细分到 4294967296 个等级, 实在是没必要了。

比特率:它描述了单位时间长度的媒体内容需要空间。每秒的传输速率。

声道:声音的通道的数目。常有单声道和立体声之分。

帧:单位时间内媒体帧的个数,其长度为样本长度(采样位数)和通道数的乘积。

数据量:采集数据需要的缓冲区的大小
数据量(字节每秒) = 采集频率 * 量化位数 * 声道数 / 8(字节) = 帧 * 字节

周期:音频设备一次处理所需要的帧数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。

交错模式:数字音频信号存储的方式。数据以连续帧的方式存放,即首先记录帧1的左声道样本和右声道样本,再开始帧2的记录...,

非交错模式:首先记录的是一个周期内所有帧的左声道样本,再记录所有右声道样本。

总结

PortAudio支持Android,为Raknet实现语音通话提供了方便。

时间: 2024-10-11 11:26:40

Android RakNet 系列之三 移植Portaudio的相关文章

Android RakNet 系列之四 实现消息、语音、文件传输

简介 RakNet在Win平台上已经实现消息.语音.文件传输了,但在Android平台下尚未实现,笔者决定把源码移植到Android平台下测试. 详情 实现消息 项目自带Chat Example Client和Chat Example Server实现消息,源码简单易懂,此处就不介绍了,直接贴上图片. 测试通过,消息是以Toast方式显示的,图片未捕捉到显示. 实现语音 Win平台下实现语音是通过Portaudio进行的,Portaudio尚未支持Android,要实现语音怎么办? Java层实

android图像处理系列之三--图片色调饱和度、色相、亮度处理

原图: 处理后: 下面贴代码: 一.图片处理层: [java] view plaincopy package com.jacp.tone.view; import java.util.ArrayList; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android

Android RakNet 系列之一 项目介绍

简介 项目对通讯要求越来越高了,为了满足新的需求开始研究RakNet在Android平台的应用,本篇是第一篇,熟悉RakNet的各个功能和插件. RakNet是一个基于UDP网络传输协议的C++网络库,允许程序员在他们自己的程序中实现高效的网络传输服务.通常情况下用于游戏,但也可以用于其它项目. RakNet致力于网络和网络相关服务的游戏引擎.不仅包含了网络通信,也包括游戏级别复制,补丁升级,NAT穿透,和语音聊天.RakNet可以用于任何的应用,且可以与其他任何使用了RakNet的系统通信,不

Android RakNet 系列之二 功能介绍

简介 RakNet 已经成功地在Android平台上测试成功.RakNet的文档很多,实现起来很简单,下面对Raknet功能细节进行详细了解. 详情 1.RakNet使用哪些数据结构? 结构文件 描述 DS_BinarySearchTree.h 二叉搜索树,以及AVL平衡二叉搜索树 DS_BPlusTree.h B+树,用于快速查询,删除,和插入 DS_BytePool.h 返回某个大小门限的数据块,减少内存碎片 DS_ByteQueue.h 用于读写字节的队列 DS_Heap.h 堆数据结构体

Android RakNet 系列之六 源码说明

简介 既然选择Raknet开发,那就深入研究其源码结构,为以后的应用打下基础. 详情 1.文件 文件 描述 _FindFirst 快速查找 AutopatcherPatchContext 自动更新.不停 AutopatcherRepositoryInterface 更新 获取重要的数据接口 Base64Encoder base64编码 BitStream 比特流 流结构 CCRakNetSlidingWindow 观测 CCRakNetUDT   CheckSum 校验 CloudClient

Android RakNet 系列之五 视频通讯 OpenCV4Android

简介 引入OpenCV4Android的目标是在Raknet框架下解决视频通讯的问题,目前在ubuntu下已成功实现,现在把它引用到Android平台下. OpenCV是一个基于开源发行的跨平台计算机视觉库,可以在 Windows, Android, Maemo,FreeBSD, OpenBSD, iOS,Linux 和Mac OS等平台上运行.它轻量级而且高效--由一系列 C 函数和少量 C++ 类构成,同时提供了Python.Ruby.MATLAB等语言的接口,实现了图像处理和计算机视觉方面

Android RakNet 系列之七 线程和服务端统计测试

简介 线程是程序中一个单一的顺序控制流程.进程内一个相对独立的.可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位.在单个程序中同时运行多个线程完成不同的工作,称为多线程. Raknet中重新封装了线程,类为:RakThread. 一个好的服务端体现在最大率使用内存,但并不是每一个程序员都可以把握好内存,一旦服务端出现了问题,我们查什么?日志. 日志就是服务端的黑匣子,统计了服务端的信息. Raknet也提供了服务端连接统计. 线程详情 类定义 class RAK_D

android图像处理系列之三-- 图片色调饱和度、色相、亮度处理

原图: 处理后: 下面贴代码: 一.图片处理层: [java] view plain copy package com.jacp.tone.view; import java.util.ArrayList; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorMatrix; import androi

android 图像处理系列合集

为了便于大家对滤镜算法的学习,以后发布的图像处理滤镜系列帖子会在这里汇总,本人第一次写合集,写得不好的地方大家请见谅,手头上虽然有一些滤镜的算法,但是大多不是android版的,教程里的代码大多是我借鉴其他语言的算法转换而成的,效率上还存在优化的空间,大家可以自行优化.有些网友说代码能看懂,但是里面的某些数值不知道是怎么计算出来的,说实话有些数值我不查资料我也不是很清楚,但是当我需要知道的时候我也会慢慢查阅算法的核心思想,很多参数由此而来.同时也希望大家养成不懂就查的习惯. android 图像