EQ from measurement-data
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
0 投票
I have a set of data from a measurement [frequency, relative gain] stored in an excel-table. Now i want to use those values to build an EQ or otherwise somehow substract the values from mulitble audio-files.
Since the parametric EQ is limited to 10 bands and the graphic EQ has fixed frequency-bands, is there any chance doing this using the AudioToolbox?
Talking about a table of around 4000 frequencies with corresponding gain-values. Audio files are IRs of length under 1 second.
I'm thankful for any advice.
採用された回答
Mathieu NOE
2021 年 12 月 2 日
hello
maybe you should share the data file (measurements) and code if you have already started one
once we have created the bank of filters we can use them to EQ the signal
for info, this code was for generating a bannk of 23 bandpass filters from 100 to 8,000 Hz center frequencies
%% INitializing Matlab Environment
close all;
clc;
clearvars;
b=log10(8000);%stop frequency and 100Hz is the pass frequency
yc1=logspace(2,b,23);
yd=stem(yc1);
grid on
xlabel('Borders','FontSize',12);
ylabel('F (Hz)','FontSize',12);
set(gca,'YScale', 'log')
%%
fs=44.1e3; %sampling frequency
figure(2)
hold on
for i= 1:1:23
BW = yc1(i)/5; % BW should be proportionnal to center frequencies (not fixed)
f_low = yc1(i) - BW/2;
f_high = yc1(i) + BW/2;
[B,A] = butter(1,[f_low, f_high]*2/fs,'bandpass');
freq = logspace(log10(f_low/4),log10(f_high*4),200);
[h]=freqz(B,A,freq,fs);
semilogx(freq,20*log10(abs(h)));
end
hold off
set(gca,'XLim',[0 fs/2.56],'XTick',10.^(0:4),'YLim',[-12 0],'YTick',-12:2:0,'XScale', 'log')
6 件のコメント
Anton Hoyer
2021 年 12 月 8 日
Thanks for your answer, your code helps quite a bit to understand how it could be done.
Based on that, i came up with the following code to create the bandpass-filters from the table (attached).
Meas = readtable('Example_Table.xlsx'); % header: frequency amplitude
L = height(Meas); % number of frequencies from measurement
fs=44100;
figure(1)
hold on
for i=1:1:L
if i<L
BW = Meas.Frequency(i+1)-Meas.Frequency(i); % bandwidth = distance to next frequency
else
BW = Meas.Frequency(i)-Meas.Frequency(i-1);
end
f_low = Meas.Frequency(i) - BW/2;
f_high = Meas.Frequency(i) + BW/2;
[B,A] = butter(1,[f_low, f_high]*2/fs, 'bandpass');
freq = logspace(log10(f_low/4),log10(f_high*4),200);
[h]=freqz(B,A,freq,fs);
semilogx(freq,20*log(abs(h)));
end
hold off
set(gca,'XLim',[0 1000],'XTick',10.^(0:4),'YLim',[-5 5],'YTick',-5:1:5,'XScale', 'lin');
Now i probably need to assign the measurement-values to the frequency-bands, right? Not sure how to do that.
I also came across the fir2, which seemed to also work, but the resulting values weren't right. That's what i tried, but there must be a logical misunterstanding according to the results.
close all;
clc;
clearvars;
fs = 44100;
fny = fs/2;
Meas = readtable('Example_Table.xlsx');
freq = [0;Meas.Frequency;fny];
amp = [0;Meas.Amplitude;0];
L = length(freq);
fn = freq/fny;
figure(1)
b = fir2(1,fn,amp);
[freq_response, fc] = freqz(b,1,L,fs);
dB = 20*log10(abs(freq_response));
semilogx(fc, dB);
Mathieu NOE
2021 年 12 月 8 日
hello again
had to shake my head a bit beacuse equalizing is not what I am doing regurlarly and some points had to be addressed again
one point we didn't really checked here is that a bank ok bandpass filters should be designed so that when all knobs are on the "0" position (no attenuation and no gain) the sum of all filters should be as close as possible to "no filter" gain (0 dB flat curve)
that's why the equalizers are build with specific center frequencies (log spaced to form the octave or 1/3 octave or even 1/24th octave scale) . that must be defined somewhere in a ISO standard
now your table of frequencies is not log scaledand donot follow the equalizer filters design rules , so when we o the sum of all filters (see thick black line) we don't get a flat 0 dB line , but an ascending trend as the "density" of filters goes up with frequency (when we look at the graph in log x )
so that should be corrected first before doing any further work

clc
clearvars
close all
Meas = readtable('Example_Table.xlsx'); % header: frequency amplitude
Center_freqs = Meas.Frequency;
L = numel(Center_freqs);
fs=44100;
figure(1)
freq = logspace(1.5,3.4,1000);
for ci=1:L
if ci<L
BW = Center_freqs(ci+1)-Center_freqs(ci); % bandwidth = distance to next frequency
else
BW = Center_freqs(ci)-Center_freqs(ci-1);
end
f_low = (-BW+sqrt(BW^2+4*Center_freqs(ci)^2))/2;
f_high = f_low + BW;
[B,A] = butter(1,[f_low f_high]*2/fs, 'bandpass');
[h]=freqz(B,A,freq,fs);
h_all(ci,:) = h; % same phase (positive) gain
% h_all(ci,:) = h*(-1)^ci; % alternate pos / neg gain for specific order filters
end
% sum of all filters responses should give flat or target amplitude curve
hh = sum(h_all);
semilogx(freq,20*log(abs(h_all)),freq,20*log(abs(hh)),'k','linewidth',5);
Mathieu NOE
2021 年 12 月 8 日
see this other example built on available equalizer (4th order filters)
the sum is quit close to flat 0 dB

clc
clearvars
close all
Center_freqs = [63 250 1000 4000];
f1 = [33.21 131.79 527.15 2108.6] % 0.5271 * Center_freqs
f2 = [119.51 474.25 1897.0 7588.0]; % 1.8970 * Center_freqs
L = numel(Center_freqs);
fs=44100;
figure(1)
freq = logspace(1.5,4.2,1000);
for ci=1:L
f_low = 0.5271*Center_freqs(ci);
f_high = 1.8970*Center_freqs(ci);
[B,A] = butter(4,[f_low f_high]*2/fs, 'bandpass');
[h]=freqz(B,A,freq,fs);
h_all(ci,:) = h; % same phase (pos) gain for even order filters
% h_all(ci,:) = h*(-1)^ci; % alternate pos / neg gain for odd order filters
end
% sum of all filters responses should give flat or target amplitude curve
hh = sum(h_all);
semilogx(freq,20*log(abs(h_all)),freq,20*log(abs(hh)),'k','linewidth',5);
Mathieu NOE
2021 年 12 月 9 日
hello again
In the mean time I looked at FIR realisation and that's the best result I could get (in my limited time) with a 300 taps long FIR filter. Maybe easier that the bank of bandpass filters solution in this case
I extended the frequency range below (down to 1 Hz) and above your data (up to 20 kHz) to make sure the filter would stay close to 0 dB gain outside your specified amplitude corrections.
Now you simply have to use this FIR filter with filter or filtfilt to apply to your audio files

clc
clearvars
Meas = readtable('Example_Table.xlsx'); % header: frequency amplitude
freqs = [1; 50; Meas.Frequency];
freqs2 = (max(freqs)+50:50:20000)';
freqs = [freqs;freqs2];
Correction_dB= [0;0;Meas.Amplitude;zeros(length(freqs2),1)];
H = 10.^(Correction_dB/20);
L = numel(freqs);
fs=44100;
ITER = 1e4;
% FIR filter design
NB = 300; % min around 128
NA = 0;
W = 2*pi*freqs/fs;
Wt = ones(size(W));
TOL = 1e-2;
[B,A] = invfreqz(H,W,NB,NA,Wt,ITER,TOL);
hverif = freqz(B,A,freqs,fs);
figure(1)
semilogx(freqs,Correction_dB,'b',freqs,20*log(abs(hverif)),'r');
legend('spec','FIR realisation');
xlabel('Frequency (Hz)');
ylabel('modulus (dB)');
Anton Hoyer
2021 年 12 月 9 日
Tanks a lot, that's what i was looking for! Already tried it with some measurement data & audiofiles and it works.
Mathieu NOE
2021 年 12 月 9 日
Good news ! glad it worked out !
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Filter Analysis についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
