音频频谱分析

音频的分析离不开从时域转化为频域的过程,这一过程最直接相关的就是快速傅里叶变化DFT。 DFT 和他的逆变化有很多开源库,网上也有很多就不介绍,我这边使用的是Java jtransforms:代码如下:


```c
 public  double[] calculateSpectrumDBFS(short[] audioData) {
        int n = audioData.length/2;
        double[] fftData = new double[n * 2]; // FFT类需要双倍长度,实部+虚部
        // 复制音频数据到FFT数据数组的实部,虚部设为0
        for (int i = 0; i < n; i++) {
            fftData[2 * i] = audioData[i*2];
            fftData[2 * i + 1] = 0;
        }

        // 执行FFT
        DoubleFFT_1D fft = new DoubleFFT_1D(n);
        fft.complexForward(fftData);

        // 计算每个频率分量的幅度和dBFS
        double[] spectrumDBFS = new double[n / 2];
        double ref = Math.pow(2, 15); // 16位PCM的最大值作为参考
        for (int i = 0; i < n / 4; i++) {
            double re = fftData[2 * i];
            double im = fftData[2 * i + 1];
            double magnitude = Math.sqrt(re * re + im * im);
            double magreal = magnitude/(double) (n/2);
            double dbfs = 20 * Math.log10(magreal / ref);
            if(dbfs > -50)
                Log.e(TAG, "ffff  HZ  =  " + i * 48000 / (n) +"    FftMediaFuncion:  dbfs  " + dbfs + "  模 " + magnitude );
            spectrumDBFS[i] = dbfs;
        }

        return spectrumDBFS;
    }
}

其中dbfs 简单的介绍一下:
dbfs 就是数字音频分贝的表示方法,计算公式 dbfs = 20log10(sample/2^15): sample 表示当前采样点样值,2^15 表示位深, 位深除了16bit 之外还有24bit 等。 位深: 表示一个采样点使用多少个bit 位来表示他的值,所以位深越大表示的频点精度也就越高,音质也就越好。目前移动设备包括车载软件一般都还是使用16bit 播放音频,少部分使用24bit 播放,这涉及到编解码以及硬件的传输能力,是个小课题。
傅里叶变化之后的返回值:
假设采样率位FS 采样点为N
傅里叶变换之后的返回值是一个复数,除了直流分量之外,复数的模的N/2就是当前所需频段的幅值。
频点的计算方法: fs = i
FS/N 其中i代表第几个采样点,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值