gpt4 book ai didi

java - Android,实时振幅和音调检测

转载 作者:太空宇宙 更新时间:2023-11-04 09:39:08 25 4
gpt4 key购买 nike

我正在编写一个应用程序,需要监听麦克风并为我提供实时幅度和音调输出。我已经弄清楚如何进行音高识别。我对 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() 方法进行幅度检测。

但我的问题是我一生都无法弄清楚如何同时做到这两点。问题是您显然可以运行多个麦克风实例。就像您尝试在不同的线程上运行两个单独的现场录音一样。我浏览了整个互联网,试图寻找一些示例代码来帮助我继续下去,但我什么也找不到。有人曾经做过类似的事情吗?

编辑我发现您可以使用音调检测处理程序中的音频事件。根据文档,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,以及我将如何在实时上下文中使用它?

  1. 列出项目

最佳答案

我自己找到了解决方案。您可以执行 audioEvent.getFloatBuffer() 然后通过一些 fft 方法运行该缓冲区,然后您可以从缓冲区中提取幅度值。缓冲区非常小,所以我最终在运行时从该缓冲区获取了最大幅度,这将使您每秒多次读取幅度读数,这对我来说已经足够了。编辑示例:

 public void handlePitch(PitchDetectionResult result, final AudioEvent e) {

final float pitchInHz = result.getPitch();
final float[] amplitudes = new float[e.getBufferSize()];

new Thread(new Runnable() {
public void run() {
if (pitchInHz > pitch) {
pitch = pitchInHz;
}

float[] audioFloatBuffer = e.getFloatBuffer();
float[] transformBuffer = new float[e.getBufferSize() * 2];
FFT fft = new FFT(e.getBufferSize());
System.arraycopy(audioFloatBuffer, 0, transformBuffer, 0, audioFloatBuffer.length);
fft.forwardTransform(transformBuffer);
fft.modulus(transformBuffer, amplitudes);


for (int index = 0; index < amplitudes.length; index++) {
if (amplitudes[index] > amp) {
amp = amplitudes[index];
}
}
}
}).start();
}

关于java - Android,实时振幅和音调检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56170296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com