読み込んだ複数のオー​ディオファイルのFF​Tパワーを同じにした​い。

15 views (last 30 days)
tazaki ush
tazaki ush on 10 Jan 2023
Edited: Hernia Baby on 15 Jan 2023
MATLABで20sのノイズ(複数)を読み込んで、それぞれ大きさ(FFTのパワー)が等しくないものを均一にしたいと思っています。
ノイズはモノラル・サンプルレート48kHz・20秒のものが7種あり、それぞれ周波数特性などが異なるものです。
パワーの調整はゲイン(音量)の調整で構いません。
方法として、公式からも提案されているパワーの計算をし、ゲインの調整を別で合わせることでやっていく方法を考えましたが、調整に途方に暮れてしまっています。
filename='noise.wav';
filename2='noise2.wav';
[x1,fs]=audioread(filename);
[x2,fs]=audioread(filename2); %以下同様なので省略。
y1=fft(x1,length(x1));
P1=abs(y1).^2; %fftパワー
Psum1=sum(P1(1:n,1)); %総和が等しくなるように調整...... しかし上手くいかない。時間がかかる。
いい方法がありましたらご教示いただけますと幸いです。調べてもわからず...

Answers (1)

Hernia Baby
Hernia Baby on 15 Jan 2023
Edited: Hernia Baby on 15 Jan 2023
パワーの正規化が必要だと考えられます。
単にFFTして2乗にしただけでは意味をなしません。
ですのでブロックサイズで割って2倍する必要があります。
dt = 0.01; % 時間分解能
L = 512; % ブロックサイズ
t = 0:dt:dt*(L-1); % 時間
Fs = 1/dt; % サンプリング周波数
y = .5*sin(2*pi*10*t) + 2*sin(2*pi*30*t); % 波形
plot(t,y,'Color',[.3 .3 .3])
xlim([0 t(end)])
xlabel '時間[sec]'
ylabel '信号'
これをFFTしてパワー値にします
plot(abs(fft(y)).^2,'Color',[.3 .3 .3])
xlim([0 L])
xline(L/2,':')
パーシバルの定理は入力信号の振幅二乗和とパワースペクトルの平均が一致するというようなものです。
式は  で表されます。
つまりブロックサイズで割ってあげる必要があります。
また折り返しの部分も足す必要があります。ですので2倍にします。
横軸は以下の通りです。
f = Fs*(0:ceil(L/2)-1)/L;
縦軸配下の通りです。
P = abs(fft(y)).^2;
P = P(1:ceil(L/2))./ceil(L/2); % 片側スペクトル
plot(f,P,'Color',[.3 .3 .3])
xlabel '周波数[Hz]'
ylabel '片側スペクトル'
詳しくは手前味噌ですがこちらご覧ください。
■懸念点
ここからは余談なのですが、
音なのでdBで表すと思うのですが、パワー値のままでいいのでしょうか?

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!