android语音录制和压缩

因为上一篇博客代码有点太多,就单开了,这两天主要在看android语音录制和压缩转码相关知识,前端时间看见腾讯官方微博宣布,已经开放出即使聊天软件正在等待审批,但这个直接影响电话运营商,能通过的可能性应该不大,但我对这方面的技术很有兴趣,所以就试试看。其中涉及到很多声音方面的处理问题,在android中有两个类可以录制语音:AudioRecord和MediaRecorder,MediaRecorder主要是录制音频并写入文件,而AudioRecord主要是录制音频流,录制的音频流为pcm格式,关于pcm格式可以自行搜索一下,在传输过程中可以转换为amr格式,但没有相关可以类库有点麻烦,另外iphone不支持播放amr格式音频,如果需要跨两个平台可以使用AAC,压缩比也不错,音质也很好,我还没有测试过,网上评议而已。编码方面大家都推荐speex,我看了一下,需要是用System.loadLibrary加载进speex提供的类库。下面记录一下写的一个边录制边播放的一段代码吧

package voice.hcent.com;
 
import java.io.IOException;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Looper;
import android.os.Process;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
 
public class VoiceHcentActivity extends Activity {
 
    static {
        System.loadLibrary("media_jni");
    }
 
    public int frequency = 8000;
    private int rBufferSize, pBufferSize;
    private Button startSpeech;
    private AudioRecord recorder;
    private VoiceSpeech vspeech;
    private AudioTrack player;
    private boolean stopSpeech = false;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        init();
 
        test();
    }
 
    public void init(){
        try{
            startSpeech = (Button)findViewById(R.id.StartSpeech);
 
            //设置播放器缓冲区大小
            pBufferSize = AudioTrack.getMinBufferSize(frequency, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                    AudioFormat.ENCODING_PCM_16BIT);
 
            //获取播放器对象
            player = new AudioTrack(AudioManager.STREAM_MUSIC, frequency, 
                    AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
                    pBufferSize, AudioTrack.MODE_STREAM);
 
            //设置录音缓冲区大小
            rBufferSize = AudioRecord.getMinBufferSize(frequency, 
                    AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
 
            //获取录音机对象
            recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
                    frequency, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                    AudioFormat.ENCODING_PCM_16BIT, rBufferSize);
 
        }catch (Exception e) {
            String msg = "ERROR init: "+e.getStackTrace();
            VoiceHcentActivity.this.toastMsg(msg);
        }
    }
 
    /**
     * 开始录音
     */
    public void startRecord(){
        stopSpeech = false;
        vspeech = new VoiceSpeech();
        vspeech.start();
    }
 
    /**
     * 结束录音
     */
    public void stopRecord() {
        stopSpeech = true;
    }
 
    /**
     * 开始播放录音
     */
    public void startPlay(){
 
        //设置播放器音量
        player.setStereoVolume(0.7f, 0.7f);
 
        player.play();
    }
 
    /**
     * 结束播放录音
     */
    public void stopPlay(){
        player.stop();
    }
 
    public void test(){
 
        startSpeech.setOnTouchListener(new View.OnTouchListener() {
 
            public boolean onTouch(View arg0, MotionEvent arg1) {
 
                switch (arg1.getAction()) {
 
                    case MotionEvent.ACTION_DOWN: //开始说话
                        startPlay();
                        startRecord();
 
                        toastMsg("starting record!");
                        break;
 
                    case MotionEvent.ACTION_UP: //停止说话
                        Log.i("hcent", "111");
                        stopPlay();
                        Log.i("hcent", "222");
                        stopRecord();
                        toastMsg("stoped record!");
                        break;
 
                    default:
                        break;
                }
 
                return false;
            }
        });
 
    }
 
    public class VoiceSpeech extends Thread{
 
        @Override
        public void run() {
            super.run();
            try {
                byte[] tempBuffer, readBuffer = new byte[rBufferSize];
                int bufResult = 0;
                recorder.startRecording();
                while(!stopSpeech){
                    bufResult = recorder.read(readBuffer, 0, rBufferSize);
                    if(bufResult>0 && bufResult%2==0){
                        tempBuffer = new byte[bufResult];
                        System.arraycopy(readBuffer, 0, tempBuffer, 0, rBufferSize);
                        player.write(tempBuffer, 0, tempBuffer.length);
                    }
                    Log.d("hcent", "get read:"+bufResult+"___"+readBuffer.length);
                }
                recorder.stop();
                Looper.prepare();
                VoiceHcentActivity.this.toastMsg("AudioSpeech have ended!");
                Looper.loop();  
            } catch (Exception e) {
                String msg = "ERROR AudioRecord: "+e.getStackTrace();
                Looper.prepare();
                VoiceHcentActivity.this.toastMsg(msg);
                Looper.loop();
            }      
        }
    }
    @Override
    protected void onDestroy(){
        player.release();
        recorder.release();
        super.onDestroy();
        Process.killProcess(Process.myPid());
    }
    public void toastMsg(String msg){
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
        Log.e("hcent", msg);
    }  
}


  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值