Android,实时幅度和音调检测

时间:2019-05-16 13:57:31

标签: java android audio tarsosdsp

我正在编写一个需要收听麦克风并为我提供实时振幅和音调输出的应用程序。我已经弄清楚了如何进行音高识别。我对fft进行了大量研究。发现Android库TarsosDSP wich使监听音调变得非常简单:

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。 根据文档https://0110.be/releases/TarsosDSP/TarsosDSP-latest/TarsosDSP-latest-Documentation/,audioevent.getbytebuffer()返回一个字节数组,其中音频数据以字节为单位。

如果转换为short []时我没记错的话,那么最高的值就是最高的幅度吧?

但是:

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;
                                    }
                                }

在这种情况下,放大器始终返回127。无论如何,这种方法真的无法正常工作吗?

还有三个问题。我的基本想法是正确的,如果是这样,为什么它总是返回127,以及如何在实时环境中使用它。

1 个答案:

答案 0 :(得分:0)

自己找到解决方案。您可以执行audioEvent.getFloatBuffer(),然后通过某些fft方法运行该缓冲区,然后可以从缓冲区中提取振幅值。缓冲区很小,所以我最终在运行时从该缓冲区中获得了最大振幅,这将使您每秒多次读取振幅,这对我来说足够活了。