Android实现伴奏录音合成MP3

发布时间:2019-08-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Android实现伴奏录音合成MP3脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

本文实例为大家分享了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教程
脚本网站
android studio

脚本宝典总结

以上是脚本宝典为你收集整理的Android实现伴奏录音合成MP3全部内容,希望文章能够帮你解决Android实现伴奏录音合成MP3所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。