- 浏览: 196888 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
guoshijie1990:
写的不错
Android Https通信 -
xiaochi_84:
你好,我想问一下。为什么我在java工程里测试没有问题。但是到 ...
Android导出xls文件 -
Visual_chenpeng:
Android Https通信 -
jasonpeak:
求jasonpeak 写道我的为什么按返回键还是不关闭呢?求破 ...
Android关于ProgressDialog按返回键关闭 -
jasonpeak:
我的为什么按返回键还是不关闭呢?
Android关于ProgressDialog按返回键关闭
Android端的语音采集主要是调用AudioRecord,首先说几个参数
private static AudioRecord mRecord; // 音频获取源 private int audioSource = MediaRecorder.AudioSource.MIC; // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025 private static int sampleRateInHz = 8000;// 44100; // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道 private static int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// AudioFormat.CHANNEL_IN_STEREO; // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。 private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 音频大小 private int bufSize;
然后初始化一下AudioRecord,过程如下:
bufSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); mRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufSize);
初始化完毕以后就需要采集音频数据了:
mRecord.startRecording(); short audiodata[] = new short[bufSize]; while (isRecord) { int readsize = 0; while (isRecord == true) { readsize = mRecord.read(audiodata, 0, bufSize); try { for (int i = 0; i < readsize; i++) { //dout.writeShort(audiodata[i]); //数据处理 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } mRecord.stop(); audiodata = null;
接下来是一个语音的播放了,我们这边不放的是采集到的语音流,即PCM无损格式的语音数据,如下:
参数:
private static AudioTrack mTrack; // 音频类型 private int streamType = AudioManager.STREAM_MUSIC; // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025 private int sampleRateInHz = 8000;// 44100; // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道 private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// AudioFormat.CHANNEL_IN_STEREO; // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。 private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 音频大小 private int bufSize; // 音频模式 private int mode = AudioTrack.MODE_STREAM; protected boolean keepRuning = true;
然后初始化播放器:
bufSize = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); mTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufSize, mode);
然后是播放:
DataOutputStream dos = null; mTrack.play(); try { revSocket = server.accept(); dos = new DataOutputStream(new BufferedOutputStream( new FileOutputStream(audioFile))); din = new DataInputStream(revSocket.getInputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } while (keepRuning) { short[] buffer = new short[bufSize / 4]; try { Log.i("状态", "接收数据"); for (int i = 0; din.available() > 0 && i < buffer.length; i++) { buffer[i] = din.readShort(); dos.writeShort(buffer[i]); Log.i("状态", "接收数据," + String.valueOf(i)); } short[] bytes_pkg = buffer.clone(); mTrack.write(bytes_pkg, 0, bytes_pkg.length); } catch (Exception e) { e.printStackTrace(); } } mTrack.stop(); try { dos.close(); din.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
将语音数据保存到文件,并且将裸数据文件保存成可播放的WAV文件
/** * 这里将数据写入文件,但是并不能播放,因为AudioRecord获得的音频是原始的裸音频, * 如果需要播放就必须加入一些格式或者编码的头信息。但是这样的好处就是你可以对音频的 裸数据进行处理,比如你要做一个爱说话的TOM * 猫在这里就进行音频的处理,然后重新封装 所以说这样得到的音频比较容易做一些音频的处理。 */ private void writeDateTOFile() { // new一个byte数组用来存一些字节数据,大小为缓冲区大小 byte[] audiodata = new byte[minBufSize]; FileOutputStream fos = null; int readsize = 0; try { File file = new File(AudioName); if (file.exists()) { file.delete(); } fos = new FileOutputStream(file);// 建立一个可存取字节的文件 } catch (Exception e) { e.printStackTrace(); } while (isRecord == true) { readsize = mRecord.read(audiodata, 0, minBufSize); Log.i("采集大小", String.valueOf(readsize)); if (AudioRecord.ERROR_INVALID_OPERATION != readsize) { try { fos.write(audiodata); } catch (IOException e) { e.printStackTrace(); } } } try { fos.close();// 关闭写入流 } catch (IOException e) { e.printStackTrace(); } } // 这里得到可播放的音频文件 private void copyWaveFile(String inFilename, String outFilename) { FileInputStream in = null; FileOutputStream out = null; long totalAudioLen = 0; long totalDataLen = totalAudioLen + 36; long longSampleRate = sampleRateInHz; int channels = 2; long byteRate = 16 * sampleRateInHz * channels / 8; byte[] data = new byte[minBufSize]; try { in = new FileInputStream(inFilename); out = new FileOutputStream(outFilename); totalAudioLen = in.getChannel().size(); totalDataLen = totalAudioLen + 36; WriteWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); while (in.read(data) != -1) { out.write(data); } in.close(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 这里提供一个头信息。插入这些信息就可以得到可以播放的文件。 为我为啥插入这44个字节,这个还真没深入研究,不过你随便打开一个wav * 音频的文件,可以发现前面的头文件可以说基本一样哦。每种格式的文件都有 自己特有的头文件。 */ private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) throws IOException { byte[] header = new byte[44]; header[0] = 'R'; // RIFF/WAVE header header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte) (totalDataLen & 0xff); header[5] = (byte) ((totalDataLen >> 8) & 0xff); header[6] = (byte) ((totalDataLen >> 16) & 0xff); header[7] = (byte) ((totalDataLen >> 24) & 0xff); header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; header[12] = 'f'; // 'fmt ' chunk header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; // 4 bytes: size of 'fmt ' chunk header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; // format = 1 header[21] = 0; header[22] = (byte) channels; header[23] = 0; header[24] = (byte) (longSampleRate & 0xff); header[25] = (byte) ((longSampleRate >> 8) & 0xff); header[26] = (byte) ((longSampleRate >> 16) & 0xff); header[27] = (byte) ((longSampleRate >> 24) & 0xff); header[28] = (byte) (byteRate & 0xff); header[29] = (byte) ((byteRate >> 8) & 0xff); header[30] = (byte) ((byteRate >> 16) & 0xff); header[31] = (byte) ((byteRate >> 24) & 0xff); header[32] = (byte) (2 * 16 / 8); // block align header[33] = 0; header[34] = 16; // bits per sample header[35] = 0; header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte) (totalAudioLen & 0xff); header[41] = (byte) ((totalAudioLen >> 8) & 0xff); header[42] = (byte) ((totalAudioLen >> 16) & 0xff); header[43] = (byte) ((totalAudioLen >> 24) & 0xff); out.write(header, 0, 44); }播放裸语音数据文件
short[] buffer = new short[bufferSize / 4]; try { // 定义输入流,将音频写入到AudioTrack类中,实现播放 DataInputStream dis = new DataInputStream( new BufferedInputStream(new FileInputStream(audioFile))); // 实例AudioTrack AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, frequence, channelConfig, audioEncoding, bufferSize, AudioTrack.MODE_STREAM); // 开始播放 track.play(); // 由于AudioTrack播放的是流,所以,我们需要一边播放一边读取 while (isPlaying && dis.available() > 0) { int i = 0; while (dis.available() > 0 && i < buffer.length) { buffer[i] = dis.readShort(); i++; } // 然后将数据写入到AudioTrack中 track.write(buffer, 0, buffer.length); } // 播放结束 track.stop(); dis.close(); } catch (Exception e) { // TODO: handle exception }
发表评论
-
Android获取设备信息
2012-11-22 00:10 1329转http://blog.csdn.net/gumanr ... -
Android列表索引实现
2012-07-15 10:47 6623最近做一个项目用到了列表索引,所以在网上找了一下,发现一个博客 ... -
Android开发环境搭建(Windows)
2012-07-03 13:37 757什么都不说来,直接下载附件好了,这个图文的不好发布 -
Linux下Android环境搭建
2012-07-03 13:34 1182--以Ubuntu为例 Linux下Android环境 ... -
Android ListView 滑动背景为黑色的解决办法
2012-06-28 22:08 1008转至:http://blog.163.com/zh ... -
Android蓝牙开发
2012-06-26 15:38 1463今天查了一些资料,然后发现一篇文章挺好,关于蓝牙的,原文网址: ... -
Android自定义对话框
2012-06-22 11:36 2453这时我封装的一个对话框工具类 package com. ... -
Android语音识别
2012-06-18 09:28 2225Android由于有了Google的支持,那么他的语音识别做起 ... -
Android监控
2012-06-08 20:04 1431Android的监控一般都是需要用到Jni的,然后进行NDK编 ... -
Android视频播放
2012-05-24 19:55 1853视频播放优好多种,一种是播放系统可以播放的视频文件,一种是播放 ... -
重写android返回键
2012-05-24 19:23 21865在Activity里面加入下面代码: @Overrid ... -
Android图像处理工具类
2012-04-09 09:37 2477还是最近整理代码、、发现了一个师兄写的图片工具类,感觉还是蛮有 ... -
Android导出xls文件
2012-04-08 15:45 6533整理硬盘的时候找到了这些代码,看了一下,发现还有点用处,所以就 ... -
android的文字跑马灯效果
2012-04-03 21:04 7266今天问了解决文本内容过长的显示问题,而用了一个android自 ... -
Android超级简单的TabView实现
2012-04-03 20:56 7120可能很多人都有想要实现一个导航栏,但是不知道改怎么弄,因为an ... -
ImageView的属性android:scaleType
2012-04-03 20:04 1999ImageView的属性android:scaleType ... -
关于Android程序的全屏显示
2012-04-03 19:53 972对于Android开发来说,全屏和无标题是我们常用的几行代码, ... -
Android文件下载
2012-03-19 16:45 1313嘿嘿,也不知道什么时候写的代码,清理硬盘的时候发现了,而且还能 ... -
Android视图的截图
2012-03-19 16:38 6853在pc上的截图软件很多,但是android上的比较少,所以就自 ... -
Android短信批量删除效果
2012-03-19 16:38 3530前段时间在做一个项目的后期维护时,对方提出了把短信做成可以批量 ...
相关推荐
在Android上实现的一个语音的程序,包括了语音的采集,编码,,解码,然后实现播放的功能,有代码注释
最近做的项目是和语音实时采集并发送,对方实时接收并播放相关,下面记录下实现的核心代码。 很多Android开发者应该知道android有个MediaRecorder对象和MediaPlayer对象,用于录制和播放音频。这个弊端在于他们不能...
设计了一种基于16位定点DSP TMS320VC5410 的语音信号采集系统, 该系统应用了集ADC 和DAC 于一体的SIGMA-DELTA 型单片模拟接口芯片TLC320AD50C,采用FIFO 技术进行缓存, CPLD实现控制逻辑, EZ-USB 外围接口器件...
使用Delphi开发的安卓下中文语音合成,一个可以朗读中文的APP就那么简单。资源内包括开发源码。同时,还演示了动态申请权限、沉浸模式、Toast显示内容。
1. Android Camera2 API 采集预览视频 2. MediaCodec 进行硬编码,编码成h264视频文件 3. AudioRecord采集音频PCM数据,同样利用MediaCodec编码成AAC数据 4. jrtplib库进行视频音频数据发送,本项目修改jrtplib库,...
Android视频采集+RTSP完整代码(可用) Android远程登录含有loading登录效.zip Angle v1.0_2D游戏引擎.ZIP BOOK看遍所有UI控件.7z BrewClock闹钟.zip BTAndroidWebViewSelection(webview选择文字) cellmap v2.0 ...
Android调用手机系统自带录音功能实现语音录制与播放
G.726编码语音传输Android端代码,原理就是Android手机采集语音的PCM编码,然后用NDK在底层编码成G.726码流,通过组播在局域网传播,PC端接收数据,通过G.726动态连接库解码成PCM流,通过SDL库的播放出来,当然通话...
语音控制的智能家居系统,实现使用android端来远程控制LED灯和收集温湿度传感器信息,图表展示温湿度走势 这是一款可以进行语音控制的智能家居系统,包括语音唤醒APP、语音开关灯、语音播报温度/湿度传感器值,此外...
在AndroidO,P版本上验证通过,采集语音数据使用AudioRecord,接收端用Audiotrack实时播放,接收发送一体。此外还做了类似微信聊天功能。可以发送,接收文字,语音消息。目前只是实现了功能,还存在一些bug,后续...
这是一款可以进行语音控制的智能家居系统,包括语音唤醒APP、语音开关灯、语音播报温度/湿度传感器值,此外语音交互后台接入了图灵机器人,除了特殊的控制指令识别外跟苹果的siri相似可以聊天、讲故事等。...
写的一个测试程序,能通过蓝牙麦克风录音并存储。 写的一个测试程序,能通过蓝牙麦克风录音并存储。 写的一个测试程序,能通过蓝牙麦克风录音并存储。 写的一个测试程序,能通过蓝牙麦克风录音并存储。
局域网场景p2p voip demo。该android demo包括采集,实时网络传输microphone语音信号,同时接收播放网络传输的语音信号,实现...该demo能帮助大家快速掌握android平台的语音采集,播放技术;网络传输技术;多线程技术。
针对应用层的功能设计,利用了Android平台编写一个能实时监测的前台界面的手机APP,它能实现显示感知层采集到的信息以及可以通过Wi-Fi技术与stm32通信控制各电机模块的启动,另外还可以通过语音命令去控制实现智能...
签到功能,用户刷脸后,与后台采集的信息对比,并显示最终的结果信息,成功识别则进行语音播报,在后台记录存储记录。 代码放在最后一节课里可下载哦~ jar包分别在两个项目的lib文件夹下,解压后找一下就有了~ 附:...
它支持多种操作系统,包括但不限于Windows、macOS、Linux、Android和iOS。通过Qt,开发者可以使用同一套源代码,在不同平台上编译并生成原生外观与体验的应用程序,极大地提高了开发效率和产品一致性。 图形用户...
Zigbee-Android小米智能家庭套装也是选择的ZigBee协议。简单的说,ZigBee是一种高可靠的无线数传网络,类似ZigBee数传模块和移动网络基站。通讯距离从标准的75m到几百米,几公里,并且支持无限扩展。主要是为工业...
采集重量数据显示在OLED屏幕上,并且语音播报重量,超重时可以语音警告。上传重量信息到机智云,可在APP设置是否开启语音播报 所需硬件 语音合成模块SYN6288 STM32F103C8T6单片机 OLED显示屏 ESP8266 01S 5千克压力...