1

我正在尝试用麦克风输入填充缓冲区并分析内容。我创建我的缓冲区:

    int bufferSize=AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
    short[] buffer1 = new short[bufferSize];

然后在一个名为 Recorder 的单独类中,我有以下相关代码:

public short[] fillBuffer(short[] audioData, int bufferSize) {

    AudioRecord recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT, bufferSize); // instantiate the
                                                            // AudioRecorder

    if (recorder.getRecordingState() == android.media.AudioRecord.RECORDSTATE_STOPPED)
        recorder.startRecording(); // check to see if the Recorder
                                    // has stopped or is not
                                    // recording, and make it
                                    // record.

    recorder.read(audioData, 0, bufferSize); // read the PCM
                                                // audio data
                                                // into the
                                                // audioData
                                                // array

    if (recorder.getState() == android.media.AudioRecord.RECORDSTATE_RECORDING)
        recorder.stop(); // stop the recorder

    return audioData;

}

然后,当我打电话时:

recorder.fillBuffer(buffer1, bufferSize);

并记录输出,它总是显示缓冲区中有一半似乎是有效的音频数据,但一半是零。

创建一个正常大小一半的缓冲区会引发错误,所以我知道它实际上是在存储零。这不仅仅是缓冲区大小的一些奇怪之处。我在这里做明显错误的事情吗?请记住,这是我的第一个 Android 应用程序,尽管我对 Java 非常熟悉。

4

3 回答 3

3

我遇到了同样的问题,我认为是因为:

  • getMinBufferSize 返回大小(以字节为单位)
  • AudioRecord 构造函数接受以字节为单位的大小。

  • 读取功能重载,可以接受字节和短路。您的 audioData 变量很短,因此它也期望缓冲区大小也很短,唯一的问题是您现在以字节为单位指定缓冲区大小,因此实际上指定的缓冲区大小是两倍大!(短 = 2x 字节)

我所做的是在读取函数中将缓冲区大小除以 2。它似乎在这里解决了它,但我必须更好地测试它。

希望这可以帮助 ;)

干杯,

马塞尔

于 2012-12-03T22:47:08.537 回答
2

我实际上认为我可能已经解决了这个问题。我之前使用 Windows WaveIn 在 C++ 中编写了这个,并且我使用了一个短的 int 数组作为缓冲区,所以我很自然地尝试在这里这样做。不过,在再次阅读文档后,看起来我需要一个 byte[] 数组。改了之后,好像可以了。不过谢谢大家的帮助!

于 2012-11-25T07:05:24.130 回答
0

文档AudioRecord.read似乎表明它返回读取的字节数。您似乎没有对 的返回值做任何事情AudioRecord.read,所以也许您只是在读取已用缓冲区的末尾。

如果要填充缓冲区,请更改AudioRecord.Read为:

int offset = 0, read = 1;
while (offset < bufferSize)
{
    read = recorder.read(audioData, offset, bufferSize);
    offset += read;
    if (read <= 0) break;
}
于 2012-11-25T02:20:24.277 回答