如何使用 AudioRecord 连续录制 4 秒组

Posted

技术标签:

【中文标题】如何使用 AudioRecord 连续录制 4 秒组【英文标题】:How to continuously record sets of 4 seconds with AudioRecord 【发布时间】:2014-01-24 11:17:20 【问题描述】:

我正在尝试从 AudioRecord 录制 4 秒的集合,处理它们然后再次录制等等。我正在以 44100 个样本/秒的速度录制,您可以在下面的代码中看到。不得不提的是,我记录,或者至少我应该记录一组 19Khz 的脉冲。

    int frequency = 44100;
                int blockSize = 44100;
                int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
                int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

                final int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);

                audioRecord = new AudioRecord(MediaRecorder.Audiosource.MIC, frequency, channelConfiguration,
                        audioEncoding, blockSize * 8); // if I multiply blockSize by 4 it will only give 88200 buffer size

                // start recording until explicitly stopped
                while ( <stopCondition> ) 
                    recData = new ByteArrayOutputStream();
                    dos = new DataOutputStream(recData);
                    short[] buffer = new short[blockSize * 4]; // Save the raw PCM
//                  timePassed = false;
//                  timer.cancel();
//                  timer.start();
                    audioRecord.startRecording();
//                  while (!timePassed) 
                        int bufferReadResult = audioRecord.read(buffer, 0, blockSize * 4);
                        for (int i = 0; i < blockSize && i < bufferReadResult; i++) 
                            try 
                                dos.writeShort(buffer[i]);
//                              buffer[i] = 0;
                             catch (IOException e) 
                                e.printStackTrace();
                            
                        
//                  

                    audioRecord.stop();
                    try 
                        dos.flush();
                        dos.close();
                     catch (IOException e1) 
                        e1.printStackTrace();
                    
... process the recorded data

正如您从代码中看到的(已注释),我尝试使用 countDownTimer 在 4 秒后停止录制。它一次只能从 audioRecord 读取 1 秒(blockSize 没有乘以 4),但我不知道缓冲区是否被覆盖,因为偏移量为 0 - 我认为它确实如此,但我仍然不确定 :) 使用这种方法,它没有记录 4 秒内播放的脉冲数 - 播放了 16 个脉冲,只记录了 2-3 个。

我尝试不使用计时器并从 audioRecord blockSize * 4 = 44100 (=1s) * 4 = 4s 中读取,但在 Audacity 中我只看到 1 秒被记录 - 在代码中的某处,此处未显示,我写了记录数据到文件以检查输出。再次记录的脉冲数不正确,但这很明显,因为我只有 1 秒的记录数据。

有没有更好的方法来连续记录 X 秒的集合并对其进行处理?或者如果我的方法比我做错的还好?

谢谢。

【问题讨论】:

【参考方案1】:

试试下面的代码。

Timer myTimer = new Timer();
        myTimer.schedule(new TimerTask() 
            @Override
            public void run() 
                startRecording();
            
        , 4000);

开始录制方法

private void startRecording() 
    myFilename = getFilename();
    recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(output_formats[currentFormat]);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setOutputFile(getFilename());
    recorder.setOnErrorListener(errorListener);
    recorder.setOnInfoListener(infoListener);
    try 
        recorder.prepare();
        recorder.start();
     catch (IllegalStateException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
    

获取文件名

private String getFilename() 
    String filepath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filepath, AUDIO_RECORDER_FOLDER);

    SimpleDateFormat sdfDate = new SimpleDateFormat("dd-MMM-yyyy hh-mm-ss");
    String currentDateandTime = sdfDate.format(new Date());

    if (!file.exists()) 
        file.mkdirs();
    
    return (file.getAbsolutePath() + "/" + currentDateandTime + file_exts[currentFormat]);

这将在 4 秒后开始新的录制,getFilename 将为您的录制命名为 currentDate 和 time。

希望你看起来和我从你的问题中理解的一样,如果我错过了理解你,请纠正我。

【讨论】:

感谢您的回答,但我认为使用 MediaRecorder 对我没有帮助。我看不到您在哪里指定采样率、音频编码等。记录一组 4 秒后,我所做的是将原始字节数据转换为双精度数组并应用 IIR 滤波器和其他处理。我只写文件来检查算法的每一步,这很好。我的问题是我不确定缓冲区是否包含所有记录的数据或只是其中的一部分。

以上是关于如何使用 AudioRecord 连续录制 4 秒组的主要内容,如果未能解决你的问题,请参考以下文章

增加录制 Android AudioRecord 的音量

Android:使用 audiorecord 类录制音频播放快进

Android 4.4中AudioRecord用例 - 录制系统内置声音

使用 AudioRecord 录制音频

在 Kotlin 上按下按钮时如何停止录制 AudioRecord

无法在 Android 中使用 AudioRecord 进行录制