实现语音数据实时采集 播放

合集下载

VC中实现语音(声音)数据的采集(附源代码)

VC中实现语音(声音)数据的采集(附源代码)

VC中实现语音(声音)数据的采集(附源代码)vc中声音的采集是用api函数来实现的。

一、数字音频基础知识Fourier级数:任何周期的波形可以分解成多个正弦波,这些正弦波的频率都是整数倍。

级数中其他正线波的频率是基础频率的整数倍。

基础频率称为一级谐波。

PCM:pulse code modulation,脉冲编码调制,即对波形按照固定周期频率采样。

为了保证采样后数据质量,采样频率必须是样本声音最高频率的两倍,这就是Nyquist频率。

样本大小:采样后用于存储振幅级的位数,实际就是脉冲编码的阶梯数,位数越大表明精度越高,这一点学过数字逻辑电路的应该清楚。

声音强度:波形振幅的平方。

两个声音强度上的差常以分贝(db)为单位来度量,计算公式如下:20*log(A1/A2)分贝。

A1,A2为两个声音的振幅。

如果采样大小为8位,则采样的动态范围为20*log(256)分贝=48db。

如果样本大小为16位,则采样动态范围为20*log(65536)大约是96分贝,接近了人听觉极限和痛苦极限,是再线音乐的理想范围。

windows同时支持8位和16位的采样大小。

二、相关API函数,结构,消息对于录音设备来说,windows 提供了一组wave***的函数,比较重要的有以下几个:打开录音设备函数MMRESULT waveInOpen(LPHWAVEIN phwi, //输入设备句柄UINT uDeviceID, //输入设备IDLPWAVEFORMATEX pwfx, //录音格式指针DWORD dwCallback, //处理MM_WIM_***消息的回调函数或窗口句柄,线程IDDWORD dwCallbackInstance,DWORD fdwOpen //处理消息方式的符号位);为录音设备准备缓存函数MMRESULT waveInPrepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT bwh );给输入设备增加一个缓存MMRESULT waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh );开始录音MMRESULT waveInStart( HWAVEIN hwi );清除缓存MMRESULT waveInUnprepareHeader( HWAVEIN hwi,LPWAVEHDR pwh, UINT cbwh);停止录音MMRESULT waveInReset( HWAVEIN hwi );关闭录音设备MMRESULT waveInClose( HWAVEIN hwi );Wave_audio数据格式typedef struct {WORD wFormatTag; //数据格式,一般为WAVE_FORMAT_PCM即脉冲编码WORD nChannels; //声道DWORD nSamplesPerSec; //采样频率DWORD nAvgBytesPerSec; //每秒数据量WORD nBlockAlign;WORD wBitsPerSample;//样本大小WORD cbSize;} WAVEFORMATEX;waveform-audio 缓存格式typedef struct {LPSTR lpData; //内存指针DWORD dwBufferLength;//长度DWORD dwBytesRecorded; //已录音的字节长度DWORD dwUser;DWORD dwFlags;DWORD dwLoops; //循环次数struct wavehdr_tag * lpNext;DWORD reserved;} WAVEHDR;相关消息MM_WIM_OPEN:打开设备时消息,在此期间我们可以进行一些初始化工作MM_WIM_DATA:当缓存已满或者停止录音时的消息,处理这个消息可以对缓存进行重新分配,实现不限长度录音MM_WIM_CLOSE:关闭录音设备时的消息。

语音合成软件的数据集采集和处理技巧(Ⅲ)

语音合成软件的数据集采集和处理技巧(Ⅲ)

语音合成软件的数据集采集和处理技巧一、数据集的重要性语音合成软件的数据集是其性能的基础。

一个好的数据集可以帮助语音合成软件更准确地模拟人类的语音,使合成的语音更加自然和流畅。

因此,数据集的采集和处理是语音合成软件开发中至关重要的步骤。

二、数据集的采集1. 采集多样化的语音样本语音合成软件的数据集需要包含多种语音特征,因此在采集数据时需要尽可能涵盖各种不同年龄、性别、口音、方言等特征的语音样本。

这样可以使得合成的语音更具通用性和适用性。

2. 保持语音样本的质量在采集语音样本时,需要注意保持语音的清晰度和准确性。

避免嘈杂的环境和杂音的干扰,保证语音的纯净度。

此外,还需要注意采集的语音样本的标注工作,确保每个语音样本都有准确的文本标注。

三、数据集的处理1. 数据清洗在采集到大量的语音样本后,需要对数据进行清洗,去除噪音和杂音,确保语音的纯净度。

此外,还需要对采集到的语音进行切分,提取出单个的语音片段,为后续的处理工作做好准备。

2. 特征提取在语音合成软件中,需要对语音样本进行特征提取,将其转化为数字形式的特征向量。

这一步是非常重要的,它直接影响着后续的模型训练和语音合成的效果。

因此,在特征提取时需要注意选择合适的特征提取算法和参数,并对提取出的特征进行分析和优化。

3. 标注在处理数据集时,还需要对语音样本进行文本标注。

这一步是为了训练语音合成模型时提供正确的文本标签,使模型能够准确地学习语音和文本之间的对应关系。

因此,在标注时需要保证标注的准确性和一致性,避免出现错误的标注导致模型训练的失败。

四、数据集的优化1. 数据增强在处理数据集时,可以通过数据增强的方式来扩充数据集的规模和多样性。

数据增强可以通过添加噪声、变速、变调等方式对语音样本进行变换,从而增加数据集的丰富性和多样性,提高模型的泛化能力。

2. 数据平衡在采集和处理数据集时,需要注意保持数据的平衡性。

即使在不同年龄、性别、口音等方面都能充分覆盖,避免数据集中出现过多的某一类别,导致模型在学习和预测时出现偏差。

凌阳单片机 5.3 语音自动播放

凌阳单片机  5.3 语音自动播放

Sunplus SPCE061A 微控制器语音播放(自动播放)语音播放一、单片机实现语音播放的原理二、语音播放程序示例三、创建一个语音播放程序四、小结和注意事项五、疑难解答一、单片机实现语音播放的原理语音录制存储流程 语音采样在定时中断的控制下,以一定的速率(8KHz )进行AD 转换压缩编码将采集到的数据以某种算法压缩编码存储将编码后的数据保存到存储介质中语音资源压缩编码存储数据队列定时中断AD采样语音语音播放流程数据提取语音数据送入解压缩队列数据解码解压缩数据并送入输出队列转换为模拟信号在定时中断的控制下进行数模转换转换为声音模拟信号经滤波、放大,通过扬声器输出解压缩队列语音资源解压缩取数据输出队列定时中断DAC输出语音用SPCE061A播放语音开始播放播放初始化语音资源播放完毕?开始解码,填入播放队列停止播放定时中断从播放队列取出数据送DAC输出返回YN播放队列设置中断播放循环中断服务自动播放与手动播放 自动播放解压缩队列语音资源解压缩取数据输出队列定时中断DAC输出语音SACM_Decoder(); SACM_A2000_FillQueue();SP_GetResource();手动播放二、语音播放程序示例语音播放程序示例// 中断服务程序 //用户接口函数在hardware.asm 中定义的用户API ,用户可以根据需要修改 F_SP_SACM_A2000_In it_ F_SP_InitQueue F_SP_ReadQueueF_SP_WriteQueueF_SP_RampUpDAC1…… ……语音函数库用户API语音播放程序三、创建一个语音播放程序创建一个语音播放程序 第1 步:新建工程创建一个语音播放程序 第2 步:复制语音播放需要的文件到工程所在的文件夹语音播放支持文件,在“IDE安装目录->Example -> 61_Exa -> Record”文件夹下可以找到sacmv26e.libhardware.inchardware.asmA2000格式的语音资源,在“IDE安装目录-> Example -> VoiceExa-> ex1_A2000->Voice”文件夹下可以找到这里选择了d1.24k和ww.24k两个文件在Project 菜单项,选择Add to Project -> Files 找到工程所在的文件夹,选择hardware.asm 、hardware.inc 两个文件(按住Ctrl 键点选),确定。

poc协议标准

poc协议标准

POC协议标准一、POC通信协议POC(Push to Talk over Cellular)是一种基于移动通信网络的通信协议,主要用于实现一对一或一对多的实时通话。

它通过使用无线电资源进行语音传输,实现快速、实时的语音通信。

二、POC媒体形式POC的媒体形式主要包括语音和视频。

通过POC协议,用户可以发送和接收语音或视频消息,实现实时、实地的通信。

三、POC应用领域POC协议广泛应用于各种领域,如公共安全、应急救援、商业通信等。

在这些领域中,POC协议可以提供快速、实时的通信服务,提高工作效率和响应速度。

四、POC安全性POC协议采用256位加密算法,保障通信内容机密性,确保数据在传输过程中的安全性。

同时,POC协议还支持身份验证和授权机制,确保只有授权用户才能访问和使用服务。

五、POC群组建立POC协议支持建立群组功能,用户可以创建和管理自己的群组,实现多人同时通话。

群组成员可以通过群组ID或群组名称进行加入和退出操作。

六、POC发言权控制POC协议支持发言权控制功能,管理员可以设置发言权规则,控制群组成员的发言权限。

例如,管理员可以设置某些成员只能接收消息而不能发送消息,或者设置某些成员拥有优先发言权等。

七、POC交互业务POC协议支持多种交互业务,如语音留言、文件传输、实时定位等。

用户可以通过POC协议进行多种交互操作,提高工作效率和用户体验。

八、POC体系结构POC协议的体系结构包括客户端、服务器端和网络传输层三个部分。

客户端负责与用户交互,实现语音和视频的采集和播放;服务器端负责管理群组和用户信息,实现语音和视频的传输和控制;网络传输层负责数据的传输和转发。

利用C实现实时音视频数据传输系统设计与开发

利用C实现实时音视频数据传输系统设计与开发

利用C实现实时音视频数据传输系统设计与开发一、引言随着互联网的快速发展,音视频通信已经成为人们日常生活中不可或缺的一部分。

实时音视频数据传输系统在视频会议、在线教育、远程医疗等领域发挥着越来越重要的作用。

本文将介绍如何利用C语言实现一个高效稳定的实时音视频数据传输系统,涵盖系统设计与开发的方方面面。

二、系统架构设计在设计实时音视频数据传输系统时,首先需要考虑系统的整体架构。

一个典型的音视频传输系统包括采集模块、编码模块、传输模块、解码模块和渲染模块。

采集模块负责从摄像头和麦克风中获取音视频数据,编码模块将原始数据进行压缩编码,传输模块通过网络传输编码后的数据,解码模块将接收到的数据进行解码,最后渲染模块将解码后的数据显示在屏幕上。

三、采集模块设计与实现采集模块是实时音视频传输系统中至关重要的一环。

在C语言中,可以利用开源库如OpenCV来实现音视频数据的采集。

通过OpenCV提供的接口,可以轻松地从摄像头和麦克风中获取音视频数据,并进行预处理操作。

四、编码模块设计与实现编码模块负责对采集到的音视频数据进行压缩编码,以减小数据量并保证传输效率。

在C语言中,可以使用FFmpeg等开源编解码库来实现音视频数据的编码工作。

FFmpeg提供了丰富的API接口,可以方便地对音视频数据进行编解码操作。

五、传输模块设计与实现传输模块是实时音视频传输系统中连接采集端和播放端的桥梁。

在C语言中,可以利用Socket编程来实现音视频数据的传输。

通过Socket套接字接口,可以建立客户端和服务器之间稳定可靠的连接,并实现音视频数据的实时传输。

六、解码模块设计与实现解码模块负责将接收到的音视频数据进行解码操作,以便后续渲染显示。

在C语言中,可以使用FFmpeg等开源库来实现音视频数据的解码工作。

通过FFmpeg提供的API接口,可以轻松地对接收到的音视频数据进行解码操作。

七、渲染模块设计与实现渲染模块是实时音视频传输系统中最终将音视频数据显示在屏幕上的环节。

语音识别中的实时语音识别技术

语音识别中的实时语音识别技术

实时语音识别技术是语音识别领域的一个重要分支,它在许多领域都有着广泛的应用,如智能语音助手、智能车载系统、远程医疗等。

实时语音识别技术需要处理大量的语音数据,并实时地将其转换为文本,以满足实际应用的需求。

实时语音识别技术的主要原理是利用声学模型和语言模型对输入的语音信号进行特征提取和文本预测。

声学模型通常采用隐马尔科夫模型(HMM)或深度学习模型(如CNN、RNN、LSTM等)来提取语音信号的特征,而语言模型则用于预测下一个可能出现的单词或短语。

实时语音识别系统通常包括前端和后端两个部分,前端负责采集和处理语音信号,后端则负责将声学特征转换为文本。

实时语音识别技术的实现需要解决许多挑战性问题,如噪声干扰、口音和语速变化、词汇多样性等。

为了提高识别的准确性和鲁棒性,需要不断优化算法和模型,引入新的技术手段和数据集。

目前,深度学习技术的发展为实时语音识别提供了强大的支持,尤其是循环神经网络(RNN)和长短时记忆网络(LSTM)的应用,使得模型能够更好地捕捉语音信号的时序特征,提高了识别的准确性和实时性。

实时语音识别的关键技术之一是去噪技术。

在实际应用中,语音信号往往受到各种噪声的干扰,如环境噪声、手机信号干扰等。

去噪技术可以通过添加人工白噪声、特征降维、基于模型的噪声建模等方法,有效地消除噪声对语音识别的干扰,提高识别的准确性和稳定性。

此外,自动增益控制技术也可以通过调整输入信号的音量,确保语音信号的动态范围适合于后续的声学模型处理。

除了上述关键技术外,实时语音识别还需要考虑许多其他因素,如系统性能、资源消耗、隐私保护等。

为了提高系统的性能,可以采用多麦克风阵列、信号处理等技术来提高信噪比和语音分离效果。

在资源消耗方面,需要优化算法和模型,降低计算复杂度和内存占用。

在隐私保护方面,需要采取加密、匿名化等技术来保护用户的隐私信息。

总之,实时语音识别技术在许多领域都有着广泛的应用前景。

为了提高识别的准确性和鲁棒性,需要不断优化算法和模型,引入新的技术手段和数据集。

基于DSP的语音采集和回放系统的实现

基于DSP的语音采集和回放系统的实现

基于DSP的语音采集和回放系统的实现王丽琴;史航【摘要】基于DSP的语音采集和回放系统,主要采用C语言进行软件编写,并在CCS环境下进行功能仿真,播放变换后语音,并给出了具体的实现方法和步骤。

实例表明,DSP满足双声道的语音信号处理的需要,具有广泛的应用价值。

【期刊名称】《时代农机》【年(卷),期】2015(000)010【总页数】2页(P57-58)【关键词】语音信号处理;DSP;语音采集和回放【作者】王丽琴;史航【作者单位】[1]常州信息职业技术学院,江苏常州213000;[2]江苏理工学院,江苏常州213000;【正文语种】中文【中图分类】TP391.42语音信号广泛存在于日常生活和工业生产过程中,具有信号频谱较全、采样速度较低、随机性强、应用场合多、实时性和稳定性等特点。

语音信号处理是一门重要的学科,在数字话音通信、声控打字机、自动语音翻译、多媒体信息处理等许多方面有重要的应用,如语音电子信箱、语音浏览、语音导航等。

随着数字信号处理算法在DSP中的实现,很多以前很难实现的语音信号处理算法都可以在DSP中实现。

1 数字信号处理器DSPDSP是数字信号处理器(Digital Signal Processing)或集成的单片数字信号处理器(Digital Signal Processor)的缩写。

DSP技术是利用计算机或专用处理设备,以数值计算的方法对信号进行采集、变换、综合、估值与识别等加工以达到提取信息和便于应用目的的一种技术。

DSP技术包括数字信号处理的理论和数字信号处理的实现。

DSP是数字信号处理系统的核心,一般由CPU、片内外设和存储空间构成。

TMS320VC5509 DSP芯片是目前集成度较高的通用型DSP,能提供完备的系统解决方案,具有96K×16位的单口 SRAM、32K×16位的双口 SRAM、32K×16位的ROM和6通道的DMA(直接存储器存储)。

游戏实时音视频解决方案

游戏实时音视频解决方案

游戏实时音视频解决方案一、引言随着游戏行业的迅速发展,实时音视频技术在游戏中的应用变得越来越重要。

游戏实时音视频解决方案是一种为游戏开辟者提供高质量、低延迟的音视频通信服务的技术方案。

本文将详细介绍游戏实时音视频解决方案的基本原理、技术要点以及应用场景。

二、基本原理游戏实时音视频解决方案基于实时音视频传输协议,通过客户端和服务器之间的通信,实现游戏玩家之间的实时音视频通信。

基本原理如下:1. 客户端采集音视频数据:游戏客户端通过摄像头和麦克风采集玩家的音视频数据。

2. 数据编码:采集到的音视频数据需要进行编码,将其转换为数字信号。

3. 数据传输:编码后的音视频数据通过网络传输到服务器。

4. 数据解码:服务器接收到音视频数据后,进行解码操作,将其转换为可播放的音视频信号。

5. 数据播放:解码后的音视频信号通过游戏客户端进行播放,玩家可以实时观看和听到其他玩家的音视频。

三、技术要点为了保证游戏实时音视频解决方案的质量和稳定性,以下是几个关键的技术要点:1. 低延迟:游戏实时音视频通信需要保证低延迟,以提供流畅的游戏体验。

为了实现低延迟,可以采用传输控制协议(TCP)或者用户数据报协议(UDP)进行数据传输。

2. 抗丢包:在网络传输过程中,由于网络拥堵或者其他原因,可能会导致数据包丢失。

为了解决这个问题,可以采用前向纠错(Forward Error Correction,FEC)技术或者重传机制,保证音视频数据的完整性。

3. 自适应码率:不同网络环境下,带宽和网络延迟都会有所不同。

为了适应不同网络环境,游戏实时音视频解决方案需要具备自适应码率的能力,根据网络状况动态调整音视频数据的传输速率。

4. 声音增强:游戏中的声音效果对于玩家的体验非常重要。

为了提供更好的声音效果,可以采用降噪、回声消除等技术,提高音频的清晰度和质量。

四、应用场景游戏实时音视频解决方案可以应用于多种游戏场景,以下是几个常见的应用场景:1. 多人语音聊天:游戏玩家可以通过实时音频通信功能,进行多人语音聊天,增强游戏社交体验。

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

实现语音数据实时采集/播放最近做的项目是和语音实时采集并发送,对方实时接收并播放相关,下面记录下实现的核心代码。

很多Android开发者应该知道android有个MediaRecorder对象和MediaPlayer对象,用于录制和播放音频。

这个弊端在于他们不能实时采集并发送出去,所以,我们只能使用AudioRecord和AudioTrack来实现。

记得申明权限:<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permission android:name="android.permission.RECORD_AUDIO" >一、AudioRecord实现核心代码介绍如下:1、先申明相关录制配置参数private AudioRecord audioRecord;// 录音对象private int frequence = 8000;// 采样率8000private int channelInConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// 定义采样通道private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;// 定义音频编码(16位)private byte[] buffer = null;// 录制的缓冲数组2、在开始录制前,我们需要初始化AudioRecord类。

// 根据定义好的几个配置,来获取合适的缓冲大小// int bufferSize = 800;int bufferSize = AudioRecord.getMinBufferSize(frequence,channelInConfig, audioEncoding);// 实例化AudioRecordaudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequence, channelInConfig, audioEncoding, bufferSize);// 定义缓冲数组buffer = new byte[bufferSize];3、准备开始录制,使用循环不断读取数据。

audioRecord.startRecording();// 开始录制isRecording = true;// 设置录制标记为true// 开始录制while (isRecording) {// 录制的内容放置到了buffer中,result代表存储长度int result = audioRecord.read(buffer, 0, buffer.length);/*.....result为buffer中录制数据的长度(貌似基本上都是640)。

剩下就是处理buffer了,是发送出去还是直接播放,这个随便你。

*/}//录制循环结束后,记得关闭录制!!if (audioRecord != null) {audioRecord.stop();}1、声明播放相关配置。

private AudioTrack track = null;// 录音文件播放对象private int frequence = 8000;// 采样率8000private int channelInConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// 定义采样通道private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;// 定义音频编码(16位)private int bufferSize = -1;// 播放缓冲大小2、初始化AudioTrack对象(初始化一次,该对象可重复使用)// 获取缓冲大小bufferSize = AudioTrack.getMinBufferSize(frequence, channelInConfig,audioEncoding);// 实例AudioTracktrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequence,channelInConfig, audioEncoding, bufferSize,AudioTrack.MODE_STREAM);3、使用AudioTrack播放语音数据。

//将语音数据写入即可。

track.write(dataArray, buffer, len);问题一:由于目前的项目是实时采集,实时发送,所以需要考虑到包的大小,经测试,我们使用160个byte作为一个包传递可以做到比较良好的播放效果(也就是将一份buffer拆分成四个发送)。

处理代码如下:// 将数据通过监听接口回调出去if (audioRecordingCallback != null) {int offset = result % MAX_DATA_LENGTH > 0 ? 1 : 0;//将一个buffer拆分成几份小数据包MAX_DATA_LENGTH 为包的最大byte数for (int i = 0; i < result / MAX_DATA_LENGTH + offset; i++) {int length = MAX_DATA_LENGTH;if ((i + 1) * MAX_DATA_LENGTH > result) {length = result - i * MAX_DATA_LENGTH;}//写到回调接口audioRecordingCallback.onRecording(buffer, i* MAX_DATA_LENGTH, length);}}问题二:有时候传输的过来播放声音会一卡一卡的,为了解决这样的问题,暂时使用了语音双缓冲机制来解决,问题优化很明显。

代码和示意图如下:双缓冲示意图【有朋友说要源码,那我就贴下】/*** 实时音频录制处理类<br/>* 记得申明系统权限:MODIFY_AUDIO_SETTINGS、RECORD_AUDIO<br/>* 使用实例代码:<br/>** <pre>* audioRecoderHandler = new AudioRecoderHandler(this);* audioRecoderHandler.startRecord(new AudioRecordingCallback() {* &#064;Override* public void onStopRecord(String savedPath) {** }** &#064;Override* public void onRecording(byte[] data, int startIndex, int length) {* // TODO 录制监听。

处理data即可。

立即播放or发送出去,随你。

* }* });* </pre>** @author 李长军**/@SuppressWarnings("deprecation")public class AudioRecoderHandler {private Context context = null;/*** 录音数据单次回调数组最大为多少*/private static int MAX_DATA_LENGTH = 160;private AudioRecord audioRecord;// 录音对象private boolean isRecording = false;// 标记是否正在录音中private int frequence = 8000;// 采样率8000private int channelInConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// 定义采样通道(过时,但是使用其他的又不行private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;// 定义音频编码(16位)private byte[] buffer = null;// 录制的缓冲数组private File lastCacheFile = null;// 记录上次录制的文件名private CommonSharedpreferenceHelper commonSharedpreferenceHelper;private boolean shouldSaveAudio = false;// 标记是否保存录音历史记录public AudioRecoderHandler(Context context) {if (context == null) {throw new RuntimeException("Context could not be null!");}this.context = context;commonSharedpreferenceHelper = CommonSharedpreferenceHelper.getInstance(context);}/*** 设置处理对象是否保存录音历史记录(如果设置为false表示不保存)** @param shouldSaveAudio* true表示保存(默认),false不保存,onStopRecord回调将会返回null*/public void setShouldSaveAudio(boolean shouldSaveAudio) {this.shouldSaveAudio = shouldSaveAudio;}/*** 开始录制音频** @param callBackListener* 录制过程中的回调函数*/public void startRecord(AudioRecordingCallback audioRecordingCallback) {RecordTask task = new RecordTask(audioRecordingCallback);task.execute();// 开始执行}/*** 停止录制*/public void stoppRecord() {isRecording = false;}/*** 删除上次录制的文件(一般是用户取消发送导致删除上次录制的内容)** @return true表示删除成功,false表示删除失败,一般是没有上次录制的文件,或者文件已经被删除了*/public boolean deleteLastRecordFile() {if (lastCacheFile != null && lastCacheFile.exists()) {success = lastCacheFile.delete();}return success;}/*** 获取音频文件的缓存地址(获取的地址都是可以直接存储的,也就是文件夹已建立好),需要注意的是,缓存地址和用户的ID有关** @return 音频文件的缓存地址路径,如果获取失败,返回null*/private String getOutputDir() {String path = null;File cacheFile = null;if (context != null) {cacheFile = context.getExternalFilesDir(android.os.Environment.DIRECTORY_MUSIC);if (cacheFile == null) {Toast.makeText(context, "您的SD卡不可用", Toast.LENGTH_SHORT).show();} else {path = cacheFile.getAbsolutePath() + "/"+ commonSharedpreferenceHelper.getCurrentUserID()+ "/record";// 创建文件夹new File(path).mkdirs();}}return path;}/*** 录制音频的任务类** @author 李长军**/private class RecordTask extends AsyncTask<String, Integer, String> {private AudioRecordingCallback audioRecordingCallback = null;public RecordTask(AudioRecordingCallback audioRecordingCallback) {this.audioRecordingCallback = oRecordingCallback;}protected void onPreExecute() {// 根据定义好的几个配置,来获取合适的缓冲大小// int bufferSize = 800;int bufferSize = AudioRecord.getMinBufferSize(frequence,channelInConfig, audioEncoding);// 实例化AudioRecordaudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequence, channelInConfig, audioEncoding, bufferSize);// 定义缓冲数组buffer = new byte[bufferSize];audioRecord.startRecording();// 开始录制isRecording = true;// 设置录制标记为true}@Overrideprotected void onPostExecute(String result) {audioRecord = null;if (result == null) {lastCacheFile = null;} else {lastCacheFile = new File(result);}if (audioRecordingCallback != null) {audioRecordingCallback.onStopRecord(result);}}@Overrideprotected String doInBackground(String... params) {String cacheDir = getOutputDir();String tempFileName = null;File cacheFile = null;// 输出的文件流DataOutputStream dataOutputStream = null;// 如果设置了要保存历史录音文件,则创建临时文件if (shouldSaveAudio && cacheDir != null) {tempFileName = cacheDir + "/" + System.currentTimeMillis();cacheFile = new File(pFileName);try {dataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(cacheFile)));} catch (FileNotFoundException e) {e.printStackTrace();}// 开始录制while (isRecording) {// 录制的内容放置到了buffer中,result代表存储长度int result = audioRecord.read(buffer, 0, buffer.length);// 如果设置需要保存录音文件if (shouldSaveAudio && dataOutputStream != null) {for (int i = 0; i < result; i++) {try {// 将录制到的内容放置到文件中dataOutputStream.write(buffer[i]);} catch (IOException e) {e.printStackTrace();}}}// 将数据回调出去if (audioRecordingCallback != null) {int offset = result % MAX_DATA_LENGTH > 0 ? 1 : 0;for (int i = 0; i < result / MAX_DATA_LENGTH + offset; i++) {int length = MAX_DATA_LENGTH;if ((i + 1) * MAX_DATA_LENGTH > result) {length = result - i * MAX_DATA_LENGTH;}audioRecordingCallback.onRecording(buffer, i* MAX_DATA_LENGTH, length);}}}if (audioRecord != null) {audioRecord.stop();}if (dataOutputStream != null) {try {dataOutputStream.close();} catch (IOException e) {e.printStackTrace();}}return tempFileName;}}* 监听录制过程,用于实时获取录音数据** @author 李长军**/public static interface AudioRecordingCallback {/*** 录音数据获取回调** @param data* 数据数组对象* @param startIndex* 数据其开始* @param length* 数据的结尾*/public void onRecording(byte[] data, int startIndex, int length);/*** 录音结束后的回调** @param savedPath* 录音文件存储的路径*/public void onStopRecord(String savedPath);}/*** 释放资源*/public void release() {if (audioRecord != null) {audioRecord.release();audioRecord = null;}}【声音播放的源码】/*** 实时音频播放处理类<br/>* 使用示例代码如下:<br/>* audioPlayerHandler = new AudioPlayerHandler();* audioPlayerHandler.prepare();// 播放前需要prepare。

相关文档
最新文档