a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁(yè) > 系統(tǒng) > Android > 正文

Android實(shí)現(xiàn)伴奏錄音合成MP3

2019-10-21 21:26:51
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文實(shí)例為大家分享了Android實(shí)現(xiàn)伴奏錄音合成MP3的具體代碼,供大家參考,具體內(nèi)容如下

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

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

 /**  * 播放伴奏  */ private MediaPlayer player; /**  * 返回按鈕  */ private ImageView btnBack; /**  * 切換歌曲  */ private Button btnSwitchSong; /**  * 伴唱時(shí)長(zhǎng)  */ private TextView tv_recod_time; /**  * 歌詞VIEW  */ private LyricView lv_lyric; /**  * 開(kāi)始錄制  */ private Button btnPlay; /**  * 標(biāo)題  */ private TextView ivTitle; private boolean canPlay = true; private boolean isPause = false;  /***  * 背景音樂(lè)模式  */ 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; /**  * 伴奏時(shí)間  */ private int bztimetmp = 0; /**  * 伴奏時(shí)間  */ private String bztime = "";  /**  * 錄制時(shí)間  */ private int recordTimeLength=0; /**  * 更新伴奏時(shí)間  */ private RecordTask rt = null;  /**  * 錄制頻率,單位hz.這里的值注意了,寫(xiě)的不好,可能實(shí)例化AudioRecord對(duì)象的時(shí)候,會(huì)出錯(cuò)。我開(kāi)始寫(xiě)成11025就不行。這取決于硬件設(shè)備  * 設(shè)置音頻采樣率,44100是目前的標(biāo)準(zhǔn),但是某些設(shè)備仍然支持22050,16000,11025  */ private int sampleRateInHz = 44100; /**  * 設(shè)置音頻的錄制的聲道CHANNEL_IN_STEREO為雙聲道,CHANNEL_CONFIGURATION_MONO為單聲道  */ private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;  /**  * 音頻數(shù)據(jù)格式:PCM 16位每個(gè)樣本。保證設(shè)備支持。PCM 8位每個(gè)樣本。不一定能得到設(shè)備支持。  */ private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;  /**  * 調(diào)整播放音量  */ private AudioManager audioManager;  /**  * 最大音量  */ private int maxVolume = 0;  /**  * 當(dāng)前音量  */ private int currentVolume = 0;  /**  * AudioRecord 寫(xiě)入緩沖區(qū)大小  */ protected int m_in_buf_size; /**  * 錄制音頻對(duì)象  */ private AudioRecord mRecorder; /**  * 錄入的字節(jié)數(shù)組  */ private byte[] m_in_bytes; /**  * 存放錄入字節(jié)數(shù)組的大小  */ private LinkedList<byte[]> m_in_q; /**  * AudioTrack 播放緩沖大小  */ private int m_out_buf_size; /**  * 播放音頻對(duì)象  */ private AudioTrack mAudioTrack; /**  * 播放的字節(jié)數(shù)組  */ private byte[] m_out_bytes; /**  * 錄制音頻線程  */ private Thread record; /**  * 播放音頻線程  */ private Thread play; /**  * 讓線程停止的標(biāo)志  */ private boolean flag = true; /**  * 是否啟動(dòng)回聲  */ private boolean room_flag = true;  /***上面有個(gè)播放歌詞的組件  /***  * 初始化  */ 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);   // 實(shí)例化播放音頻對(duì)象   mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat,     m_in_buf_size);   // 實(shí)例化一個(gè)字節(jié)數(shù)組,長(zhǎng)度為最小緩沖區(qū)的長(zhǎng)度   m_in_bytes = new byte[m_in_buf_size];   // 實(shí)例化一個(gè)鏈表,用來(lái)存放字節(jié)組數(shù)   m_in_q = new LinkedList<byte[]>();    // AudioTrack 得到播放最小緩沖區(qū)的大小   m_out_buf_size = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);   // 實(shí)例化播放音頻對(duì)象   mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRateInHz, channelConfig, audioFormat,     m_out_buf_size, AudioTrack.MODE_STREAM);   // 實(shí)例化一個(gè)長(zhǎng)度為播放最小緩沖大小的字節(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) {     // 實(shí)例化播放音頻對(duì)象     mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig,       audioFormat, m_in_buf_size);    }     // 開(kāi)始錄音    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(), "啟動(dòng)錄音播放1");      if (play == null||!room_flag) {       //Log.d(SingSingleActivity.this.getClass().getName(), "啟動(dòng)錄音播放2");       room_flag = true;       play = new Thread(new playRecord());       // 啟動(dòng)播放線程       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;      }     }     // 寫(xiě)入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)用開(kāi)源工具(Mad)實(shí)現(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);      }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产精品视频一区二区三区麻豆 | 91在线一区二区 | 日日躁夜夜躁白天躁晚上躁91 | 精品国产乱码久久久久久蜜柚 | 在线观看av片 | 欧美激情一区二区三区蜜桃视频 | 午夜一级毛片 | 男人天堂中文字幕 | 国产精品视频一区二区三区不卡 | 99视频精品 | 亚洲综合色自拍一区 | 亚洲成人av在线 | 亚洲欧美日韩精品 | 日韩特黄一级欧美毛片特黄 | 91人人射| 男女羞羞羞视频午夜视频 | 91精品国产91久久久久久吃药 | 免费a在线看 | 国产精品久久久久久久一区探花 | 99精品国产一区二区 | 大香萑 | 免费成人高清在线视频 | 欧美日韩国产精品一区二区亚洲 | 欧美日韩国产综合视频 | 国产亚洲成av人片在线观看桃 | 成人av免费在线观看 | 亚洲中国精品精华液 | 日韩精品一区二区三区视频播放 | 亚洲视频一区二区在线 | 黄色片视频网站 | 久久精品国产99久久久 | 三级视频在线观看 | 神马久久久久久久 | 亚洲综合在线一区二区三区 | 国产免费拔擦拔擦8x高清 | 特级毛片www| 国产日韩视频在线观看 | 久久亚洲一区二区三区四区 | 亚洲国产精品成人综合色在线婷婷 | 策驰影院在线观看2024 | 日韩三级免费观看 |