1

运行 YandexSpeechKit 识别器时,我可以在文件中同时录制来自麦克风的声音吗?

需要同时进行语音识别(使用类识别器)并将声音从设备麦克风录制到文件中。使用标准机制 MediaRecord 是不可能的,因为 MediaRecord 和 YandexSpeechKit 使用本机方法和相同的资源。它导致某些进程(MediaRecord 或 Recognizer)失败。

我正在尝试使用 RecognizerListener -> onSoundDataRecorded(Recognizer Recognizer, byte[] bytes) 代码如下:

@Override
public void onSoundDataRecorded(Recognizer recognizer, byte[] bytes) {

    Logger.d(TAG, "onSoundDataRecorded");
    write(bytes);
}     


public void write(byte[] bytes) {

    File file = getTmpFile();
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file, true);
        fos.write(bytes);
    } catch (IOException e1) {
        e1.printStackTrace();
    } finally {
        if(fos != null) {
            try {
                fos.flush();
                fos.close();
            } catch(IOException e) {

            }
        }
    }
}

但是虽然生成的文件无法播放。有人可以帮助我吗?

谢谢!

4

1 回答 1

0

Yandex SpeechKit 返回原始 PCM(16 kHz 单声道 16 位)数据。您应该添加 WAV 标头或作为 PCM 播放。例如在通过 sox 的类 unix 操作系统中:

play -r 16000 -b 16 -c 1 -e signed-integer filename.pcm

要添加 WAV 标头,您可以使用带有参数的此类https://github.com/MohammadAG/Android-SoundRecorder/blob/master/src/com/mohammadag/soundrecorder/WavConverter.java

private static final long SAMPLE_RATE = 16000; private static final int RECORDER_BPP = 16; private static final int CHANNELS = 1; private static final long BYTE_RATE = RECORDER_BPP * SAMPLE_RATE * CHANNELS/8;

        @Override
        public void onRecognizerRecordingBegin() {
            try {
                tempFileName = getFilename();
                os = new FileOutputStream(tempFileName, true);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onRecognizerRecordingDone() {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            int bufferSize = AudioRecord.getMinBufferSize(
                    16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
            WavConverter.copyWaveFile(tempFileName, getFilename(), bufferSize);
            deleteTempFile();
        }

        @Override
        public void onRecognizerSoundDataRecorded(byte[] bytes) {
            try {
                os.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
于 2015-09-28T13:47:51.023 回答