【问题标题】:MediaRecorder record audio in a loopMediaRecorder 循环录制音频
【发布时间】:2019-05-04 21:44:21
【问题描述】:

我正在开发一个声音识别系统。我正在使用在 python 上开发的 tensorflow 模型将 MFCC 值转换为标签。我正在使用 MediaRecorder 类来录制音频,并且我在循环中进行,因此我可以不断地获取麦克风音频,然后从模型中获取标签。这是录音循环:

temp = 0;
    while (true) {
        audioPath = getApplicationContext().getFilesDir().getAbsolutePath();
        audioPath += "/Recording" + temp + ".3gp";

        audioFile = new File(audioPath);
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setOutputFile(audioPath);
        try {
            mediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mediaRecorder.start();
        sleep(2000);
        if (!isRunning) {
            mediaRecorder.stop();
            return;
        }
        try {
            int amplitude = mediaRecorder.getMaxAmplitude();
            Log.d("volume", Integer.toString(amplitude));
            //finished = false;
            avgVolumeTask task = new avgVolumeTask();
            task.execute(amplitude);
        } catch (Exception e) {
            Log.d("Exception in startMediaRecorder()", e.toString());
        }
        mediaRecorder.stop();
        mediaRecorder.release();

        soundRecognition task2 = new soundRecognition();
        task2.execute();
        audioFile.delete();
        temp++;
    }

这是声音识别方法:

private class soundRecognition extends AsyncTask<Integer, Integer, Long> {
    @Override
    protected Long doInBackground(Integer... level) {
        float[] mfccValues = null;
        Interpreter tflite = null;
        float[][] labelProbArray = null;
        try {
            mfccValues = computeMFCC();
            labelList = loadLabelList();
            labelProbArray = new float[1][labelList.size()];
            tflite = new Interpreter(loadModel());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
        }
        tflite.run(mfccValues, labelProbArray);

        for (int i = 0; i < labelProbArray[0].length; i++) {
            float value = labelProbArray[0][i];
            //if (i == 1f){
                //Log.d("Output at " + Integer.toString(i) + ": ", Float.toString(value));
                //doAlert(i);
            //}
        }

        return null;
    }
}

computeMFCC 方法是这样的:

public float[] computeMFCC() throws IOException, UnsupportedAudioFileException {

    FileInputStream in2 = new FileInputStream(audioPath);
    int i;
    // InputStream to byte array
    byte[] buf = IOUtils.toByteArray(in2);
    in2.close();
    i = Integer.MAX_VALUE;

    // byte array to short array
    short[] shortArr = new short[buf.length / 2];
    ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shortArr);

    int count = 0;
    while (count <= shortArr.length) {                    // Still have data to process.
        for (int n = 0; n < nSubframePerBuf; n++) {            // Process audio signal in ArrayList and shift by one subframe each time
            int k = 0;
            for (i = (n * frameShift); i < (n + 1) * frameShift; i++) {
                subx[k] = shortArr[i];
                k++;
            }
            subframeList.add(subx);                            // Add the current subframe to the subframe list. Later, a number of
        }
        count++;
    }
    // Need at least nSubframePerMfccFrame to get one analysis frame
    x = extractOneFrameFromList(nSubframePerMfccFrame);

    MFCC mfcc = new MFCC(samplePerFrm, 16000, numMfcc);
    double[] mfccVals = mfcc.doMFCC(x);
    float[] floatArray = new float[mfccVals.length];
    for (i = 0 ; i < mfccVals.length; i++)
    {
        floatArray[i] = (float) mfccVals[i];
    }
    return floatArray;
}

doMFCC 方法来自此处下载的 java 文件:

https://github.com/enmwmak/ScreamDetector/blob/master/src/edu/polyu/mfcc/MFCC.java

我遇到的问题是,经过几次迭代后,我遇到了文件未创建的问题,然后将结果从输入流传递到 tensorflow 模型时出现空错误。

可能的问题

一个原因可能是文件的存储位置。我一直在尝试将文件发送到本地存储,因为我担心所有设备都没有外部存储。

另一个原因可能是我没有在正确的位置调用声音识别。在 mediaRecorder 停止后,我等待将确保文件是用麦克风音频写入的,但是当我查看 fileInputStream 的内容时,它似乎无法正常工作,并且在每个循环中文件始终相同。

任何帮助将不胜感激。

【问题讨论】:

    标签: java android mediarecorder


    【解决方案1】:

    在 while 循环中设置 sleep(2000) 可能会很棘手。 最好检查毫秒并中断直到 2000 毫秒过去。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 2011-08-18
      相关资源
      最近更新 更多