Android 实时录音和回放,边录音边播放 (KTV回音效果)

1、AndioRecord类介绍

  AndioRecord类的主要功能是让各种JAVA应用能够管理音频资源,以便它们通过此类能够录制平台的声音输入硬件所收集的声音。此功能的实现就是通过”pulling同步”(reading读取)AudioRecord对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过后面三个类方法中的一个去及时地获取AudioRecord对象的录音数据. AudioRecord类提供的三个获取声音数据的方法分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int)。 无论选择使用那一个方法都必须事先设定方便用户的声音数据的存储格式。然后再使用AudioTrack实时回放声音即可。

  下面是使用AudioRecord的过程中,可能会遇到的返回值,对于定位问题的原因很有用,解析很简单,我就不翻译了。

2、AudioRecord初始化

//Edited by mythou//http://www.cnblogs.com/mythou/
// AudioRecord 得到录制最小缓冲区的大小
m_in_buf_size = AudioRecord.getMinBufferSize(8000,
                AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
// 实例化播放音频对象
m_in_rec = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,
                AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT, m_in_buf_size);

  AudioRecord的初始化参数比较多,需要注意设置。这几个参数都是标准的声音采集的参数,下面我针对这几个参数做个介绍,实际使用的时候,你可以根据你的情况设置。

AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

AudioRecord构造参数的参数解析,可以根据实际情况调整:

audioSource 音频源:指的是从哪里采集音频。这里我们是从麦克风采集音频,所以此参数的值为MIC。可以参考MediaRecorder.AudioSource类,查看其他音频源。
sampleRateInHz 采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使用4000、8000等低采样率。
channelConfig 声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
audioFormat 编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。当然采样大小越大,那么信息量越多,音质也越高,现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit 足够了。
bufferSizeInBytes 采集数据需要的缓冲区的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。

  

  上面是针对AudioRecord的初始化参数做了详细阐述,这个对于使用AudioRecord十分重要,也影响了录音和后期播放的效果,所以在你使用AudioRecord进行录音前,请仔细熟悉上面参数。

3、录音

//Edited by mythou
//http://www.cnblogs.com/mythou/
     //    录音线程
    class recordSound implements Runnable
    {
        @Override
        public void run()
        {
            Log.d(TAG, "........recordSound run()......");
            byte[] bytes_pkg;
            // 开始录音
            m_in_rec.startRecording();

            while (flag)
            {
                m_in_rec.read(m_in_bytes, 0, m_in_buf_size);
                bytes_pkg = m_in_bytes.clone();
                Log.i(TAG, "........recordSound bytes_pkg==" + bytes_pkg.length);
                if (m_in_q.size() >= 2)
                {
                    m_in_q.removeFirst();
                }
                m_in_q.add(bytes_pkg);
            }
        }

    }

  这里录音使用的是read()方法来读取录音的数据,并且把录音放到一个独立线程执行,读取到的录音数据,放入到队列里面,供播放线程使用。下面我们看看播放线程:

//Edited by mythou
//http://www.cnblogs.com/mythou/
     //播放线程
    class playRecord implements Runnable
    {
        @Override
        public void run()
        {
            Log.d(TAG, "........playRecord run()......");
            byte[] bytes_pkg = null;
            // 开始播放
            m_out_trk.play();

            while (flag)
            {
                try
                {
                    m_out_bytes = m_in_q.getFirst();
                    bytes_pkg = m_out_bytes.clone();
                    m_out_trk.write(bytes_pkg, 0, bytes_pkg.length);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

  播放录音和录音过程大致一样,都是一个独立线程,这里需要注意的是,录音和播放都是开了独立的线程,而不是放在UI线程执行,至于原因不用我多说,大家应该都明白。

 5、解决异常

  下面把我调试过程中遇到的一个问题分享一下:

08-06 20:08:25.032: E/AndroidRuntime(32389): FATAL EXCEPTION: Thread-2063
08-06 20:08:25.032: E/AndroidRuntime(32389): java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
08-06 20:08:25.032: E/AndroidRuntime(32389):     at android.media.AudioRecord.startRecording(AudioRecord.java:540)
08-06 20:08:25.032: E/AndroidRuntime(32389):     at com.apical.AuxIn.AudioNowRecord$recordSound.run(AudioNowRecord.java:131)
08-06 20:08:25.032: E/AndroidRuntime(32389):     at java.lang.Thread.run(Thread.java:856)

  出现上面问题的原因是录音的硬件资源被申请了,但是没有释放,然后你再次申请资源,导致 初始化失败。这里需要注意的是不仅仅需要调用Release()方法。还需要把AudioRecord对象置为null,否则还是释放失败。下面是 Android 开发网上面的一个对于AudioRecord的释放说明。

Releases the native AudioRecord resources. The object can no longer be used and the reference should be set to null after a call to release()。

6、结语

  上面就是一边录音一边播放的大致代码流程,主要就是AudioRecord和 AudioTrack的使用,实际使用的时候,你需要根据自己的实际情况,调试AudioRecord的音频采样参数和回放的参数,达到你想要的效果。另 外这个功能也能实现KTV的回声效果。自己调试一下参数即可。

代码:这里

时间: 2024-10-05 10:06:13

Android 实时录音和回放,边录音边播放 (KTV回音效果)的相关文章

Android实例-录音与回放(播放MP3)(XE8+小米2)

结果: 1.增加ActionList中的Action时,需要跳到Master界面,不能在Android4Phonel界面下. 2.如果不打开权限的话,会提示“该设备不支持停止录音操作”(Record audion改为True). 3.播放的效果是播放一次就停止了.不是循环的. 实例代码: 1 unit Unit1; 2 3 interface 4 5 uses 6 System.SysUtils, System.Types, System.UITypes, System.Classes, Sys

Android开发手记(31) 使用MediaRecorder录音

使用Android手机的时候,有时我们会用到录音功能,本文简单的介绍了如何使用MediaRecorder通过手机自带麦克风进行录音. 首先,既然是录音,我们需要录音和写外存的权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECORD_AUDIO&q

Android开发--仿微信语音对讲录音

自微信出现以来取得了很好的成绩,语音对讲的实现更加方便了人与人之间的交流.今天来实践一下微信的语音对讲的录音实现,这个也比较容易实现.在此,我将该按钮封装成为一个控件,并通过策略模式的方式实现录音和界面的解耦合,以方便我们在实际情况中对录音方法的不同需求(例如想要实现wav格式的编码时我们也就不能再使用MediaRecorder,而只能使用AudioRecord进行处理). 效果图: 实现思路 1.在微信中我们可以看到实现语音对讲的是通过点按按钮来完成的,因此在这里我选择重新自己的控件使其继承自

[Android]实现点击持续录音,松开结束录音,并实现随着分贝的大小改变图片

显示录音大小的DIALOG实现 public class VioceDomio { private Context mContext; private AlertDialog dialog ; private AlertDialog.Builder adialogbuile; private ImageView vioce_show; public VioceDomio(Context mContext) { this.mContext=mContext; } public void showR

类似微信发送语音,按下录音,松开结束录音;并且可播放

需要导入 #import <AVFoundation/AVFoundation.h> 利用此框架中的 AVAudioRecorder和AVAudioPlayer来录音和播放以下是AVAudioRecorder录音的使用方法: - (IBAction)downAction:(id)sender { 按下录音 if ([self canRecord]) { NSError *error = nil; 必须真机上测试,模拟器上可能会崩溃 recorder = [[AVAudioRecorder al

什么录音软件可以录制电脑内部播放的声音

说起录音,我们应该都不陌生,多多少少都会使用到录音这个功能,不管是商业还是日常的工作学习中,录音已经成为人们生活中不可或缺的一项小功能,可能很多人使用录音这个功能都是通过手机,但是我们都知道手机中想录音只能录制外部声音,而无法录制手机中正在播放的内容,目前手机只支持录制外部声音,但是对于电脑而言就方便多了,那什么录音软件可以录制电脑内部播放的声音呢? 1.由于手机和电脑系统的不同,所以在电脑上录制其系统发出的声音不是难事,但是需要借助第三方录音工具,类似的录音工具还是很多的,小编直接安利如何?

飞凌干货丨OK-xx18 Android实时时钟框架介绍

RTC(Real-TimeClock)实时时钟为操作系统提供了一个可靠的时间,并且在断电的情况下,RTC实时时钟也可以通过电池供电,一直运行下去.本文以OK-4418-C为例,介绍在Android实时时钟框架. 整体流程介绍由于实时时钟子系统,硬件抽象层.框架层.应用层的android开发包都已经做好,因此此接口的主要设计工作在于rx8010芯片的驱动的实现,包括芯片的初始化及配置时间,读取时间及接入实时时钟子系统等功能. 板子上电以后,内核驱动会初始化rtc芯片rx8010,并生成/dev/r

Android通过意图使用内置的音频播放器

如果实现一个音频文件的播放,那么在应用程序中提供播放音频文件功能的最简单的方式是利用内置的"Music(音乐)"应用程序的功能--即使用系统自带的或已安装好的音乐播放器来播放指定的音频文件. 本例比较简单,下面直接给出源代码: 布局文件activity_main: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http:/

android高仿微信UI点击头像显示大图片效果

转自:http://www.cnblogs.com/Jaylong/archive/2012/09/27/androidUI.html 用过微信的朋友朋友都见过微信中点击对方头像显示会加载大图,先贴两张图片说明下: 这种UI效果对用户的体验不错,今天突然有了灵感,试着去实现,结果就出来了.. 下面说说我的思路: 1.点击图片时跳转到另一个activity,然后显示加载的效果,即progressbar 2.显示图片的之前先弹出自定义dialog,然后模拟加载一段时间后,显示整张大图片,要全屏显示,