刁一妾,网游之盟约天下,粉色房间
本文实例为大家分享了android实现伴奏录音合成mp3的具体代码,供大家参考,具体内容如下
基本实现思路如下:
1.利用android自带的录音类(audiorecord)实现录音.
/** * 播放伴奏 */ private mediaplayer player; /** * 返回按钮 */ private imageview btnback; /** * 切换歌曲 */ private button btnswitchsong; /** * 伴唱时长 */ private textview tv_recod_time; /** * 歌词view */ private lyricview lv_lyric; /** * 开始录制 */ private button btnplay; /** * 标题 */ private textview ivtitle; private boolean canplay = true; private boolean ispause = false; /*** * 背景音乐模式 */ private backgroudmusicmode mode = backgroudmusicmode.accompany; /** * 歌曲id */ private string songid; /** * 歌曲名称 */ private string songname; /** * 歌手名字 */ private string singername; /** * 伴奏文件 */ private file file; /** * 是否正在录制 */ private boolean isstart = false; /** * 录音状态 */ private boolean starting = false; /** * 伴奏时间 */ private int bztimetmp = 0; /** * 伴奏时间 */ private string bztime = ""; /** * 录制时间 */ private int recordtimelength=0; /** * 更新伴奏时间 */ private recordtask rt = null; /** * 录制频率,单位hz.这里的值注意了,写的不好,可能实例化audiorecord对象的时候,会出错。我开始写成11025就不行。这取决于硬件设备 * 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025 */ private int samplerateinhz = 44100; /** * 设置音频的录制的声道channel_in_stereo为双声道,channel_configuration_mono为单声道 */ private int channelconfig = audioformat.channel_configuration_mono; /** * 音频数据格式:pcm 16位每个样本。保证设备支持。pcm 8位每个样本。不一定能得到设备支持。 */ private int audioformat = audioformat.encoding_pcm_16bit; /** * 调整播放音量 */ private audiomanager audiomanager; /** * 最大音量 */ private int maxvolume = 0; /** * 当前音量 */ private int currentvolume = 0; /** * audiorecord 写入缓冲区大小 */ protected int m_in_buf_size; /** * 录制音频对象 */ private audiorecord mrecorder; /** * 录入的字节数组 */ private byte[] m_in_bytes; /** * 存放录入字节数组的大小 */ private linkedlist<byte[]> m_in_q; /** * audiotrack 播放缓冲大小 */ private int m_out_buf_size; /** * 播放音频对象 */ private audiotrack maudiotrack; /** * 播放的字节数组 */ private byte[] m_out_bytes; /** * 录制音频线程 */ private thread record; /** * 播放音频线程 */ private thread play; /** * 让线程停止的标志 */ private boolean flag = true; /** * 是否启动回声 */ private boolean room_flag = true; /***上面有个播放歌词的组件 /*** * 初始化 */ private void init() { audiomanager = (audiomanager)getsystemservice(context.audio_service); maxvolume = audiomanager.getstreammaxvolume(audiomanager.stream_voice_call); currentvolume = audiomanager.getstreamvolume(audiomanager.stream_voice_call); registerheadsetplugreceiver(); ycapplication = (yuechangapplication) getapplication(); coverdao = new coverdao(getapplicationcontext()); bundle bundle = getintent().getextras(); songid = bundle.getstring("songid"); songname = bundle.getstring("songname"); singername = bundle.getstring("singername"); if (songid != null) { // audiorecord 得到录制最小缓冲区的大小 m_in_buf_size = audiorecord.getminbuffersize(samplerateinhz, channelconfig, audioformat); // 实例化播放音频对象 mrecorder = new audiorecord(mediarecorder.audiosource.mic, samplerateinhz, channelconfig, audioformat, m_in_buf_size); // 实例化一个字节数组,长度为最小缓冲区的长度 m_in_bytes = new byte[m_in_buf_size]; // 实例化一个链表,用来存放字节组数 m_in_q = new linkedlist<byte[]>(); // audiotrack 得到播放最小缓冲区的大小 m_out_buf_size = audiotrack.getminbuffersize(samplerateinhz, channelconfig, audioformat); // 实例化播放音频对象 maudiotrack = new audiotrack(audiomanager.stream_music, samplerateinhz, channelconfig, audioformat, m_out_buf_size, audiotrack.mode_stream); // 实例化一个长度为播放最小缓冲大小的字节数组 m_out_bytes = new byte[m_out_buf_size]; record = new thread(new recordsound()); // if(ycapplication.isheadsetplug()){ // }else{ // m_out_trk = new audiotrack(audiomanager.stream_music, samplerateinhz, channelconfig, audioformat, // m_out_buf_size, audiotrack.mode_stream); // } } } /** * * 类描述:录音线程 * * @version 1.0 */ class recordsound implements runnable { @override public void run() { // 初始化输出流 dataoutputstream dos = null; try { file audiofile = new file(songutil.getrecordsingpcmpath(songid)); // 初始化输出流 dos = new dataoutputstream(new bufferedoutputstream(new fileoutputstream(audiofile))); byte[] bytes_pkg; if (mrecorder.getstate() == audiorecord.state_uninitialized) { // 实例化播放音频对象 mrecorder = new audiorecord(mediarecorder.audiosource.mic, samplerateinhz, channelconfig, audioformat, m_in_buf_size); } // 开始录音 mrecorder.startrecording(); while (flag) { int size = mrecorder.read(m_in_bytes, 0, m_in_buf_size); bytes_pkg = m_in_bytes.clone(); if (m_in_q.size() >= 2) { m_in_q.removefirst(); } m_in_q.add(bytes_pkg); if ((ycapplication.isheadsetplug() && ycapplication.isopeninearphone()) || (!ycapplication.isheadsetplug() && ycapplication.isopeninspeaker())) { //log.d(singsingleactivity.this.getclass().getname(), "启动录音播放1"); if (play == null||!room_flag) { //log.d(singsingleactivity.this.getclass().getname(), "启动录音播放2"); room_flag = true; play = new thread(new playrecord()); // 启动播放线程 play.start(); } } else { if(room_flag||play != null){ //log.d(singsingleactivity.this.getclass().getname(), "关闭录音播放1"); room_flag = false; if (play != null) { play.interrupt(); } play = null; } } // 写入pcm文件 dos.write(bytes_pkg, 0, size); dos.flush(); } } catch (exception e) { // todo: handle exception e.printstacktrace(); } finally { try { // 关闭录音 if (mrecorder != null) { try { if (mrecorder.getstate() == audiorecord.state_initialized) { // 关闭录音 mrecorder.stop(); mrecorder.release(); } } catch (exception e2) { // todo: handle exception } } if (dos != null) { dos.close(); } } catch (exception e2) { // todo: handle exception e2.printstacktrace(); } } } }
2.录音完成后,调用开源工具(mad)实现pcm合成输出到mp3文件.
主要调用的合成方法:
/*** * 方法描述:本地方法调用jni合并mp3pcm与sourcepcm * @param sourcepcm * @param mp3pcm * @param mixpcm * @return */ public static native int mix2pcmtopcm(string sourcepcm, string mp3pcm, string mixpcm); string recordpcmpath = songutil.getrecordsingpcmpath(songid); //录音生成的pcm文件 string accompanypcmpath = songutil.getaccompanysongpcmpath(songid); //伴奏解码生成的pcm文件 string mixpcmpath = songutil.getmixsingpcmpath(songid); //合成后的pcm文件 string mixmp3path = songutil.getmixsingmp3path(songid); //合成后的mp3文件 // 混音 int code = songencodeutil.mix2pcmtopcm(recordpcmpath, accompanypcmpath, mixpcmpath); if (code == 0) { // 转换混合后音频格式 to mp3 int i = simplelame.convert(mixpcmpath, mixmp3path, m_in_buf_size); log.i(singsingleactivity.this.getclass().getname(), "转换" + i + "混音完成"); savemp3file(mixmp3path); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android Manifest中meta-data扩展元素数据的配置与获取方式
Android实现获取meta-data和build.gradle的值
Android获取清单文件中的meta-data,解决碰到数值为null的问题
解决webview 第二次调用loadUrl页面不刷新的问题
解决Android WebView拦截url,视频播放加载失败的问题
Android webview加载https链接错误或无响应的解决
网友评论