关于音源录制的问题

转载请注明转载自http://blog.csdn.net/l646871731/article/details/52160462


最近在弄项目,刚接触碰到了一个声音录制的问题

用了半天的时间写了一个录制demo,简单地写了使用AudioRecord来录制声音,结果却出来了一大堆问题


经过了总结,问题一共有三个

1.使用不同的方式采集声音源

2.使用不同的录音通道(主要是API的更新)

3.使用不同的保存音源数据的方式


下面我们一一说一下上面的三个问题。

原因及解决:

1.  不同的设备对音源输入的支持不同,部分不支持MediaRecorder.AudioSource.VOICE_RECOGNITION方式采取声音源的,采集到的是杂音,方案是判断次后视镜设备是否支持

MediaRecorder.AudioSource.VOICE_RECOGNITION方式采取声音源,若支持,则使用,不支持则使用MediaRecorder.AudioSource.MIC方式采集。

2.  channelConfig通道参数中api在版本5以后有部分修改,

Added in API level5;

修改如下:

3.保存音源信息成ACM流文件,可以用byte型数组取资源或者用short型数组,我一开始用的是short,但是奇怪的是用short[]去保存数据,出来的ACM流信息的音源文件播放出来的是杂音,又有可能是出来的文件,每隔一段没有了一些声音信息,原因还没有找到。如果大家有知道这个问题的原因和解决,欢迎大家提出和讨论

最后用byte[]来保存就没有问题了。


下面我把main文件贴出来供大家参考。


public class MainActivity extends Activity implements OnClickListener {

    private TextView stateView;
    private Button btnStart;
    private Button btnStop;

    private RecordTask recorder;

    private boolean isRecording = true;
    // ???????ڴ??
    private int bufferSizeInBytes = 0;
    private AudioRecord audioRecord;

    private int audioSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
    private int frequence = 16000;
    /**
     * ChannelConfig:AudioFormat .CHANNEL_CONFIGURATION_MONO??dioFormat.CHANNEL_CONFIGURATION_STEREO(??ʱ?????
     * CHANNEL_OUT_STEREO ???CHANNEL_IN_STEREO???
     * **/
    private int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
    private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        stateView = (TextView) this.findViewById(R.id.view_state);
        btnStart = (Button) this.findViewById(R.id.btn_start);
        btnStart.setOnClickListener(this);
        btnStop = (Button) this.findViewById(R.id.btn_stop);
        btnStop.setOnClickListener(this);
        btnStop.setEnabled(false);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.btn_start:
                // ??ʼ¼?
                recorder = new RecordTask();
                recorder.execute();
                stateView.setText("??ʼ¼?");
                break;
            case R.id.btn_stop:
                // ֹͣ¼?,???״̬
                this.isRecording = false;
                stateView.setText("ֹͣ¼?");
                break;
        }
    }

    @Override
    public void onDestroy() {
        // ¼????
        if (isRecording) {
            audioRecord.stop();
            audioRecord.release();
        }
        audioRecord = null;
        super.onDestroy();
    }

    class RecordTask extends AsyncTask<Void, Integer, Void> {
        @Override
        protected Void doInBackground(Void...arg0) {
            isRecording = true;
            try {
                // ???ݶ???õļ??????????????ʵĻ???С
                if (MediaRecorder.getAudioSourceMax() >= MediaRecorder.AudioSource.VOICE_RECOGNITION) {
                    audioSource = MediaRecorder.AudioSource.MIC;
                }
                bufferSizeInBytes = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
                // ʵ????AudioRecord
                audioRecord = new AudioRecord(audioSource, frequence, channelConfig, audioEncoding, bufferSizeInBytes);

                // ??ʼ¼?
                audioRecord.startRecording();
                writeDateTOFile();
            } catch (Exception e) {
            }
            return null;
        }

        protected void onProgressUpdate(Integer...progress) {
            stateView.setText(progress[0].toString());
        }

        protected void onPostExecute(Void result) {
            btnStop.setEnabled(false);
            btnStart.setEnabled(true);
        }

        protected void onPreExecute() {
            btnStart.setEnabled(false);
            btnStop.setEnabled(true);
        }

    }

    /**
     * ??ォ????????
     */
    private void writeDateTOFile() {
        // newһ??byte????????Щ?????ݣ????Ϊ????????
        byte[] audiodata = new byte[bufferSizeInBytes];
        FileOutputStream fos = null;
        int readsize = 0;

        try {
            File file;
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// ????SD?????
                file =
                        new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/record/" + "record"
                                + System.currentTimeMillis() + ".pcm");
                file.mkdirs();
                if (file.exists()) {
                    file.delete();
                }
            } else// ????SD?????
            {
                file = this.getCacheDir();
            }
            fos = new FileOutputStream(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        while (isRecording == true) {
            readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
            if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) {
                try {
                    fos.write(audiodata);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            if (fos != null)
                fos.close();
            // ¼????
            audioRecord.stop();
            audioRecord.release();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值