Android - 录制音频时的音频剪辑波峰/峰值剪辑和其间的周期性 0 位值

问题描述

我正在尝试通过蓝牙设备录制音频流。我正在使用蓝牙 SCO 来获取蓝牙音频和 AudioRecord 类来录制音频。 我正在使用采样率为 16000

.PCM 通道录制 RAW MONO 文件

我正在像这样计算 BufferSize

    private static final int BUFFER_SIZE_FACTOR = 2;
    private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLING_RATE_IN_HZ,CHANNEL_CONFIG,AUDIO_FORMAT) * BUFFER_SIZE_FACTOR;

这就是我目前获取/编写音频的方式,

private class RecordingRunnable implements Runnable {

    @Override
    public void run() {
        setFileNameAndPath();
        
        final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
        try (final FileOutputStream outStream = new FileOutputStream(mFilePath)) {
            while (recordingInProgress.get()) {
                int result = recorder.read(buffer,BUFFER_SIZE);
                if (result < 0) {
                    throw new RuntimeException("Reading of audio buffer failed: " +
                            getBufferReadFailureReason(result));
                }
                outStream.write(buffer.array(),BUFFER_SIZE);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Writing of recorded audio failed",e);
        }

    }

我做了一点研究,发现裁剪效果可能是由于错误的字节顺序 (LITTLE_ENDIAN or BIG_ENDIAN) 或由于多线程不佳。但是,在当前的实现中,我无法理解字节是如何排序和保存的,以及如何解决剪切/噪声问题。

我正在启动我的录音机,可以像这样运行

    recordingThread = new Thread(new RecordingRunnable(),"Recording Thread");
    recordingThread.start();
    recordingThread.setPriority(Thread.MAX_PRIORITY);

解决方法

我遇到了同样的问题,我用下面的代码解决了这个问题。

    private byte[] short2byte(short[] sData,int size) {
        int shortArrsize = size;
        byte[] bytes = new byte[shortArrsize * 2];
        for (int i = 0; i < shortArrsize; i++) {
            bytes[i * 2] = (byte) (sData[i] & 0x00FF);
            bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
            sData[i] = 0;
        }
        return bytes;

    }

......

            int bufferSize = AudioRecord.getMinBufferSize(48000,AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT);
            short[] buffer = new short[bufferSize];

            int source = MediaRecorder.AudioSource.VOICE_RECOGNITION;

            mAudioRecorder = new AudioRecord(source,48000,AudioFormat.ENCODING_PCM_16BIT,bufferSize);
            int state = mAudioRecorder.getState();
            if (state != AudioRecord.STATE_INITIALIZED) {
                Log.e(TAG,"Can not support");
                return;
            }

            mAudioRecorder.startRecording();

            while (mIsRecording) {
                int bufferReadResult = mAudioRecorder.read(buffer,bufferSize);
                if (bufferReadResult < 0) {
                    continue;
                }

                try {
                    byte data[] = short2byte(buffer,bufferReadResult);
                    fos.write(data,bufferReadResult * 2);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...