基本实现思路如下:
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);
                        }

完整代码下载