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일
1 개 추천
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!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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)
