我正在编写一个需要听麦克风并为我提供实时幅度和音高输出的应用程序。我已经弄清楚如何进行音高识别。我一直在对fft进行大量研究。发现 Android 库 TarsosDSP 使得监听音高变得非常简单:
AudioDispatcher dispatcher =
AudioDispatcherFactory.fromDefaultMicrophone(22050,1024,0);
PitchDetectionHandler pdh = new PitchDetectionHandler() {
@Override
public void handlePitch(PitchDetectionResult res, AudioEvent e){
final float pitchInHz = res.getPitch();
runOnUiThread(new Runnable() {
@Override
public void run() {
processPitch(pitchInHz);
}
});
}
};
AudioProcessor pitchProcessor = new PitchProcessor(PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, pdh);
dispatcher.addAudioProcessor(pitchProcessor);
Thread audioThread = new Thread(dispatcher, "Audio Thread");
audioThread.start();
我还想出了如何通过使用内置的 android .getMaxAmplitude() 方法来进行幅度检测。
但我的问题是,我一生都无法弄清楚如何同时做到这两点。问题是您显然可以运行多个麦克风实例。就像您尝试在单独的线程上运行两个单独的实时录制一样。我已经浏览了整个互联网,试图寻找一些示例代码来让我继续前进,但我找不到任何东西。有没有人不得不做类似的事情?
编辑 我发现您可以使用 Pitchdetectionhandler 中的 AudioEvent。audioevent.getbytebuffer() 根据文档返回一个字节数组,其中包含以字节为单位的音频数据:https ://0110.be/releases/TarsosDSP/TarsosDSP-latest/TarsosDSP-latest-Documentation/ 。
如果我在转换为短 [] 时没有弄错,那么最大值就是最高幅度,对吗?
但:
final byte[] audioBytes = e.getByteBuffer();
short[] shortArray = new short[audioBytes.length];
for (int index = 0; index < audioBytes.length; index++) {
shortArray[index] = (short) audioBytes[index];
float item = shortArray[index];
if (item > amp){
amp = item;
}
}
在这种情况下,amp 总是返回 127。而且这种方法不会真的在现场工作吗?
还有三个问题。我的基本想法是对的,如果是这样,为什么它总是返回 127,我将如何在实时环境中使用它。