在FFT

时间:2018-01-10 16:55:01

标签: matlab signal-processing

我正在编写一个程序,可以直观地显示构成音频的频率。要做到这一点,我有一个滚动窗口,我执行FFT(我将在底部发布代码)。让我感兴趣的是我所有的地块都在0hz附近有一个高功率,在10khz附近有一个低功率: enter image description here enter image description here

我想更改图表,以便显示相对于与歌曲其余部分相同频率的功率而不是显示实际功率。例如,我希望它能使0hz的最大值与10khz的最大值相同。这意味着降低低频时的y值并在高频时提高y值。我将如何进行此操作并使图表看起来不是向下倾斜?

作为算法运行后的旁注,我将流式传输音频而不是从音频文件中读取音频,这样就可以消除在整首歌曲中保持每个频率的平均值的可能性。

% Prototype to graph moving window of FFT through an audio file in real time
clear all;
warning('off','MATLAB:colon:nonIntegerIndex'); % Suppress integer operand errors because it's ok to round for the window size

% Read Audio
fs = 44100;         % sample frequency (Hz)
full = audioread('O.mp3');

% Remove leading 0's and select range
for i = 1:fs
    if full(i) ~= 0
        crop = i;
        break
    end
end
full = full(crop:end);

startTime = 0;
endTime = length(full)/fs;

% Play song
tic
player = audioplayer(full(fs*startTime+1:fs*endTime), fs);
player.play();
initialTime = toc;

% Perform fft and get frequencies (hopefully in realish time with audio)
windowSize = fs/8;
for i = windowSize/2+1+fs*startTime : fs/16 : fs*endTime
    beginningChunk = round(i-windowSize/2);
    endChunk = round(i+windowSize/2);

    x = full(beginningChunk:endChunk);
    y = fft(x);
    n = length(x);          % number of samples in chunk
    power = abs(y).^2/n;    % power of the DFT
    power = power(1:end/2);
    f = (0:n-1)*(fs/n);     % frequency range
    f = f(1:end/2);
    while initialTime+i/fs > toc
        pause(.0001);
    end
    figure(1);
    plot(f,power);
    axis([0 10000 0 5]);
    xlabel('Frequency');
    ylabel('Power');
end

1 个答案:

答案 0 :(得分:3)

将权力表示为z得分

为基线准备[t,f]个样本

winrange = windowSize/2+1+fs*startTime : fs/16 : fs*endTime;
for i = winrange
   ...
   % base_pow is [# of time bins,# freq bins] 
   base_pow(i == winrange,:) = power(1:end/2);
   ...
end

按基准数据标准化每个样本

for i = winrange
   ...
   raw_pow = power(1:end/2);
   % collapse across 1st dimension of base_pow
   norm_pow = (raw_pow - mean(base_pow,1))./std(base_pow,[],1)
   ...
end

信号流

上述解决方案要求您使用完整的样本。一种计算效率更高的方法是在流式传输任何样本之前将某些函数拟合到多个音轨,并使用该曲线进行标准化。