【问题标题】:How to get an amplitude of certain frequency audio signal realtime android如何实时获取特定频率音频信号的幅度android
【发布时间】:2017-02-11 23:03:36
【问题描述】:

我正在开发 lumiere 应用程序。我有一个特定频率的载波信号(更准确地说是 19.2 kHz),我需要在播放音频时获取它的幅度。 我在 Google 上搜索了一些有关音频处理的信息,发现为了获得频谱,您必须使用 FFT 算法。

我已经尝试过 TarsosDSP 库及其 FFT 类。

TarsosDSPAudioFormat format = new TarsosDSPAudioFormat((float) SAMPLE_RATE, 16, 1, true, false);
TarsosDSPAudioFloatConverter converter = TarsosDSPAudioFloatConverter.getConverter(format);

float[] buff = new float[bufferFloatSize];
final float[] amps = new float[fftSize];

converter.toFloatArray(tmpBuffer, buff);

FFT fft = new FFT(bufferFloatSize, new HannWindow());
fft.forwardTransform(buff);
fft.modulus(buff, amps);

然后我得到频带索引并计算它的幅度

int amp = (int) (10 * Math.log10(amps[index]);

但是我得到错误的幅度。 我有一个 19.2kHz 信号的音频文件,其振幅恒定为 0 dB,但 19207 Hz 振幅的结果值在 -39 dB 到 -46 dB 之间变化。我检查了相邻的频率,可能其中一些有 0 dB,但没有。 我还检查了 -36 dB 和 -60 dB 的文件,但结果分别为 -39 到 -48 dB 和 -44 到 - 61 dB。

我们可以看到最后一个文件很接近,但它不是恒定的,我无法预测它什么时候是对的,什么时候是错的。

如果有人遇到这个问题,请帮助我。 如果您知道任何其他确定可行的好的 FFT 库 - 请告诉我

更新: 好的,我已经添加了 TSG 的函数并在我的 fft.forwardTransform() 之前和之后调用它来比较结果; 结果是: 对于 0 dB 19.2kHz 音频文件: 之前:-39 分贝 之后 - 10 分贝

对于 -36 dB 19.2kHz 音频文件: 之前:-75 分贝 之后:-46 分贝

对于 -60 dB 19.2kHz 音频文件: 之前:-97.7 分贝 之后:-69 分贝

现在结果是恒定的,不会随着时间或尝试而改变。 我们还可以看到结果中存在一定的模式。在 fft 之前,结果与正确的结果不同,为 -39 dBs,之后为 -10dBs。 所以问题是:为什么我们会犯这些错误?

【问题讨论】:

    标签: java android audio fft tarsosdsp


    【解决方案1】:
        In the TarsosDSP manual , the following example was given sound pressure level in db  where  ,
    
     db=audioEvent.getdBSPL(); or Amplitude=audioEvent.getRMS() //root mean square of the signal.
    
    
    
        float[] buffer = audioEvent.getFloatBuffer();
    
    
    
        private double soundPressureLevel(final float[] buffer) {
        double power = 0.0D;
        for (float element : buffer) {
        power += element*element;
        }
    
        double value = Math.pow(power, 0.5)/ buffer.length;;
        return 20.0*Math.log10(value);
        }
        });
    

    【讨论】:

    • 请您解释一下,为什么要在 20.0*Math.log10(value); 中乘以 20;因为我见过同样的表达式乘以十:10 * Math.log10(value);
    • 函数在 0 dB 19.2kHz 音频文件上的结果在调用 FFT 之前为 -39 dB,在调用 FFT 之后为 -10 dB。 Log.d("test", "在功率电平之前:" + soundPressureLevel(buff) + " dB"); fft.forwardTransform(buff); fft.modulus(buff,amps); Log.d("test", "经过功率电平:" + soundPressureLevel(buff) + " dB");
    • 我还检查了所有三个文件始终具有相同的结果,更好的是,因为我们有恒定的值(没有像以前那样的变化)并且正确结果和错误之间的差异大约是39 dBs(fft 之前的结果)。就像它应该是 0 dB 并且是 -39 dB,应该是 -36 dB 并且是 -75 dB,应该是 -60 dB 并且是 -98 dB。
    • 据我所知 TarsosDSp 使用的 FFT 是 JTransforms。
    • TarsosDSP 手册中的公式,audioEvent.getdBSPL() 调用完全匹配通常称为声压级的声压函数表现。 SPL=20Log10(P(rms) /P0) 其中 P0 是一个常数 = 2e-5。 ,P 是您的公式应用的声压波动 rms,称为 PWL 或声功率级,单位也是 dB。两者其实是一样的,都是以一个共同的基准为基准的相对测量,在功率的情况下,基准是强度等级10E-12 W/M2,强度=P sq (rms)除以pc(密度x声速)大气条件下空气的 pc 常数=4e2 kg/m2s
    猜你喜欢
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多