本文实例为大家分享了Android实现伴奏录音合成MP3的具体代码,供大家参考,具体内容如下
基本实现思路如下:
1.利用android自带的录音类(AudioRecord)实现录音.
private MediaPlayer player; private ImageView btnBack; private Button btnSwitchSong; private TextView tv_recod_time; private LyricView lv_lyric; private Button btnPlay; private TextView ivTitle; private boolean canPlay = true; private boolean isPause = false; private BackgroudMusicMode mode = BackgroudMusicMode.Accompany; 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; private int sampleRateInHz = 44100; private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; private AudioManager audioManager; private int maxVolume = 0; private int currentVolume = 0; protected int m_in_buf_size; private AudioRecord mRecorder; private byte[] m_in_bytes; private linkedListm_in_q; 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 (); // 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); // } } } 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文件.
主要调用的合成方法:
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);
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



