真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android如何實現(xiàn)伴奏錄音合成MP3

這篇文章主要介紹了Android如何實現(xiàn)伴奏錄音合成MP3,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站設計、成都做網(wǎng)站與策劃設計,潛江網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設10余年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:潛江等地區(qū)。潛江做網(wǎng)站價格咨詢:028-86922220

具體內(nèi)容如下

基本實現(xiàn)思路如下:

1.利用android自帶的錄音類(AudioRecord)實現(xiàn)錄音.

 /**
  * 播放伴奏
  */
 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;
 /**
  * 錄音狀態(tài)
  */
 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;
 
 /**
  * 音頻數(shù)據(jù)格式:PCM 16位每個樣本。保證設備支持。PCM 8位每個樣本。不一定能得到設備支持。
  */
 private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
 
 /**
  * 調(diào)整播放音量
  */
 private AudioManager audioManager;
 
 /**
  * 最大音量
  */
 private int maxVolume = 0;
 
 /**
  * 當前音量
  */
 private int currentVolume = 0;
 
 /**
  * AudioRecord 寫入緩沖區(qū)大小
  */
 protected int m_in_buf_size;
 /**
  * 錄制音頻對象
  */
 private AudioRecord mRecorder;
 /**
  * 錄入的字節(jié)數(shù)組
  */
 private byte[] m_in_bytes;
 /**
  * 存放錄入字節(jié)數(shù)組的大小
  */
 private LinkedList m_in_q;
 /**
  * AudioTrack 播放緩沖大小
  */
 private int m_out_buf_size;
 /**
  * 播放音頻對象
  */
 private AudioTrack mAudioTrack;
 /**
  * 播放的字節(jié)數(shù)組
  */
 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 得到錄制最小緩沖區(qū)的大小
   m_in_buf_size = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
   // 實例化播放音頻對象
   mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat,
     m_in_buf_size);
   // 實例化一個字節(jié)數(shù)組,長度為最小緩沖區(qū)的長度
   m_in_bytes = new byte[m_in_buf_size];
   // 實例化一個鏈表,用來存放字節(jié)組數(shù)
   m_in_q = new LinkedList();
 
   // AudioTrack 得到播放最小緩沖區(qū)的大小
   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);
   // 實例化一個長度為播放最小緩沖大小的字節(jié)數(shù)組
   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(), "關(guān)閉錄音播放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 {
     // 關(guān)閉錄音
     if (mRecorder != null) {
      try {
       if (mRecorder.getState() == AudioRecord.STATE_INITIALIZED) {
        // 關(guān)閉錄音
        mRecorder.stop();
        mRecorder.release();
       }
      } catch (Exception e2) {
       // TODO: handle exception
      }
     }
     if (dos != null) {
      dos.close();
     }
    } catch (Exception e2) {
     // TODO: handle exception
     e2.printStackTrace();
    }
   }
 
  }
 }

2.錄音完成后,調(diào)用開源工具(Mad)實現(xiàn)PCM合成輸出到MP3文件.

主要調(diào)用的合成方法:

/***
 * 方法描述:本地方法調(diào)用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) {
       // 轉(zhuǎn)換混合后音頻格式 TO mp3
       int i = SimpleLame.convert(mixPCMPath, mixMP3Path, m_in_buf_size);
       Log.i(SingSingleActivity.this.getClass().getName(), "轉(zhuǎn)換" + i + "混音完成");
       saveMp3File(mixMP3Path);
      }

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Android如何實現(xiàn)伴奏錄音合成MP3”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學習!


本文名稱:Android如何實現(xiàn)伴奏錄音合成MP3
文章分享:http://weahome.cn/article/jiecdj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部