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);
      }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android采用FFmpeg实现音视频合成与分离

    上一篇文章谈到音频剪切.混音.拼接与转码,也详细介绍cMake配置与涉及FFmpeg文件的导入: android端采用FFmpeg进行音频混合与拼接剪切.现在接着探讨音视频的合成与分离. 1.音频提取 从多媒体文件中提取音频,关键命令为"-acodec copy -vn",其中"-acodec copy"是采用音频编码器拷贝音频流,"-vn"是去掉video视频流: /** * 使用ffmpeg命令行进行抽取音频 * @param srcFile

  • Android音频编辑之音频合成功能

    前言 音频编辑系列: - android音频编辑之音频转换PCM与WAV -android音频编辑之音频裁剪 - android音频编辑之音频合成 本篇主要讲解音频PCM数据的合成,这里合成包括音频之间的拼接,混合. - 音频拼接:一段音频连接着另一段音频,两段音频不会同时播放,有先后顺序. - 音频混合:一段音频和另一段音频存在相同的区间,两者会有同时播放的区间. 下面是音频拼接,音频混合的效果图: 音频拼接 如果大家理解了android音频编辑之音频转换PCM与WAV和android音频编辑

  • Android Studio应用开发集成百度语音合成使用方法实例讲解

    首先,语音合成是指将文本信息转换成声音.意思就是将文本转化为声音,让你的应用开口说话.国内在业内比较有名的第三方语音合成平台有百度语音和科大讯飞. 本文集成的是百度语音合成,其主要特点是: 完全永久免费 业界首创完全永久免费新形式,为开发者提供最流畅最自然的语音合成服务.完全免费,永久使用,彻底摆脱限制. 离线在线融合模式 SDK可以根据当前网络状况,自动判断使用本地引擎还是云端引擎进行语音合成,再也不用担心流量消耗! 多语言多音色可选 中文普通话.中英文混读.男声.女声任你选,更支持语速.音调

  • Android中音视频合成的几种方案详析

    前言 最近工作中遇到了音视频处理的需求,Android下音视频合成,在当前调研方案中主要有三大类方法:MediaMux硬解码,mp4parser,FFmepg.三种方法均可实现,但是也有不同的局限和问题,先将实现和问题记录于此,便于之后的总结学习.下面话不多说了,来一起看看详细的介绍吧. 方法一(Fail) 利用MediaMux实现音视频的合成. 效果:可以实现音视频的合并,利用Android原生的VideoView和SurfaceView播放正常,大部分的播放器也播放正常,但是,但是,在上传Y

  • Android实现伴奏录音合成MP3

    本文实例为大家分享了Android实现伴奏录音合成MP3的具体代码,供大家参考,具体内容如下 基本实现思路如下: 1.利用android自带的录音类(AudioRecord)实现录音. /** * 播放伴奏 */ private MediaPlayer player; /** * 返回按钮 */ private ImageView btnBack; /** * 切换歌曲 */ private Button btnSwitchSong; /** * 伴唱时长 */ private TextView

  • Android编程实现播放MP3功能示例

    本文实例讲述了Android编程实现播放MP3功能.分享给大家供大家参考,具体如下: 在android中播放mp3非常简单,也是项目中经常使用的,比如说要做项目的背景音乐,应用中某些功能的提示音等的.应用非常广泛,下面提供一个简单的使用实例: layout文件的配置: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.and

  • Android录制语音文件wav转mp3的方法示例

    1.Android 使用AudioRecord而实现录音暂停以及wav文件转mp3文件.因为android系统开源的原因,导致许多生产厂商乱改系统源码,此处小米最为恶心,使用android原生的AudioRecord录制只能保存wav和pcm格式的语音文件,但是小米手机录制的wav语音文件系统本身不支持,所以使用MediaPlayer不能播放wav格式的文件,其它手机可以.此时有一万匹草泥马从旁边疾驰而过... 2.针对这个问题解决方案目前有两种: 方案1: 将录制完的wav文件转化成mp3格式

  • Cocos2d-x中背景音乐和音效使用实例

    游戏中的音乐和音效是必不可少的,好的音乐可以给我们留下很深的印象也决定了这个游戏的品质.今天我们来学习一下cocos2d-x中如何使用音乐和音效.这些用到的函数都比较简单,现在直接上代码. //声音预先处理类的头文件 #ifndef _AUDIO_PRETREAT_H #define _AUDIO_PRETREAT_H #include "cocos2d.h" //使用声音引擎必须包含SimpleAudioEngeim.h头文件 #include "SimpleAudioEn

  • 利用libmp3lame实现在Android上录音MP3文件示例

    之前项目需要实现MP3的录音,于是使用上了Lame这个库.这次做一个demo,使用AndroidStudio+Cmake+NDK进行开发.利用Android SDK提供的AndroidRecorder进行录音,得到PCM数据,并使用jni调用Lame这个C库将PCM数据转换为MP3文件.并使用MediaPlayer对录音的MP3文件进行播放.另外此次的按键是仿微信的语音按键,按下录音,松开结束,若中途上滑松开即取消 效果如下: 项目地址: LameMp3ForAndroid_jb51.rar 一

  • Android实现使用流媒体播放远程mp3文件的方法

    本文实例讲述了Android实现使用流媒体播放远程mp3文件的方法.分享给大家供大家参考,具体如下: package com.shadow.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.

  • Android递归方式删除某文件夹下的所有文件(.mp3文件等等)

    1.由于需要删除文件,因此需要如下权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> 2.核心代码 复制代码 代码如下: package com.example.deleteyoumi; import java.io.File; import android.os.Bundle; import android.os.Han

  • Android录制mp3格式文件

    前言 最近做一个即时通信类的项目,由于要保证pc端,iOS端和Android端的通用性,最终统一为MP3格式,一直担心MP3格式会不会很大,但是实测还是可以接受的.下面来看看具体步骤: 工具 MP3格式是用一个开源项目转的,MP3lame,由于该项目用到了jni,所以需要大家配置好ndk环境,环境配置在此就不多说了,大家可以自行百度,最新的应该很好配置. 创建jni 拷贝文件 下载好后(我下载的是3.98.4版本)打开,找到libmp3lame文件,将里面的.h和.c拷贝下来,在自己的工程里创建

  • 详解Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.迭代List集合,把每一个Mp3Info对象的所有属性,保存到Map对象当中 3.定义一个List集合,把Map对象添加到List集合当中 4.通过定义一个SimpleAdpter,调用setAdpter方法,将数据显示到列表当中 /** * 用于从数据库中查询歌曲的信息,保存在List当中 * * @return */ public Lis

  • Android录音mp3格式实例详解

    Android录音支持的格式有amr.aac,但这两种音频格式在跨平台上表现并不好. MP3显然才是跨平台的最佳选择. 项目地址 GavinCT/AndroidMP3Recorder 实现思路概述 在分析代码前,我们需要明确几个问题 1. 如何最终生成MP3 实现MP3格式最好是借助Lame这个成熟的解决方案. 对于Android来说,需要借助JNI来调用Lame的C语言代码,实现音频格式的转化. 2. 如何获取最初的音频数据 AudioRecord类可以直接帮助我们获取音频数据. 3. 如何进

随机推荐