当前位置: 首页 > 知识库问答 >
问题:

Android,实时振幅和音高检测

乌俊健
2023-03-14

我正在编写一个应用程序,它需要监听麦克风并给我一个实时的振幅和音调输出。我已经找到了如何进行音高识别的方法。我对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进行振幅检测。GetMaxAmplific()方法。

但我的问题是,我一辈子都不知道如何同时做这两件事。问题是你显然可以运行多个麦克风实例。就像你试图在不同的线程上运行两个单独的现场录音一样。我在整个互联网上寻找一些示例代码来让我继续前进,但我找不到任何东西。有人必须做类似的事情吗?

编辑我发现您可以使用Pitchdetectionhandler中的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个答案

丁震博
2023-03-14

我自己找到了解决方案。您可以执行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();
                    }
 类似资料:
  • 问题内容: 我目前正在尝试使用Android实现一些代码,以检测何时通过手机的麦克风播放了多个特定音频频率范围。我已经使用AudioRecord该类设置了该类: 然后读取音频: 执行FFT是我遇到的困难,因为我在这方面的经验很少。我一直在尝试使用此类: Java和Complex类中的FFT一起使用 然后,我发送以下值: 这很容易让我误解了此类的工作原理,但是返回的值到处都是跳跃的,即使在沉默中也不

  • 问题内容: 我正在将adMob横幅成功添加到我的应用中。出现横幅时,我需要获取其高度以调整所有布局元素的大小。我正在使用正确触发的事件onReceivedAd。但是,alturaBanner =0。那么,如何获取其高度?谢谢。 问题答案: 在准备视图之前获取视图的高度将始终返回0。无论您使用哪种设备/屏幕,都使用下一个代码来获取正确的大小: 在给定的runnable内部,您可以查询视图的实际大小。

  • 我读过两篇文章,内容是从AudioInputStream中提取样本并将其转换为dB。 https://stackoverflow.com/a/26576548/8428414 https://stackoverflow.com/a/26824664/8428414 据我所知,

  • 我面临的问题,使用MediaPlayer以及原生Android音频播放器播放音频网址。这是我的网址http://live.politiafm.com:8500/politiafm.mp3 这是我的代码使用本机音频播放器Intent意图=new Intent(android.content.Intent。ACTION_VIEW);intent.setDataAndType(Uri.parse(STR

  • 如何删除Flutter中的调试横幅? 我正在使用,我希望屏幕截图上没有横幅。现在确实有了。 注意,emulator不支持配置文件和发布模式的

  • 本文向大家介绍Android中通知Notification使用实例(振动、灯光、声音),包括了Android中通知Notification使用实例(振动、灯光、声音)的使用技巧和注意事项,需要的朋友参考一下 本文实例讲解了通知Notification使用方法,此知识点就是用作通知的显示,包括振动、灯光、声音等效果,分享给大家供大家参考,具体内容如下 效果图: MainActivity: activ