├── ANC_1.m ├── ANC_2.m ├── ANC_3.m ├── ANC_4.m ├── ANC_6.m ├── ANC_7.m ├── ANC_Final Report_Final Submission_u5491523_Guofeng Xu.pdf ├── LICENSE ├── README.md ├── TRY_FB~1.M ├── adaptfilt_filtxlms.m ├── anc_5.m ├── feedback928.m ├── fxlms_me.m ├── fxlms_time_domain.m ├── power ratio dB interval 100.fig ├── power ratio dB interval100 10000times u =0.1.fig ├── power ratio dB interval100 10000times u =0.2.fig ├── power ratio dB with background noise 0.1 1000times u =0.1.fig ├── power ratio dB with background noise 0.1 1000times u =0.3.fig ├── power ratio dB withbackground noise 0.3 1000times u 0.1 0.1.fig ├── power ratio dB withbackground noise 0.5 1000times u 0.1 0.1.fig ├── secondary path 16 to end power ratio dB with background noise 0.1 1000times u =0.1.fig ├── slicing_fxlms.m ├── slicingby8.m ├── trial1018dB.m ├── try_fblms.m └── without_secondary_estimate.m /ANC_1.m: -------------------------------------------------------------------------------- 1 | Fs = 8e3; % 8 kHz 2 | N = 800; % 800 samples@8 kHz = 0.1 seconds 3 | Flow = 160; % Lower band-edge: 160 Hz 4 | Fhigh = 2000; % Upper band-edge: 2000 Hz 5 | delayS = 7; 6 | Ast = 20; % 20 dB stopband attenuation 7 | Nfilt = 8; % Filter order 8 | 9 | % Design bandpass filter to generate bandlimited impulse response 10 | Fd = fdesign.bandpass('N,Fst1,Fst2,Ast',Nfilt,Flow,Fhigh,Ast,Fs); 11 | Hd = design(Fd,'cheby2','FilterStructure','df2tsos',... 12 | 'SystemObject',true); 13 | 14 | % Filter noise to generate impulse response 15 | H = step(Hd,[zeros(delayS,1); log(0.99*rand(N-delayS,1)+0.01).* ... 16 | sign(randn(N-delayS,1)).*exp(-0.01*(1:N-delayS)')]); 17 | H = H/norm(H); 18 | 19 | t = (1:N)/Fs; 20 | plot(t,H,'b'); 21 | xlabel('Time [sec]'); 22 | ylabel('Coefficient value'); 23 | title('True Secondary Path Impulse Response'); -------------------------------------------------------------------------------- /ANC_2.m: -------------------------------------------------------------------------------- 1 | ntrS = 30000; 2 | s = randn(ntrS,1); % Synthetic random signal to be played 3 | Hfir = dsp.FIRFilter('Numerator',H.'); 4 | dS = step(Hfir,s) + ... % random signal propagated through secondary path 5 | 0.01*randn(ntrS,1); % measurement noise at the microphone 6 | -------------------------------------------------------------------------------- /ANC_3.m: -------------------------------------------------------------------------------- 1 | M = 250; 2 | muS = 0.1; 3 | hNLMS = dsp.LMSFilter('Method','Normalized LMS','StepSize', muS,... 4 | 'Length', M); 5 | [yS,eS,Hhat] = step(hNLMS,s,dS); 6 | 7 | n = 1:ntrS; 8 | plot(n,dS,n,yS,n,eS); 9 | xlabel('Number of iterations'); 10 | ylabel('Signal value'); 11 | title('Secondary Identification Using the NLMS Adaptive Filter'); 12 | legend('Desired Signal','Output Signal','Error Signal'); -------------------------------------------------------------------------------- /ANC_4.m: -------------------------------------------------------------------------------- 1 | plot(t,H,t(1:M),Hhat,t,[H(1:M)-Hhat(1:M); H(M+1:N)]); 2 | xlabel('Time [sec]'); 3 | ylabel('Coefficient value'); 4 | title('Secondary Path Impulse Response Estimation'); 5 | legend('True','Estimated','Error'); -------------------------------------------------------------------------------- /ANC_6.m: -------------------------------------------------------------------------------- 1 | % FIR Filter to be used to model primary propagation path 2 | Hfir = dsp.FIRFilter('Numerator',G.'); 3 | 4 | % Filtered-X LMS adaptive filter to control the noise 5 | L = 350; 6 | muW = 0.0001; 7 | Hfx = dsp.FilteredXLMSFilter('Length',L,'StepSize',muW,... 8 | 'SecondaryPathCoefficients',Hhat); 9 | 10 | % Sine wave generator to synthetically create the noise 11 | A = [.01 .01 .02 .2 .3 .4 .3 .2 .1 .07 .02 .01]; La = length(A); 12 | F0 = 60; k = 1:La; F = F0*k; 13 | phase = rand(1,La); % Random initial phase 14 | Hsin = dsp.SineWave('Amplitude',A,'Frequency',F,'PhaseOffset',phase,... 15 | 'SamplesPerFrame',512,'SampleRate',Fs); 16 | 17 | % Audio player to play noise before and after cancellation 18 | Hpa = audioDeviceWriter('SampleRate',Fs); 19 | 20 | % Spectrum analyzer to show original and attenuated noise 21 | Hsa = dsp.SpectrumAnalyzer('SampleRate',Fs,'OverlapPercent',80,... 22 | 'SpectralAverages',20,'PlotAsTwoSidedSpectrum',false,... 23 | 'ShowLegend',true, ... 24 | 'ChannelNames', {'Original noisy signal', 'Attenuated noise'}); -------------------------------------------------------------------------------- /ANC_7.m: -------------------------------------------------------------------------------- 1 | for m = 1:400 2 | s = step(Hsin); % Generate sine waves with random phase 3 | x = sum(s,2); % Generate synthetic noise by adding all sine waves 4 | d = step(Hfir,x) + ... % Propagate noise through primary path 5 | 0.1*randn(size(x)); % Add measurement noise 6 | if m <= 200 7 | % No noise control for first 200 iterations 8 | e = d; 9 | else 10 | % Enable active noise control after 200 iterations 11 | xhat = x + 0.1*randn(size(x)); 12 | [y,e] = step(Hfx,xhat,d); 13 | end 14 | step(Hpa,e); % Play noise signal 15 | step(Hsa,[d,e]); % Show spectrum of original (Channel 1) 16 | % and attenuated noise (Channel 2) 17 | end 18 | release(Hpa); % Release audio device 19 | release(Hsa); % Release spectrum analyzer -------------------------------------------------------------------------------- /ANC_Final Report_Final Submission_u5491523_Guofeng Xu.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/ANC_Final Report_Final Submission_u5491523_Guofeng Xu.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 jeremyxu177 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # active-noise-control -------------------------------------------------------------------------------- /TRY_FB~1.M: -------------------------------------------------------------------------------- 1 | %-------------------------------------------------------------------------- 2 | % I am very busy lately with my work so, regretfully, I have no choice 3 | % except to postpone my plan to write a new code for simulating a multi- 4 | % channel active noise control system. In the meantime, I compose one code 5 | % about feed-back active noise control system (FbLMS), which is somewhat 6 | % different to the feed-forward system (FxLMS) in method for obtaining 7 | % reference signal. FbLMS does not employ any reference sensor. Instead, it 8 | % uses linear predictor for generating reference signal. Thus, FbLMS is 9 | % suitable for reducing narrow-band noise. 10 | % 11 | % Here is the system block diagram. 12 | % 13 | % +-----------+ + 14 | % x(k) ------->| P(z) |--yp(k)----------------> sum --+---> e(k) 15 | % +-----------+ ^- | 16 | % | | 17 | % +-------------------------------+ | | 18 | % | | | | 19 | % | \ | ys(k) | 20 | % | +-----------+ | +-----------+ | | 21 | % | +--->| C(z) |--yw(k)-+->| S(z) |---+ | 22 | % | | +-----------+ +-----------+ | 23 | % | | \ | 24 | % | | \-----------------\ | 25 | % | | \ | 26 | % | | +-----------+ +-----------+ | 27 | % | +--->| Sh(z) |--xs(k)-+->| LMS |<------+ 28 | % | | +-----------+ +-----------+ | 29 | % | xh(z) | 30 | % | | + | 31 | % | +----------------------- sum <-------------------+ 32 | % | ^+ 33 | % | +-----------+ | 34 | % +--------->| Sh(z) |--------+ 35 | % +-----------+ 36 | % 37 | % Similar to the previous FxLMS code, I used FIR filter to model P(z), 38 | % C(z), S(z), and Sh(z). Imagine that the noise x(k) is propagating from 39 | % the source to the sensor, through the fluid medium P(z). The sensor 40 | % measures the arriving noise as yp(k). 41 | % 42 | % To reduce noise, we generate another 'noise' yw(k) using the controller 43 | % C(z). We hope that it destructively interferes x(k). It means that the 44 | % controller has to be a model of the propagation medium P(z). Least mean 45 | % square algorithm is applied to adjust the controller coefficient/weight. 46 | % 47 | % However, there is also fluid medium S(z) that stay between the actuator 48 | % and sensor. We called it the secondary propagation path. So, to make the 49 | % solusion right, we need to compensate the adjustment process using Sh(z), 50 | % which is an estimate of S(z). 51 | % 52 | % You can find many good information in "Active Noise Control Systems - 53 | % Algorithms and DSP Implementations," written by S. M. Kuo and 54 | % D. R. Morgan in 1996. 55 | % 56 | % Let's start the code :) 57 | % 58 | % Developed by Agustinus Oey 59 | % Center of Noise and Vibration Control (NoViC) 60 | % Department of Mechanical Engineering 61 | % Korea Advanced Institute of Science and Technology (KAIST) 62 | % Daejeon, South Korea 63 | %-------------------------------------------------------------------------- 64 | 65 | % Set simulation duration (normalized) 66 | clear 67 | T=1000; 68 | 69 | % We do not know P(z) and S(z) in reality. So we have to make dummy paths 70 | Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 71 | Sw=Pw*0.25; 72 | 73 | % Remember that the first task is to estimate S(z). So, we can generate a 74 | % white noise signal, 75 | x_iden=randn(1,T); 76 | 77 | % send it to the actuator, and measure it at the sensor position, 78 | y_iden=filter(Sw, 1, x_iden); 79 | 80 | % Then, start the identification process 81 | Shx=zeros(1,16); % the state of Sh(z) 82 | Shw=zeros(1,16); % the weight of Sh(z) 83 | e_iden=zeros(1,T); % data buffer for the identification error 84 | 85 | % and apply least mean square algorithm 86 | mu=0.1; % learning rate 87 | for k=1:T, % discrete time k 88 | Shx=[x_iden(k) Shx(1:15)]; % update the state 89 | Shy=sum(Shx.*Shw); % calculate output of Sh(z) 90 | e_iden(k)=y_iden(k)-Shy; % calculate error 91 | Shw=Shw+mu*e_iden(k)*Shx; % adjust the weight 92 | end 93 | 94 | % Lets check the result 95 | subplot(2,1,1) 96 | plot([1:T], e_iden) 97 | ylabel('Amplitude'); 98 | xlabel('Discrete time k'); 99 | legend('Identification error'); 100 | subplot(2,1,2) 101 | stem(Sw) 102 | hold on 103 | stem(Shw, 'r*') 104 | ylabel('Amplitude'); 105 | xlabel('Numbering of filter tap'); 106 | legend('Coefficients of S(z)', 'Coefficients of Sh(z)') 107 | 108 | 109 | % The second task is the active control itself. Again, we need to simulate 110 | % the actual condition. In practice, it should be an iterative process of 111 | % 'measure', 'control', and 'adjust'; sample by sample. Now, let's generate 112 | % a narrow-band noise: 113 | X=0.1*randn(1,T)+0.9*cos(2*pi*(1/5)*[0:T-1]); 114 | 115 | % and measure the arriving noise at the sensor position, 116 | Yd=filter(Pw, 1, X); 117 | 118 | % We do not have any reference signal because there is no reference sensor. 119 | % Instead, it has to be estimated. So, lets prepare an empty buffer 120 | Xh=zeros(size(X)); 121 | 122 | % Initiate the system, 123 | Cx=zeros(1,16); % the state of C(z) 124 | Cw=zeros(1,16); % the weight of C(z) 125 | Cyx=zeros(1,16); % the state for the estimate of control signal 126 | Sx=zeros(size(Sw)); % the state for the secondary path 127 | Xhx=zeros(1,16); % the state of the filtered x(k) 128 | e_cont=zeros(1,T); % data buffer for the control error 129 | 130 | % send the first sample of control signal, 131 | k=1; 132 | Cx=[Xh(k) Cx(1:15)]; % update the controller state 133 | Cy=sum(Cx.*Cw); % calculate the controller output 134 | Sx=[Cy Sx(1:length(Sx)-1)]; % propagate to secondary path 135 | e_cont(k)=Yd(k)-sum(Sx.*Sw);% measure the residue 136 | 137 | % and start the FbLMS algorithm 138 | mu=0.1; % learning rate 139 | for k=2:T, % discrete time k 140 | Cyx=[Cy Cyx(1:15)]; % update the state for control signal 141 | Xh(k)=e_cont(k-1)+sum(Cyx.*Shw); % estimate reference signal 142 | 143 | Cx=[Xh(k) Cx(1:15)]; % update the controller state 144 | Cy=sum(Cx.*Cw); % calculate the controller output 145 | Sx=[Cy Sx(1:length(Sx)-1)]; % propagate to secondary path 146 | e_cont(k)=Yd(k)-sum(Sx.*Sw); % measure the residue 147 | 148 | Shx=[Xh(k) Shx(1:15)]; % update the state of Sh(z) 149 | Xhx=[sum(Shx.*Shw) Xhx(1:15)]; % calculate the filtered x(k) 150 | Cw=Cw+mu*e_cont(k)*Xhx; % adjust the controller weight 151 | end 152 | 153 | % Report the result 154 | figure 155 | subplot(2,1,1) 156 | plot([1:T], e_cont) 157 | ylabel('Amplitude'); 158 | xlabel('Discrete time k'); 159 | legend('Noise residue') 160 | subplot(2,1,2) 161 | plot([1:T], Yd) 162 | hold on 163 | plot([1:T], Yd-e_cont, 'r:') 164 | ylabel('Amplitude'); 165 | xlabel('Discrete time k'); 166 | legend('Noise signal', 'Control signal') 167 | -------------------------------------------------------------------------------- /adaptfilt_filtxlms.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | Fs = 8000; 5 | N = 8000; 6 | x = randn(1,N); % Noise source 7 | g = fir1(47,0.4); % FIR primary path system model 8 | n = 0.1*randn(1,N); % Observation noise signal 9 | d = filter(g,1,x)+n; % Signal to be cancelled 10 | b = fir1(31,0.4); % FIR secondary path system model 11 | mu = 0.008; % Filtered-X LMS step size 12 | lms = dsp.FilteredXLMSFilter(32, 'StepSize', mu, 'LeakageFactor', ... 13 | 1, 'SecondaryPathCoefficients', b); 14 | [y,e] = step(lms,x,d); 15 | plot(1:N,d,1:N,y,1:N,e); 16 | title('Active Noise Control of a Random Noise Signal'); 17 | legend('Desired','Output','Error'); 18 | xlabel('Time Index'); ylabel('Signal Value'); grid on; 19 | hold on 20 | 21 | ratio = abs(e./d); 22 | dB = 20*log10(ratio); 23 | figure 24 | plot(1:N,dB,1:N,zeros(1,N)) 25 | -------------------------------------------------------------------------------- /anc_5.m: -------------------------------------------------------------------------------- 1 | delayW = 15; 2 | Flow = 200; % Lower band-edge: 200 Hz 3 | Fhigh = 800; % Upper band-edge: 800 Hz 4 | Ast = 20; % 20 dB stopband attenuation 5 | Nfilt = 10; % Filter order 6 | 7 | % Design bandpass filter to generate bandlimited impulse response 8 | Fd2 = fdesign.bandpass('N,Fst1,Fst2,Ast',Nfilt,Flow,Fhigh,Ast,Fs); 9 | Hd2 = design(Fd2,'cheby2','FilterStructure','df2tsos',... 10 | 'SystemObject',true); 11 | 12 | % Filter noise to generate impulse response 13 | G = step(Hd2,[zeros(delayW,1); log(0.99*rand(N-delayW,1)+0.01).*... 14 | sign(randn(N-delayW,1)).*exp(-0.01*(1:N-delayW)')]); 15 | G = G/norm(G); 16 | 17 | plot(t,G,'b'); 18 | xlabel('Time [sec]'); 19 | ylabel('Coefficient value'); 20 | title('Primary Path Impulse Response'); -------------------------------------------------------------------------------- /feedback928.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | T = 8000; %simulation duration 5 | 6 | % set primary path 7 | % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01]; 8 | % Pw = [0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01 0.3 0.5]; 9 | Pw=[0.9 -0.7 0.8 -0.48 0.5 -0.35 0.36 -0.32 0.3 -0.22 0.28 -0.2... 10 | 0.22 -0.15 0.2 -0.14 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01]; 11 | % secondary path 12 | % Sw=Pw(3:7)*0.25; 13 | % Sw=Pw(3:end)*0.25; 14 | Sw=Pw(13:end)*0.6; 15 | % Sw=Pw*0.25; 16 | %% secondary path estimation (offline modelling) 17 | x_iden = randn(1,T); % generate a white noise 18 | % send it to the error microphone, i.e. the identification error 19 | y_iden = filter(Sw,1,x_iden); 20 | % y_iden = conv(Sw,x_iden); 21 | 22 | %% offline modelling 23 | L = 16; %filter order, order should be sufficient to accurately model the response... 24 | %of the physical system. The larger, the better???? This value should be 25 | %larger than length(Pw) 26 | % L =30; % accuracy decreases 27 | % L = 20; 28 | S_hat_x = zeros(1,L); %define the reference signal vector of S(z)_hat 29 | S_hat_w = zeros(1,L); %define the coefficient vector of the S(z)_hat 30 | e_iden = zeros(1,L); %define the identification error in the estimation process of... 31 | % the seconday path 32 | 33 | % apply LMS algorithm 34 | % mu = 0.1; 35 | % mu = 0.05; % estimation accuracy decreases 36 | mu = 0.1; %also a very good value, performs better than 0.1 37 | for n = 1:T %time index 38 | S_hat_x = [x_iden(n) S_hat_x(1:L-1)]; %update the reference signal vector 39 | Shy = sum(S_hat_x.*S_hat_w); % calculate output of Secondary path estimate 40 | e_iden(n)=y_iden(n)-Shy; % calculate error 41 | S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x; % adjust the weight 42 | end 43 | 44 | %%plotting 45 | subplot(2,1,1) 46 | plot([1:T], e_iden) 47 | ylabel('Amplitude'); 48 | xlabel('Discrete time n'); 49 | legend('Identification error'); 50 | subplot(2,1,2) 51 | stem(Sw) 52 | hold on 53 | stem(S_hat_w, 'r*') 54 | ylabel('Amplitude'); 55 | xlabel('Numbering of filter tap'); 56 | legend('Coefficients of Secondary Path', 'Coefficients of Secondary Path Estimate') 57 | 58 | %% Then we can propagate the seconday path estimate into the entire system 59 | % X=cos(2*pi*(1/5)*[0:T-1]); %feedback can only deal with narrowband 60 | % X=0.9*cos(2*pi*(1/4)*[0:T-1]); 61 | %When the input is narrowband only, the performance is extremely better 62 | %than (narowband + broadband). 63 | X=0.03*randn(1,T)+0.9*cos(2*pi*(1/5)*[0:T-1]); 64 | % X=0.1*randn(1,T); 65 | d = filter(Pw,1,X); % desired signal (signal at the error microphone) 66 | 67 | % Since we do not have any reference signal, we first define a vector for 68 | % reference signal 69 | x_ref = zeros(size(X)); 70 | 71 | % Initialization of Active Noise Control 72 | Cx = zeros(1,L); %reference signal vector of W(z) 73 | Cw = zeros(1,L); %coefficient vector of W(z) 74 | Cyx = zeros(1,L); %adaptive filter output estimate??? 75 | Sx = zeros(size(Sw)); %??? 76 | e = zeros(1,T); %define error value 77 | X_s = zeros(1,L); %filtered X 78 | 79 | %% send the first sample of control signal 80 | n = 1; 81 | Cx = [x_ref(n) Cx(1:L-1)]; 82 | Cy = sum(Cx.*Cw); %adaptive filter output 83 | Sx = [Cy Sx(1:length(Sx)-1)]; 84 | e(n) = d(n) - sum(Sx.*Sw); 85 | %% 86 | mu = 0.15; 87 | for n = 2:T 88 | Cyx = [Cy Cyx(1:L-1)]; 89 | x_ref(n) = e(n-1) + sum(Cyx.*S_hat_w); 90 | 91 | Cx = [x_ref(n) Cx(1:L-1)]; 92 | Cy = sum(Cx.*Cw); 93 | Sx = [Cy Sx(1:length(Sx)-1)]; 94 | e(n) = d(n) - sum(Sx.*Sw); 95 | 96 | S_hat_x = [X(n) S_hat_x(1:L-1)]; %update the vector signal of secondary path estimate 97 | X_s = [sum(S_hat_x.*S_hat_w) X_s(1:L-1)]; %i.e. x' in the paper 98 | Cw = Cw + mu*e(n)*X_s; %update the coefficiet vector of adaptive filter 99 | end 100 | 101 | % %Plotting 102 | figure 103 | subplot(2,1,1) 104 | plot([1:T],e) 105 | ylabel('Amplitude'); 106 | xlabel('Discrete time n'); 107 | legend('Noise residual'); 108 | 109 | subplot(2,1,2) 110 | plot([1:T],d) 111 | hold on 112 | plot([1:T],d-e,'r:') %d-e right; y wrong ????; 113 | ylabel('Amplitude'); 114 | xlabel('Discrete time n'); 115 | legend('Noise signal','Control signal'); 116 | 117 | % ratio = abs(e./d); 118 | % dB = 20*log10(ratio); 119 | % figure 120 | % plot(1:T,dB,'.',1:T,zeros(1,T)) -------------------------------------------------------------------------------- /fxlms_me.m: -------------------------------------------------------------------------------- 1 | function result=fxlms_me(fs) 2 | % T = 1000; %simulation duration 3 | % fs=8000; 4 | t=0:1/fs:1; 5 | T=length(t)-1; 6 | % set primary path 7 | % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 8 | % Sw=Pw*0.25; 9 | % % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01]; 10 | % Pw = [0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01 0.3 0.5]; 11 | % % secondary path 12 | % % Sw=Pw(3:7)*0.25; 13 | % Sw=Pw(3:end)*0.25; 14 | 15 | % Pw=[0.9 -0.7 0.8 -0.48 0.5 -0.35 0.36 -0.32 0.3 -0.22 0.28 -0.2... 16 | % 0.22 -0.15 0.2 -0.14 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01 0.01 -0.01]; 17 | Pw=[0.9 -0.3 0.7 -0.28 0.5 -0.25 0.36 -0.22 0.3 -0.18 0.28 -0.15... 18 | 0.22 -0.1 0.2 -0.1 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01]; 19 | Sw=Pw(13:end)*0.6; 20 | %% secondary path estimation (offline modelling) 21 | x_iden = rand(1,T); % generate a white noise 22 | % send it to the error microphone, i.e. the identification error 23 | y_iden = filter(Sw,1,x_iden); 24 | % y_iden = conv(Sw,x_iden); 25 | 26 | %% offline modelling 27 | L = 16; %filter order, order should be sufficient to accurately model the response... 28 | %of the physical system. The larger, the better???? This value should be 29 | %larger than length(Pw) 30 | % L =30; % accuracy decreases 31 | % L = 20; 32 | S_hat_x = zeros(1,L); %define the reference signal vector of S(z)_hat 33 | S_hat_w = zeros(1,L); %define the coefficient vector of the S(z)_hat 34 | e_iden = zeros(1,L); %define the identification error in the estimation process of... 35 | % the seconday path 36 | 37 | % apply LMS algorithm 38 | % mu = 0.1; 39 | % mu = 0.05; % estimation accuracy decreases 40 | mu = 0.5; %also a very good value, performs better than 0.1 41 | for n = 1:T %time index 42 | S_hat_x = [x_iden(n) S_hat_x(1:L-1)]; %update the reference signal vector 43 | Shy = sum(S_hat_x.*S_hat_w); % calculate output of Secondary path estimate 44 | e_iden(n)=y_iden(n)-Shy; % calculate error 45 | S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x; % adjust the weight 46 | end 47 | 48 | %%plotting 49 | subplot(2,1,1) 50 | plot([1:T], e_iden) 51 | ylabel('Amplitude'); 52 | xlabel('Discrete time n'); 53 | legend('Identification error'); 54 | subplot(2,1,2) 55 | stem(Sw) 56 | hold on 57 | stem(S_hat_w, 'r*') 58 | ylabel('Amplitude'); 59 | xlabel('Numbering of filter tap'); 60 | legend('Coefficients of Secondary Path', 'Coefficients of Secondary Path Estimate') 61 | 62 | %% Then we can propagate the seconday path estimate into the entire system 63 | X = randn(1,T); % define the input noise(source signal) 64 | % X=0.9*cos(2*pi*(1/5)*[0:T-1]); 65 | n = 0.1*randn(1,T); % Observation noise signal 66 | d = filter(Pw,1,X); % desired signal (signal at the error microphone) 67 | % Initialization of Active Noise Control 68 | Cx = zeros(1,L); %reference signal vector of W(z) 69 | Cw = zeros(1,L); %coefficient vector of W(z) 70 | Sx = zeros(size(Sw)); %??? 71 | e = zeros(1,T); %define error value 72 | X_s = zeros(1,L); %filtered X 73 | 74 | %% Apply FXLMS 75 | mu = 0.1; 76 | for n = 1:T %time index 77 | Cx = [X(n) Cx(1:L-1)]; %update the reference signal vector 78 | Cy = sum(Cx.*Cw); %Adaptive filter output 79 | Sx = [Cy Sx(1:length(Sx)-1)]; %propagate to secondary path 80 | y = sum(Sx.*Sw); %output passing through secondary path, to the reference microphone 81 | e(n) = d(n) - y; %calculating the residual error 82 | S_hat_x = [X(n) S_hat_x(1:L-1)]; %update the vector signal of secondary path estimate 83 | X_s = [sum(S_hat_x.*S_hat_w) X_s(1:L-1)]; %i.e. x' in the paper 84 | Cw = Cw + mu*e(n)*X_s; %update the coefficiet vector of adaptive filter 85 | end 86 | %% Time domain plot 87 | %Plotting 88 | % figure 89 | % subplot(2,1,1) 90 | % plot([1:T],e) 91 | % ylabel('Amplitude'); 92 | % xlabel('Discrete time n'); 93 | % legend('Noise residual'); 94 | % 95 | % subplot(2,1,2) 96 | % plot([1:T],d) 97 | % hold on 98 | % plot([1:T],d-e,'r:') %d-e right; y wrong ????; 99 | % ylabel('Amplitude'); 100 | % xlabel('Discrete time n'); 101 | % legend('Noise signal','Control signal'); 102 | 103 | %% Timde domain dB 104 | % ratio = abs((e.^2)./(d.^2)); 105 | % dB = 20*log10(ratio); 106 | % % % figure 107 | % plot(1:length(dB),dB,1:length(dB),zeros(1,T)) 108 | % 109 | % % figure 110 | % F1=fft(X(0.75*T:T-1))./length(0.75*T:T-1); 111 | % df=(1/T)*fs; 112 | % f=df*(0:(T-1)); 113 | % % subplot(2,1,1) 114 | % % plot(f,abs(F1)) 115 | % % hold on 116 | % 117 | % F2=fft(e(0.75*T:T-1))./length(0.75*T:T-1); 118 | % df=(1/T)*fs; 119 | % f=df*(0:(T-1)); 120 | % % subplot(2,1,2) 121 | % % plot(f,abs(F2)) 122 | % % hold on 123 | % 124 | % % ratio = abs(F2./F1); 125 | % dB = 20*log10(ratio); 126 | % result=dB; 127 | % frequency domain 128 | F1=fft(X(0.75*T:T-1))./length(0.75*T:T-1); 129 | df=(1/T)*fs; 130 | f=df*(1:0.25*T); 131 | F2=fft(e(0.75*T:T-1))./length(0.75*T:T-1); 132 | df=(1/T)*fs; 133 | f=df*(1:0.25*T); 134 | ratio = abs(F2./F1); 135 | dB = 20*log10(ratio); 136 | result = dB; 137 | % plot(1:length(dB),dB,1:length(dB),zeros(1,T)) 138 | % F1=fft(X)./T; 139 | % df=(1/T)*fs; 140 | % f=df*(0:(T-1)); 141 | % % subplot(2,1,1) 142 | % % plot(f,abs(F1)) 143 | % % hold on 144 | % 145 | % F2=fft(e)./T; 146 | % df=(1/T)*fs; 147 | % f=df*(0:(T-1)); 148 | % % subplot(2,1,2) 149 | % % plot(f,abs(F2)) 150 | % % hold on 151 | % 152 | % ratio = abs(F2./F1); 153 | % dB = 20*log10(ratio); 154 | % result=dB; 155 | end 156 | -------------------------------------------------------------------------------- /fxlms_time_domain.m: -------------------------------------------------------------------------------- 1 | function result_time_domain=fxlms_time_domain(k) 2 | % T = 1000; %simulation duration 3 | fs=8000; 4 | t=0:1/fs:k; 5 | T=length(t)-1; 6 | % set primary path 7 | % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 8 | % Sw=Pw*0.25; 9 | % % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01]; 10 | % Pw = [0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01 0.3 0.5]; 11 | % % secondary path 12 | % % Sw=Pw(3:7)*0.25; 13 | % Sw=Pw(3:end)*0.25; 14 | 15 | Pw=[0.9 -0.7 0.8 -0.48 0.5 -0.35 0.36 -0.32 0.3 -0.22 0.28 -0.2... 16 | 0.22 -0.15 0.2 -0.14 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01 0.01 -0.01]; 17 | % Pw=[0.9 -0.3 0.7 -0.28 0.5 -0.25 0.36 -0.22 0.3 -0.18 0.28 -0.15... 18 | % 0.22 -0.1 0.2 -0.1 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01]; 19 | % Pw=[0.9 0.9 -0.3 -0.3 0.7 0.7 -0.28 -0.28 0.5 0.5 -0.25 -0.25 0.36 0.36 -0.22 -0.22... 20 | % 0.3 0.3 -0.18 -0.18 0.28 0.28 -0.15 -0.15 0.22 0.22 -0.1 -0.1 0.2 0.2 -0.1 -0.1... 21 | % 0.14 0.14 -0.08 -0.08 0.1 0.1 -0.05 -0.05 0.05 0.05 -0.03 -0.03 0.02 0.02 -0.01 -0.01]; 22 | Sw=Pw(13:end)*0.6; 23 | % Pw = fir1(24,0.4); 24 | % Sw = fir1(12,0.2); 25 | %% secondary path estimation (offline modelling) 26 | x_iden = randn(1,T); % generate a white noise 27 | % send it to the error microphone, i.e. the identification error 28 | y_iden = filter(Sw,1,x_iden); 29 | % y_iden = conv(Sw,x_iden); 30 | 31 | %% offline modelling 32 | L = 16; %filter order, order should be sufficient to accurately model the response... 33 | %of the physical system. The larger, the better???? This value should be 34 | %larger than length(Pw) 35 | % L =30; % accuracy decreases 36 | % L = 20; 37 | S_hat_x = zeros(1,L); %define the reference signal vector of S(z)_hat 38 | S_hat_w = zeros(1,L); %define the coefficient vector of the S(z)_hat 39 | e_iden = zeros(1,L); %define the identification error in the estimation process of... 40 | % the seconday path 41 | % error = 0.0004*randn(1,T); 42 | 43 | % apply LMS algorithm 44 | % mu = 0.1; 45 | % mu = 0.05; % estimation accuracy decreases 46 | mu = 0.1; %also a very good value, performs better than 0.1 47 | for n = 1:T %time index 48 | S_hat_x = [x_iden(n) S_hat_x(1:L-1)]; %update the reference signal vector 49 | Shy = sum(S_hat_x.*S_hat_w); % calculate output of Secondary path estimate 50 | e_iden(n)=y_iden(n)-Shy; % calculate error 51 | % S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x + error(n); % adjust the weight 52 | S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x; 53 | end 54 | 55 | %%plotting 56 | subplot(2,1,1) 57 | plot([1:T], e_iden) 58 | ylabel('Amplitude'); 59 | xlabel('Discrete time n'); 60 | legend('Identification error'); 61 | subplot(2,1,2) 62 | stem(Sw) 63 | hold on 64 | stem(S_hat_w, 'r*') 65 | ylabel('Amplitude'); 66 | xlabel('Numbering of filter tap'); 67 | legend('Coefficients of Secondary Path', 'Coefficients of Secondary Path Estimate') 68 | 69 | %% Then we can propagate the seconday path estimate into the entire system 70 | % X = randn(1,T); % define the input noise(source signal) 71 | X=cos(2*pi*(1/4)*[0:T-1])+cos(2*pi*(1/100)*[0:T-1]); 72 | n = 0.03*randn(1,T); % Observation noise signal 73 | d = filter(Pw,1,X)+n; % desired signal (signal at the error microphone) 74 | % Initialization of Active Noise Control 75 | Cx = zeros(1,L); %reference signal vector of W(z) 76 | Cw = zeros(1,L); %coefficient vector of W(z) 77 | Sx = zeros(size(Sw)); %??? 78 | e = zeros(1,T); %define error value 79 | X_s = zeros(1,L); %filtered X 80 | 81 | %% Apply FXLMS 82 | mu = 0.15; 83 | for n = 1:T %time index 84 | Cx = [X(n) Cx(1:L-1)]; %update the reference signal vector 85 | Cy = sum(Cx.*Cw); %Adaptive filter output 86 | Sx = [Cy Sx(1:length(Sx)-1)]; %propagate to secondary path 87 | y = sum(Sx.*Sw); %output passing through secondary path, to the reference microphone 88 | e(n) = d(n) - y; %calculating the residual error 89 | S_hat_x = [X(n) S_hat_x(1:L-1)]; %update the vector signal of secondary path estimate 90 | X_s = [sum(S_hat_x.*S_hat_w) X_s(1:L-1)]; %i.e. x' in the paper 91 | Cw = Cw + mu*e(n)*X_s; %update the coefficiet vector of adaptive filter 92 | end 93 | %% Time domain plot 94 | %Plotting 95 | figure 96 | subplot(2,1,1) 97 | plot([1:T],e) 98 | ylabel('Amplitude'); 99 | xlabel('Discrete time n'); 100 | legend('Noise residual'); 101 | 102 | subplot(2,1,2) 103 | plot([1:T],d) 104 | hold on 105 | plot([1:T],d-e,'r:') %d-e right; y wrong ????; 106 | ylabel('Amplitude'); 107 | xlabel('Discrete time n'); 108 | legend('Noise signal','Control signal'); 109 | 110 | %% Timde dOmain dB 111 | % ratio = e.^2; 112 | ratio = zeros(1,T-100); 113 | for i = 1:T-100 114 | ratio(i) = (sum(e(i:(i+99)).^2))/(sum(d(i:(i+99)).^2)); 115 | end 116 | 117 | % ratio = zeros(1,T-10); 118 | % for i = 1:T-10 119 | % ratio(i) = (sum(e(i:(i+9)).^2))/(sum(d(i:(i+9)).^2)); 120 | % end 121 | 122 | % ratio = abs((e.^2)./(d.^2)); 123 | % ratio = abs(e./d); 124 | dB = 10*log10(ratio); 125 | % % figure 126 | % plot(1:length(dB),dB,1:length(dB),zeros(1,T)) 127 | result_time_domain=dB; 128 | 129 | % figure 130 | % plot(1:7900,dB) 131 | % 132 | % % figure 133 | % F1=fft(X(0.75*T:T-1))./length(0.75*T:T-1); 134 | % df=(1/T)*fs; 135 | % f=df*(0:(T-1)); 136 | % % subplot(2,1,1) 137 | % % plot(f,abs(F1)) 138 | % % hold on 139 | % 140 | % F2=fft(e(0.75*T:T-1))./length(0.75*T:T-1); 141 | % df=(1/T)*fs; 142 | % f=df*(0:(T-1)); 143 | % % subplot(2,1,2) 144 | % % plot(f,abs(F2)) 145 | % % hold on 146 | % 147 | % % ratio = abs(F2./F1); 148 | % dB = 20*log10(ratio); 149 | % result=dB; 150 | %% frequency domain 151 | % F1=fft(X(0.75*T:T-1))./length(0.75*T:T-1); 152 | % df=(1/T)*fs; 153 | % f=df*(0:(T-1)); 154 | % F2=fft(e(0.75*T:T-1))./length(0.75*T:T-1); 155 | % df=(1/T)*fs; 156 | % f=df*(0:(T-1)); 157 | % ratio = abs(F2./F1); 158 | % dB = 20*log10(ratio); 159 | % result = dB; 160 | % plot(1:length(dB),dB,1:length(dB),zeros(1,T)) 161 | % F1=fft(X)./T; 162 | % df=(1/T)*fs; 163 | % f=df*(0:(T-1)); 164 | % % subplot(2,1,1) 165 | % % plot(f,abs(F1)) 166 | % % hold on 167 | % 168 | % F2=fft(e)./T; 169 | % df=(1/T)*fs; 170 | % f=df*(0:(T-1)); 171 | % % subplot(2,1,2) 172 | % % plot(f,abs(F2)) 173 | % % hold on 174 | % 175 | % ratio = abs(F2./F1); 176 | % dB = 20*log10(ratio); 177 | % result=dB; 178 | end 179 | -------------------------------------------------------------------------------- /power ratio dB interval 100.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB interval 100.fig -------------------------------------------------------------------------------- /power ratio dB interval100 10000times u =0.1.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB interval100 10000times u =0.1.fig -------------------------------------------------------------------------------- /power ratio dB interval100 10000times u =0.2.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB interval100 10000times u =0.2.fig -------------------------------------------------------------------------------- /power ratio dB with background noise 0.1 1000times u =0.1.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB with background noise 0.1 1000times u =0.1.fig -------------------------------------------------------------------------------- /power ratio dB with background noise 0.1 1000times u =0.3.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB with background noise 0.1 1000times u =0.3.fig -------------------------------------------------------------------------------- /power ratio dB withbackground noise 0.3 1000times u 0.1 0.1.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB withbackground noise 0.3 1000times u 0.1 0.1.fig -------------------------------------------------------------------------------- /power ratio dB withbackground noise 0.5 1000times u 0.1 0.1.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/power ratio dB withbackground noise 0.5 1000times u 0.1 0.1.fig -------------------------------------------------------------------------------- /secondary path 16 to end power ratio dB with background noise 0.1 1000times u =0.1.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremyxu177/active-noise-control/58f83dc1fefd409a3199a86dd7a16082523c5029/secondary path 16 to end power ratio dB with background noise 0.1 1000times u =0.1.fig -------------------------------------------------------------------------------- /slicing_fxlms.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | % T = 1000; %simulation duration 5 | fs=8000; 6 | t=0:1/fs:1; 7 | T=length(t); 8 | % set primary path 9 | % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 10 | % Sw=Pw*0.25; 11 | % % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01]; 12 | % P = [0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01 0.3 0.5]; 13 | % Pw = exp(-(1:length(P))).*P; 14 | % % secondary path 15 | % % Sw=Pw(3:7)*0.25; 16 | % Sw=Pw(3:end)*0.25; 17 | 18 | Pw=[0.9 -0.3 0.7 -0.28 0.5 -0.25 0.36 -0.22 0.3 -0.18 0.28 -0.15 0.22 -0.1 0.2 -0.1 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01 0.01 -0.01]; 19 | % Pw = exp(-(1:length(P))).*P; 20 | % Sw = fir1(13,0.3); 21 | Sw=Pw(13:end)*0.6; 22 | %% secondary path estimation (offline modelling) 23 | x_iden = rand(1,T); % generate a white noise 24 | 25 | % send it to the error microphone, i.e. the identification error 26 | y_iden = filter(Sw,1,x_iden); 27 | % y_iden = conv(Sw,x_iden); 28 | 29 | %% offline modelling 30 | L = 16; %filter order, order should be sufficient to accurately model the response... 31 | %of the physical system. The larger, the better???? This value should be 32 | %larger than length(Pw) 33 | % L =30; % accuracy decreases 34 | % L = 20; 35 | S_hat_x = zeros(1,L); %define the reference signal vector of S(z)_hat 36 | S_hat_w = zeros(1,L); %define the coefficient vector of the S(z)_hat 37 | e_iden = zeros(1,L); %define the identification error in the estimation process of... 38 | % the seconday path 39 | 40 | % apply LMS algorithm 41 | % mu = 0.1; 42 | % mu = 0.05; % estimation accuracy decreases 43 | mu = 0.2; %also a very good value, performs better than 0.1 44 | for n = 1:T %time index 45 | S_hat_x = [x_iden(n) S_hat_x(1:L-1)]; %update the reference signal vector 46 | Shy = sum(S_hat_x.*S_hat_w); % calculate output of Secondary path estimate 47 | e_iden(n)=y_iden(n)-Shy; % calculate error 48 | S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x; % adjust the weight 49 | end 50 | 51 | %plotting 52 | figure 53 | subplot(2,1,1) 54 | plot([1:T], e_iden) 55 | title('secondary path offline modelling'); 56 | ylabel('Amplitude'); 57 | xlabel('Discrete time n'); 58 | legend('Identification error'); 59 | subplot(2,1,2) 60 | stem(Sw) 61 | hold on 62 | stem(S_hat_w, 'r*') 63 | ylabel('Amplitude'); 64 | xlabel('Numbering of filter tap'); 65 | legend('Coefficients of Secondary Path', 'Coefficients of Secondary Path Estimate') 66 | 67 | 68 | 69 | %% Then we can propagate the seconday path estimate into the entire system 70 | X = randn(1,T)+ 0.8*randn(1,T); % define the input noise(source signal) 71 | % X=0.9*cos(2*pi*(1/5)*[0:T-1]); 72 | % X = cos(2*pi*(1/5)*[0:T-1]); 73 | d = filter(Pw,1,X); % desired signal (signal at the error microphone) 74 | % Initialization of Active Noise Control 75 | Cx = zeros(1,L); %reference signal vector of W(z) 76 | Cw = zeros(1,L); %coefficient vector of W(z) 77 | Sx = zeros(size(Sw)); %??? 78 | e = zeros(1,T); %define error value 79 | X_s = zeros(1,L); %filtered X 80 | 81 | %% Apply FXLMS 82 | mu = 0.1; 83 | for n = 1:T %time index 84 | Cx = [X(n) Cx(1:L-1)]; %update the reference signal vector 85 | Cy = sum(Cx.*Cw); %Adaptive filter output 86 | Sx = [Cy Sx(1:length(Sx)-1)]; %propagate to secondary path 87 | y = sum(Sx.*Sw); %output passing through secondary path, to the reference microphone 88 | e(n) = d(n) - y; %calculating the residual error 89 | S_hat_x = [X(n) S_hat_x(1:L-1)]; %update the vector signal of secondary path estimate 90 | X_s = [sum(S_hat_x.*S_hat_w) X_s(1:L-1)]; %i.e. x' in the paper 91 | Cw = Cw + mu*e(n)*X_s; %update the coefficiet vector of adaptive filter 92 | end 93 | 94 | %Plotting 95 | figure 96 | subplot(2,1,1) 97 | plot([1:T],e) 98 | title('ANC time domain performance'); 99 | ylabel('Amplitude'); 100 | xlabel('Discrete time n'); 101 | legend('Noise residual'); 102 | 103 | subplot(2,1,2) 104 | plot(1:T,d,1:T,d-e,'r:') %d-e right; y wrong ????; 105 | ylabel('Amplitude'); 106 | xlabel('Discrete time n'); 107 | legend('Noise signal','Control signal'); 108 | 109 | figure 110 | interval = [(1:0.25*T);(0.25*T:0.5*T-1) ;(0.5*T:0.75*T-1); (0.75*T:T-1)]; 111 | for i = 1:4 112 | F1 = fft(d(interval(i,:)))./length(interval(i,:)); 113 | df = (1/T)*fs; 114 | f = df*interval(1,:); 115 | % figure 116 | subplot(4,3,i*3-2) 117 | plot(f,abs(F1)) 118 | 119 | 120 | F2 = fft(e(interval(i,:)))./length(interval(i,:)); 121 | df = (1/T)*fs; 122 | f = df*interval(1,:); 123 | %figure 124 | subplot(4,3,3*i-1) 125 | plot(f,abs(F2)) 126 | 127 | ratio = abs(F2./F1); 128 | dB = 20*log10(ratio); 129 | subplot(4,3,3*i) 130 | plot(f,dB,f,zeros(1,length(interval(i,:)))); 131 | end 132 | 133 | %% TIME DOMAIN POWER ANALYSIS 134 | power_sum_e = zeros(1,T); 135 | power_sum_d = zeros(1,T); 136 | ratio3 = zeros(1,T); 137 | power_ratio = zeros(1,T); 138 | for n = 1:T 139 | power_e = abs(e.^2); 140 | power_d = abs(d.^2); 141 | power_sum_e = power_sum_e + power_e; 142 | power_sum_d = power_sum_d + power_d; 143 | ratio3 = power_sum_e./power_sum_d; 144 | power_ratio = 10*log10(ratio3); 145 | end 146 | % disp(ratio3) 147 | % disp(power_ratio) 148 | hold on 149 | figure 150 | plot([1:T],power_ratio) 151 | title('power ratio decline in time domain'); 152 | 153 | % figure 154 | % F1=fft(X(1:0.25*T))./[1:0.25*T]; 155 | % df=(1/T)*fs; 156 | % f=df*(0:(0.25*T-1)); 157 | % subplot(2,1,1) 158 | % % plot(f,abs(F1)) 159 | % plot(abs(F1)) 160 | % title('FFT of Noise signal'); 161 | % hold on 162 | % 163 | % F2=fft(e(1:0.25*T))./[1:0.25*T]; 164 | % df=(1/T)*fs; 165 | % f=df*(0:(0.25*T-1)); 166 | % subplot(2,1,2) 167 | % % plot(f,abs(F2)) 168 | % plot(abs(F2)) 169 | % title('FFT of Residual signal'); 170 | % hold on 171 | % 172 | % ratio1 = abs(e(1:0.25*T)./d(1:0.25*T)); 173 | % ratio2 = abs(F2(1:0.25*T)./F1(1:0.25*T)); 174 | % dB = 20*log10(ratio2); 175 | % figure 176 | % % plot(f,dB,f,zeros(1,T)) 177 | % plot(dB) 178 | % title('ANC frequency domain performance'); 179 | % hold on 180 | % 181 | % figure 182 | % F1=fft(X(0.25:0.5*T))./[0.25:0.5*T]; 183 | % df=(1/T)*fs; 184 | % f=df*(0.25*T:(0.5*T-1)); 185 | % subplot(2,1,1) 186 | % % plot(f,abs(F1)) 187 | % plot(abs(F1)) 188 | % title('FFT of Noise signal'); 189 | % hold on 190 | % 191 | % F2=fft(e(0.25:0.5*T))./[0.25:0.5*T]; 192 | % df=(1/T)*fs; 193 | % f=df*(0.25*T:(0.5*T-1)); 194 | % subplot(2,1,2) 195 | % % plot(f,abs(F2)) 196 | % plot(abs(F2)) 197 | % title('FFT of Residual signal'); 198 | % hold on 199 | % 200 | % ratio1 = abs(e(0.25:0.5*T)./d(0.25:0.5*T)); 201 | % ratio2 = abs(F2(0.25:0.5*T)./F1(0.25:0.5*T)); 202 | % dB = 20*log10(ratio2); 203 | % figure 204 | % % plot(f,dB,f,zeros(1,T)) 205 | % plot(dB) 206 | % title('ANC frequency domain performance'); 207 | % hold on 208 | % 209 | % figure 210 | % F1=fft(X(0.5:0.75*T))./[0.5:0.75*T]; 211 | % df=(1/T)*fs; 212 | % f=df*(0.5*T:(0.75*T-1)); 213 | % subplot(2,1,1) 214 | % % plot(f,abs(F1)) 215 | % plot(abs(F1)) 216 | % title('FFT of Noise signal'); 217 | % hold on 218 | % 219 | % F2=fft(e(0.5:0.75*T))./[0.5:0.75*T]; 220 | % df=(1/T)*fs; 221 | % f=df*(0.5:(0.75*T-1)); 222 | % subplot(2,1,2) 223 | % % plot(f,abs(F2)) 224 | % plot(abs(F2)) 225 | % title('FFT of Residual signal'); 226 | % hold on 227 | % 228 | % ratio1 = abs(e(0.5:0.75*T)./d(0.5:0.75*T)); 229 | % ratio2 = abs(F2(0.5:0.75*T)./F1(0.5:0.75*T)); 230 | % dB = 20*log10(ratio2); 231 | % figure 232 | % % plot(f,dB,f,zeros(1,T)) 233 | % plot(dB) 234 | % title('ANC frequency domain performance'); 235 | % hold on 236 | % %% FREQUENCY DOMAIN 237 | % figure 238 | % subplot(6,2,1) 239 | % plot(abs(F1(1:0.25*T))); 240 | % title('first quarter of iterations'); 241 | % subplot(6,2,3) 242 | % plot(abs(F2(1:0.25*T))); 243 | % subplot(6,2,5) 244 | % plot(dB(1:0.25*T)); 245 | % 246 | % subplot(6,2,2) 247 | % plot(abs(F1(0.25*T:0.5*T))); 248 | % title('second quarter of iterations'); 249 | % subplot(6,2,4) 250 | % plot(abs(F2(0.25*T:0.5*T))); 251 | % subplot(6,2,6) 252 | % plot(dB(0.25*T:0.5*T)); 253 | % 254 | % subplot(6,2,7) 255 | % plot(abs(F1(0.5*T:0.75*T))); 256 | % title('third quarter of iterations'); 257 | % subplot(6,2,9) 258 | % plot(abs(F2(0.5*T:0.75*T))); 259 | % subplot(6,2,11) 260 | % plot(dB(0.5*T:0.75*T)); 261 | % 262 | % subplot(6,2,8) 263 | % plot(abs(F1(0.75*T:T))); 264 | % title('fourth quarter of iterations'); 265 | % subplot(6,2,10) 266 | % plot(abs(F2(0.75*T:T))); 267 | % subplot(6,2,12) 268 | % plot(dB(0.75*T:T)); 269 | % %% TIME DOMAIN 270 | % figure 271 | % subplot(6,2,1) 272 | % plot([1:0.25*T],e(1:0.25*T)); 273 | % title('first quarter of iterations'); 274 | % axis([0 8000 -5 5]) 275 | % subplot(6,2,3) 276 | % plot([1:0.25*T],d(1:0.25*T)); 277 | % axis([0 8000 -10 10]) 278 | % subplot(6,2,5) 279 | % plot([1:0.25*T],ratio1(1:0.25*T)); 280 | % 281 | % subplot(6,2,2) 282 | % plot([0.25*T:0.5*T],e(0.25*T:0.5*T)); 283 | % title('second quarter of iterations'); 284 | % axis([0 8000 -5 5]) 285 | % subplot(6,2,4) 286 | % plot([0.25*T:0.5*T],d(0.25*T:0.5*T)); 287 | % axis([0 8000 -10 10]) 288 | % subplot(6,2,6) 289 | % plot([0.25*T:0.5*T],ratio1(0.25*T:0.5*T)); 290 | % 291 | % subplot(6,2,7) 292 | % plot([0.5*T:0.75*T],e(0.5*T:0.75*T)); 293 | % title('third quarter of iterations'); 294 | % axis([0 8000 -5 5]) 295 | % subplot(6,2,9) 296 | % plot([0.5*T:0.75*T],d(0.5*T:0.75*T)); 297 | % axis([0 8000 -10 10]) 298 | % subplot(6,2,11) 299 | % plot([0.5*T:0.75*T],ratio1(0.5*T:0.75*T)); 300 | % 301 | % subplot(6,2,8) 302 | % plot([0.75*T:T],e(0.75*T:T)); 303 | % title('fourth quarter of iterations'); 304 | % axis([0 8000 -5 5]) 305 | % subplot(6,2,10) 306 | % plot([0.75*T:T],d(0.75*T:T)); 307 | % axis([0 8000 -10 10]) 308 | % subplot(6,2,12) 309 | % plot([0.75*T:T],ratio1(0.75*T:T)); 310 | % 311 | % 312 | % %% TIME DOMAIN POWER ANALYSIS 313 | % power_sum_e = zeros(1,T); 314 | % power_sum_d = zeros(1,T); 315 | % ratio3 = zeros(1,T); 316 | % power_ratio = zeros(1,T); 317 | % for n = 1:T 318 | % power_e = abs(e.^2); 319 | % power_d = abs(d.^2); 320 | % power_sum_e = power_sum_e + power_e; 321 | % power_sum_d = power_sum_d + power_d; 322 | % ratio3 = power_sum_e./power_sum_d; 323 | % power_ratio = 10*log10(ratio3); 324 | % end 325 | % disp(ratio3) 326 | % disp(power_ratio) 327 | % hold on 328 | % figure 329 | % plot([1:T],power_ratio) 330 | % title('power_ratio decline in time domain'); -------------------------------------------------------------------------------- /slicingby8.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | % T = 1000; %simulation duration 5 | fs=8000; 6 | t=0:1/fs:1; 7 | T=length(t)-1; 8 | % set primary path 9 | % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 10 | % Sw=Pw*0.25; 11 | % % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01]; 12 | % P = [0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01 0.3 0.5]; 13 | % Pw = exp(-(1:length(P))).*P; 14 | % % secondary path 15 | % % Sw=Pw(3:7)*0.25; 16 | % Sw=Pw(3:end)*0.25; 17 | 18 | Pw=[0.9 -0.3 0.7 -0.28 0.5 -0.25 0.36 -0.22 0.3 -0.18 0.28 -0.15 0.22 -0.1 0.2... 19 | -0.1 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01 0.01 -0.01]; 20 | % Pw = exp(-(1:length(P))).*P; 21 | % Sw = fir1(13,0.3); 22 | Sw=Pw(13:end)*0.6; 23 | %% secondary path estimation (offline modelling) 24 | x_iden = rand(1,T); % generate a white noise 25 | % send it to the error microphone, i.e. the identification error 26 | y_iden = filter(Sw,1,x_iden); 27 | % y_iden = conv(Sw,x_iden); 28 | 29 | %% offline modelling 30 | L = 16; %filter order, order should be sufficient to accurately model the response... 31 | %of the physical system. The larger, the better???? This value should be 32 | %larger than length(Pw) 33 | % L =30; % accuracy decreases 34 | % L = 20; 35 | S_hat_x = zeros(1,L); %define the reference signal vector of S(z)_hat 36 | S_hat_w = zeros(1,L); %define the coefficient vector of the S(z)_hat 37 | e_iden = zeros(1,L); %define the identification error in the estimation process of... 38 | % the seconday path 39 | 40 | % apply LMS algorithm 41 | % mu = 0.1; 42 | % mu = 0.05; % estimation accuracy decreases 43 | mu = 0.2; %also a very good value, performs better than 0.1 44 | for n = 1:T %time index 45 | S_hat_x = [x_iden(n) S_hat_x(1:L-1)]; %update the reference signal vector 46 | Shy = sum(S_hat_x.*S_hat_w); % calculate output of Secondary path estimate 47 | e_iden(n)=y_iden(n)-Shy; % calculate error 48 | S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x; % adjust the weight 49 | end 50 | 51 | %plotting 52 | figure 53 | subplot(2,1,1) 54 | plot([1:T], e_iden) 55 | title('secondary path offline modelling'); 56 | ylabel('Amplitude'); 57 | xlabel('Discrete time n'); 58 | legend('Identification error'); 59 | subplot(2,1,2) 60 | stem(Sw) 61 | hold on 62 | stem(S_hat_w, 'r*') 63 | ylabel('Amplitude'); 64 | xlabel('Numbering of filter tap'); 65 | legend('Coefficients of Secondary Path', 'Coefficients of Secondary Path Estimate') 66 | 67 | 68 | 69 | %% Then we can propagate the seconday path estimate into the entire system 70 | X = randn(1,T)+ 0.8*randn(1,T); % define the input noise(source signal) 71 | % X=0.9*cos(2*pi*(1/5)*[0:T-1]); 72 | % X = cos(2*pi*(1/5)*[0:T-1]); 73 | d = filter(Pw,1,X); % desired signal (signal at the error microphone) 74 | % Initialization of Active Noise Control 75 | Cx = zeros(1,L); %reference signal vector of W(z) 76 | Cw = zeros(1,L); %coefficient vector of W(z) 77 | Sx = zeros(size(Sw)); %??? 78 | e = zeros(1,T); %define error value 79 | X_s = zeros(1,L); %filtered X 80 | 81 | %% Apply FXLMS 82 | mu = 0.1; 83 | for n = 1:T %time index 84 | Cx = [X(n) Cx(1:L-1)]; %update the reference signal vector 85 | Cy = sum(Cx.*Cw); %Adaptive filter output 86 | Sx = [Cy Sx(1:length(Sx)-1)]; %propagate to secondary path 87 | y = sum(Sx.*Sw); %output passing through secondary path, to the reference microphone 88 | e(n) = d(n) - y; %calculating the residual error 89 | S_hat_x = [X(n) S_hat_x(1:L-1)]; %update the vector signal of secondary path estimate 90 | X_s = [sum(S_hat_x.*S_hat_w) X_s(1:L-1)]; %i.e. x' in the paper 91 | Cw = Cw + mu*e(n)*X_s; %update the coefficiet vector of adaptive filter 92 | end 93 | 94 | %Plotting 95 | figure 96 | subplot(2,1,1) 97 | plot([1:T],e) 98 | title('ANC time domain performance'); 99 | ylabel('Amplitude'); 100 | xlabel('Discrete time n'); 101 | legend('Noise residual'); 102 | 103 | subplot(2,1,2) 104 | plot(1:T,d,1:T,d-e,'r:') %d-e right; y wrong ????; 105 | ylabel('Amplitude'); 106 | xlabel('Discrete time n'); 107 | legend('Noise signal','Control signal'); 108 | 109 | figure 110 | interval = [(1:0.125*T);(0.125*T:0.25*T-1) ;(0.25*T:0.375*T-1); (0.375*T:0.5*T-1);... 111 | (0.5*T:0.625*T-1);(0.625*T:0.75*T-1);(0.75*T:0.875*T-1);(0.875*T:T-1)]; 112 | for i = 1:8 113 | F1 = fft(d(interval(i,:)))./length(interval(i,:)); 114 | df = (1/T)*fs; 115 | f = df*interval(1,:); 116 | % figure 117 | subplot(8,3,i*3-2) 118 | plot(f,abs(F1)) 119 | 120 | 121 | F2 = fft(e(interval(i,:)))./length(interval(i,:)); 122 | df = (1/T)*fs; 123 | f = df*interval(1,:); 124 | %figure 125 | subplot(8,3,3*i-1) 126 | plot(f,abs(F2)) 127 | 128 | ratio = abs(F2./F1); 129 | dB = 20*log10(ratio); 130 | subplot(8,3,3*i) 131 | plot(f,dB,f,zeros(1,length(interval(i,:)))); 132 | end 133 | 134 | %% TIME DOMAIN POWER ANALYSIS 135 | % power_sum_e = zeros(1,T); 136 | % power_sum_d = zeros(1,T); 137 | % ratio3 = zeros(1,T); 138 | % power_ratio = zeros(1,T); 139 | % for n = 1:T 140 | % power_e = abs(e.^2); 141 | % power_d = abs(d.^2); 142 | % power_sum_e = power_sum_e + power_e; 143 | % power_sum_d = power_sum_d + power_d; 144 | % ratio3 = power_sum_e./power_sum_d; 145 | % power_ratio = 10*log10(ratio3); 146 | % end 147 | % % disp(ratio3) 148 | % % disp(power_ratio) 149 | % hold on 150 | % figure 151 | % plot([1:T],power_ratio) 152 | % title('power ratio decline in time domain'); 153 | 154 | % figure 155 | % F1=fft(X(1:0.25*T))./[1:0.25*T]; 156 | % df=(1/T)*fs; 157 | % f=df*(0:(0.25*T-1)); 158 | % subplot(2,1,1) 159 | % % plot(f,abs(F1)) 160 | % plot(abs(F1)) 161 | % title('FFT of Noise signal'); 162 | % hold on 163 | % 164 | % F2=fft(e(1:0.25*T))./[1:0.25*T]; 165 | % df=(1/T)*fs; 166 | % f=df*(0:(0.25*T-1)); 167 | % subplot(2,1,2) 168 | % % plot(f,abs(F2)) 169 | % plot(abs(F2)) 170 | % title('FFT of Residual signal'); 171 | % hold on 172 | % 173 | % ratio1 = abs(e(1:0.25*T)./d(1:0.25*T)); 174 | % ratio2 = abs(F2(1:0.25*T)./F1(1:0.25*T)); 175 | % dB = 20*log10(ratio2); 176 | % figure 177 | % % plot(f,dB,f,zeros(1,T)) 178 | % plot(dB) 179 | % title('ANC frequency domain performance'); 180 | % hold on 181 | % 182 | % figure 183 | % F1=fft(X(0.25:0.5*T))./[0.25:0.5*T]; 184 | % df=(1/T)*fs; 185 | % f=df*(0.25*T:(0.5*T-1)); 186 | % subplot(2,1,1) 187 | % % plot(f,abs(F1)) 188 | % plot(abs(F1)) 189 | % title('FFT of Noise signal'); 190 | % hold on 191 | % 192 | % F2=fft(e(0.25:0.5*T))./[0.25:0.5*T]; 193 | % df=(1/T)*fs; 194 | % f=df*(0.25*T:(0.5*T-1)); 195 | % subplot(2,1,2) 196 | % % plot(f,abs(F2)) 197 | % plot(abs(F2)) 198 | % title('FFT of Residual signal'); 199 | % hold on 200 | % 201 | % ratio1 = abs(e(0.25:0.5*T)./d(0.25:0.5*T)); 202 | % ratio2 = abs(F2(0.25:0.5*T)./F1(0.25:0.5*T)); 203 | % dB = 20*log10(ratio2); 204 | % figure 205 | % % plot(f,dB,f,zeros(1,T)) 206 | % plot(dB) 207 | % title('ANC frequency domain performance'); 208 | % hold on 209 | % 210 | % figure 211 | % F1=fft(X(0.5:0.75*T))./[0.5:0.75*T]; 212 | % df=(1/T)*fs; 213 | % f=df*(0.5*T:(0.75*T-1)); 214 | % subplot(2,1,1) 215 | % % plot(f,abs(F1)) 216 | % plot(abs(F1)) 217 | % title('FFT of Noise signal'); 218 | % hold on 219 | % 220 | % F2=fft(e(0.5:0.75*T))./[0.5:0.75*T]; 221 | % df=(1/T)*fs; 222 | % f=df*(0.5:(0.75*T-1)); 223 | % subplot(2,1,2) 224 | % % plot(f,abs(F2)) 225 | % plot(abs(F2)) 226 | % title('FFT of Residual signal'); 227 | % hold on 228 | % 229 | % ratio1 = abs(e(0.5:0.75*T)./d(0.5:0.75*T)); 230 | % ratio2 = abs(F2(0.5:0.75*T)./F1(0.5:0.75*T)); 231 | % dB = 20*log10(ratio2); 232 | % figure 233 | % % plot(f,dB,f,zeros(1,T)) 234 | % plot(dB) 235 | % title('ANC frequency domain performance'); 236 | % hold on 237 | % %% FREQUENCY DOMAIN 238 | % figure 239 | % subplot(6,2,1) 240 | % plot(abs(F1(1:0.25*T))); 241 | % title('first quarter of iterations'); 242 | % subplot(6,2,3) 243 | % plot(abs(F2(1:0.25*T))); 244 | % subplot(6,2,5) 245 | % plot(dB(1:0.25*T)); 246 | % 247 | % subplot(6,2,2) 248 | % plot(abs(F1(0.25*T:0.5*T))); 249 | % title('second quarter of iterations'); 250 | % subplot(6,2,4) 251 | % plot(abs(F2(0.25*T:0.5*T))); 252 | % subplot(6,2,6) 253 | % plot(dB(0.25*T:0.5*T)); 254 | % 255 | % subplot(6,2,7) 256 | % plot(abs(F1(0.5*T:0.75*T))); 257 | % title('third quarter of iterations'); 258 | % subplot(6,2,9) 259 | % plot(abs(F2(0.5*T:0.75*T))); 260 | % subplot(6,2,11) 261 | % plot(dB(0.5*T:0.75*T)); 262 | % 263 | % subplot(6,2,8) 264 | % plot(abs(F1(0.75*T:T))); 265 | % title('fourth quarter of iterations'); 266 | % subplot(6,2,10) 267 | % plot(abs(F2(0.75*T:T))); 268 | % subplot(6,2,12) 269 | % plot(dB(0.75*T:T)); 270 | % %% TIME DOMAIN 271 | % figure 272 | % subplot(6,2,1) 273 | % plot([1:0.25*T],e(1:0.25*T)); 274 | % title('first quarter of iterations'); 275 | % axis([0 8000 -5 5]) 276 | % subplot(6,2,3) 277 | % plot([1:0.25*T],d(1:0.25*T)); 278 | % axis([0 8000 -10 10]) 279 | % subplot(6,2,5) 280 | % plot([1:0.25*T],ratio1(1:0.25*T)); 281 | % 282 | % subplot(6,2,2) 283 | % plot([0.25*T:0.5*T],e(0.25*T:0.5*T)); 284 | % title('second quarter of iterations'); 285 | % axis([0 8000 -5 5]) 286 | % subplot(6,2,4) 287 | % plot([0.25*T:0.5*T],d(0.25*T:0.5*T)); 288 | % axis([0 8000 -10 10]) 289 | % subplot(6,2,6) 290 | % plot([0.25*T:0.5*T],ratio1(0.25*T:0.5*T)); 291 | % 292 | % subplot(6,2,7) 293 | % plot([0.5*T:0.75*T],e(0.5*T:0.75*T)); 294 | % title('third quarter of iterations'); 295 | % axis([0 8000 -5 5]) 296 | % subplot(6,2,9) 297 | % plot([0.5*T:0.75*T],d(0.5*T:0.75*T)); 298 | % axis([0 8000 -10 10]) 299 | % subplot(6,2,11) 300 | % plot([0.5*T:0.75*T],ratio1(0.5*T:0.75*T)); 301 | % 302 | % subplot(6,2,8) 303 | % plot([0.75*T:T],e(0.75*T:T)); 304 | % title('fourth quarter of iterations'); 305 | % axis([0 8000 -5 5]) 306 | % subplot(6,2,10) 307 | % plot([0.75*T:T],d(0.75*T:T)); 308 | % axis([0 8000 -10 10]) 309 | % subplot(6,2,12) 310 | % plot([0.75*T:T],ratio1(0.75*T:T)); 311 | % 312 | % 313 | % %% TIME DOMAIN POWER ANALYSIS 314 | % power_sum_e = zeros(1,T); 315 | % power_sum_d = zeros(1,T); 316 | % ratio3 = zeros(1,T); 317 | % power_ratio = zeros(1,T); 318 | % for n = 1:T 319 | % power_e = abs(e.^2); 320 | % power_d = abs(d.^2); 321 | % power_sum_e = power_sum_e + power_e; 322 | % power_sum_d = power_sum_d + power_d; 323 | % ratio3 = power_sum_e./power_sum_d; 324 | % power_ratio = 10*log10(ratio3); 325 | % end 326 | % disp(ratio3) 327 | % disp(power_ratio) 328 | % hold on 329 | % figure 330 | % plot([1:T],power_ratio) 331 | % title('power_ratio decline in time domain'); -------------------------------------------------------------------------------- /trial1018dB.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | % T = 1000; %simulation duration 5 | fs=8000; 6 | t=0:1/fs:1; 7 | T=length(t)-1; 8 | % set primary path 9 | % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 10 | % Sw=Pw*0.25; 11 | % % Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01]; 12 | % P = [0.01 0.25 0.5 1 0.5 0.25 0.01 0.02 0.01 0.3 0.5]; 13 | % Pw = exp(-(1:length(P))).*P; 14 | % % secondary path 15 | % % Sw=Pw(3:7)*0.25; 16 | % Sw=Pw(3:end)*0.25; 17 | 18 | Pw=[0.9 -0.3 0.7 -0.28 0.5 -0.25 0.36 -0.22 0.3 -0.18 0.28 -0.15 0.22 -0.1 0.2 -0.1 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01 0.01 -0.01]; 19 | % Pw = exp(-(1:length(P))).*P; 20 | % Sw = fir1(13,0.3); 21 | Sw=Pw(13:end)*0.5; 22 | %% secondary path estimation (offline modelling) 23 | x_iden = rand(1,T); % generate a white noise 24 | % send it to the error microphone, i.e. the identification error 25 | y_iden = filter(Sw,1,x_iden); 26 | % y_iden = conv(Sw,x_iden); 27 | 28 | %% offline modelling 29 | L = 16; %filter order, order should be sufficient to accurately model the response... 30 | %of the physical system. The larger, the better???? This value should be 31 | %larger than length(Pw) 32 | % L =30; % accuracy decreases 33 | % L = 20; 34 | S_hat_x = zeros(1,L); %define the reference signal vector of S(z)_hat 35 | S_hat_w = zeros(1,L); %define the coefficient vector of the S(z)_hat 36 | e_iden = zeros(1,L); %define the identification error in the estimation process of... 37 | % the seconday path 38 | 39 | % apply LMS algorithm 40 | % mu = 0.1; 41 | % mu = 0.05; % estimation accuracy decreases 42 | mu = 0.2; %also a very good value, performs better than 0.1 43 | for n = 1:T %time index 44 | S_hat_x = [x_iden(n) S_hat_x(1:L-1)]; %update the reference signal vector 45 | Shy = sum(S_hat_x.*S_hat_w); % calculate output of Secondary path estimate 46 | e_iden(n)=y_iden(n)-Shy; % calculate error 47 | S_hat_w=S_hat_w + mu*e_iden(n)*S_hat_x; % adjust the weight 48 | end 49 | 50 | %plotting 51 | figure 52 | subplot(2,1,1) 53 | plot([1:T], e_iden) 54 | title('secondary path offline modelling'); 55 | ylabel('Amplitude'); 56 | xlabel('Discrete time n'); 57 | legend('Identification error'); 58 | subplot(2,1,2) 59 | stem(Sw) 60 | hold on 61 | stem(S_hat_w, 'r*') 62 | ylabel('Amplitude'); 63 | xlabel('Numbering of filter tap'); 64 | legend('Coefficients of Secondary Path', 'Coefficients of Secondary Path Estimate') 65 | 66 | 67 | 68 | %% Then we can propagate the seconday path estimate into the entire system 69 | X = randn(1,T)+ 0.8*randn(1,T); % define the input noise(source signal) 70 | % X=0.9*cos(2*pi*(1/5)*[0:T-1]); 71 | % X = cos(2*pi*(1/5)*[0:T-1]); 72 | d = filter(Pw,1,X); % desired signal (signal at the error microphone) 73 | % Initialization of Active Noise Control 74 | Cx = zeros(1,L); %reference signal vector of W(z) 75 | Cw = zeros(1,L); %coefficient vector of W(z) 76 | Sx = zeros(size(Sw)); %??? 77 | e = zeros(1,T); %define error value 78 | X_s = zeros(1,L); %filtered X 79 | 80 | %% Apply FXLMS 81 | mu = 0.1; 82 | for n = 1:T %time index 83 | Cx = [X(n) Cx(1:L-1)]; %update the reference signal vector 84 | Cy = sum(Cx.*Cw); %Adaptive filter output 85 | Sx = [Cy Sx(1:length(Sx)-1)]; %propagate to secondary path 86 | y = sum(Sx.*Sw); %output passing through secondary path, to the reference microphone 87 | e(n) = d(n) - y; %calculating the residual error 88 | S_hat_x = [X(n) S_hat_x(1:L-1)]; %update the vector signal of secondary path estimate 89 | X_s = [sum(S_hat_x.*S_hat_w) X_s(1:L-1)]; %i.e. x' in the paper 90 | Cw = Cw + mu*e(n)*X_s; %update the coefficiet vector of adaptive filter 91 | end 92 | 93 | %Plotting 94 | figure 95 | subplot(2,1,1) 96 | plot([1:T],e) 97 | title('ANC time domain performance'); 98 | ylabel('Amplitude'); 99 | xlabel('Discrete time n'); 100 | legend('Noise residual'); 101 | 102 | subplot(2,1,2) 103 | plot(1:T,d,1:T,d-e,'r:') %d-e right; y wrong ????; 104 | ylabel('Amplitude'); 105 | xlabel('Discrete time n'); 106 | legend('Noise signal','Control signal'); 107 | 108 | ratio = abs(e.^2)./abs(d.^2); 109 | dB = 20*log10(ratio); 110 | figure 111 | plot(1:T,dB,'.',1:T,zeros(1,T)) 112 | % figure 113 | % interval = [(1:0.25*T);(0.25*T:0.5*T-1) ;(0.5*T:0.75*T-1); (0.75*T:T-1)]; 114 | % for i = 1:4 115 | % F1 = fft(d(interval(i,:)))./length(interval(i,:)); 116 | % df = (1/T)*fs; 117 | % f = df*interval(1,:); 118 | % % figure 119 | % subplot(4,3,i*3-2) 120 | % plot(f,abs(F1)) 121 | % 122 | % 123 | % F2 = fft(e(interval(i,:)))./length(interval(i,:)); 124 | % df = (1/T)*fs; 125 | % f = df*interval(1,:); 126 | % %figure 127 | % subplot(4,3,3*i-1) 128 | % plot(f,abs(F2)) 129 | % 130 | % ratio = abs(F2./F1); 131 | % dB = 20*log10(ratio); 132 | % subplot(4,3,3*i) 133 | % plot(f,dB,f,zeros(1,length(interval(i,:)))); 134 | % end 135 | -------------------------------------------------------------------------------- /try_fblms.m: -------------------------------------------------------------------------------- 1 | %-------------------------------------------------------------------------- 2 | % I am very busy lately with my work so, regretfully, I have no choice 3 | % except to postpone my plan to write a new code for simulating a multi- 4 | % channel active noise control system. In the meantime, I compose one code 5 | % about feed-back active noise control system (FbLMS), which is somewhat 6 | % different to the feed-forward system (FxLMS) in method for obtaining 7 | % reference signal. FbLMS does not employ any reference sensor. Instead, it 8 | % uses linear predictor for generating reference signal. Thus, FbLMS is 9 | % suitable for reducing narrow-band noise. 10 | % 11 | % Here is the system block diagram. 12 | % 13 | % +-----------+ + 14 | % x(k) ------->| P(z) |--yp(k)----------------> sum --+---> e(k) 15 | % +-----------+ ^- | 16 | % | | 17 | % +-------------------------------+ | | 18 | % | | | | 19 | % | \ | ys(k) | 20 | % | +-----------+ | +-----------+ | | 21 | % | +--->| C(z) |--yw(k)-+->| S(z) |---+ | 22 | % | | +-----------+ +-----------+ | 23 | % | | \ | 24 | % | | \-----------------\ | 25 | % | | \ | 26 | % | | +-----------+ +-----------+ | 27 | % | +--->| Sh(z) |--xs(k)-+->| LMS |<------+ 28 | % | | +-----------+ +-----------+ | 29 | % | xh(z) | 30 | % | | + | 31 | % | +----------------------- sum <-------------------+ 32 | % | ^+ 33 | % | +-----------+ | 34 | % +--------->| Sh(z) |--------+ 35 | % +-----------+ 36 | % 37 | % Similar to the previous FxLMS code, I used FIR filter to model P(z), 38 | % C(z), S(z), and Sh(z). Imagine that the noise x(k) is propagating from 39 | % the source to the sensor, through the fluid medium P(z). The sensor 40 | % measures the arriving noise as yp(k). 41 | % 42 | % To reduce noise, we generate another 'noise' yw(k) using the controller 43 | % C(z). We hope that it destructively interferes x(k). It means that the 44 | % controller has to be a model of the propagation medium P(z). Least mean 45 | % square algorithm is applied to adjust the controller coefficient/weight. 46 | % 47 | % However, there is also fluid medium S(z) that stay between the actuator 48 | % and sensor. We called it the secondary propagation path. So, to make the 49 | % solusion right, we need to compensate the adjustment process using Sh(z), 50 | % which is an estimate of S(z). 51 | % 52 | % You can find many good information in "Active Noise Control Systems - 53 | % Algorithms and DSP Implementations," written by S. M. Kuo and 54 | % D. R. Morgan in 1996. 55 | % 56 | % Let's start the code :) 57 | % 58 | % Developed by Agustinus Oey 59 | % Center of Noise and Vibration Control (NoViC) 60 | % Department of Mechanical Engineering 61 | % Korea Advanced Institute of Science and Technology (KAIST) 62 | % Daejeon, South Korea 63 | %-------------------------------------------------------------------------- 64 | 65 | % Set simulation duration (normalized) 66 | clear 67 | T=1000; 68 | 69 | % We do not know P(z) and S(z) in reality. So we have to make dummy paths 70 | Pw=[0.01 0.25 0.5 1 0.5 0.25 0.01]; 71 | Sw=Pw*0.25; 72 | 73 | % Remember that the first task is to estimate S(z). So, we can generate a 74 | % white noise signal, 75 | x_iden=randn(1,T); 76 | 77 | % send it to the actuator, and measure it at the sensor position, 78 | y_iden=filter(Sw, 1, x_iden); 79 | 80 | % Then, start the identification process 81 | Shx=zeros(1,16); % the state of Sh(z) 82 | Shw=zeros(1,16); % the weight of Sh(z) 83 | e_iden=zeros(1,T); % data buffer for the identification error 84 | 85 | % and apply least mean square algorithm 86 | mu=0.1; % learning rate 87 | for k=1:T, % discrete time k 88 | Shx=[x_iden(k) Shx(1:15)]; % update the state 89 | Shy=sum(Shx.*Shw); % calculate output of Sh(z) 90 | e_iden(k)=y_iden(k)-Shy; % calculate error 91 | Shw=Shw+mu*e_iden(k)*Shx; % adjust the weight 92 | end 93 | 94 | % Lets check the result 95 | subplot(2,1,1) 96 | plot([1:T], e_iden) 97 | ylabel('Amplitude'); 98 | xlabel('Discrete time k'); 99 | legend('Identification error'); 100 | subplot(2,1,2) 101 | stem(Sw) 102 | hold on 103 | stem(Shw, 'r*') 104 | ylabel('Amplitude'); 105 | xlabel('Numbering of filter tap'); 106 | legend('Coefficients of S(z)', 'Coefficients of Sh(z)') 107 | 108 | 109 | % The second task is the active control itself. Again, we need to simulate 110 | % the actual condition. In practice, it should be an iterative process of 111 | % 'measure', 'control', and 'adjust'; sample by sample. Now, let's generate 112 | % a narrow-band noise: 113 | X=0.1*randn(1,T)+0.9*cos(2*pi*(1/5)*[0:T-1]); 114 | 115 | % and measure the arriving noise at the sensor position, 116 | Yd=filter(Pw, 1, X); 117 | 118 | % We do not have any reference signal because there is no reference sensor. 119 | % Instead, it has to be estimated. So, lets prepare an empty buffer 120 | Xh=zeros(size(X)); 121 | 122 | % Initiate the system, 123 | Cx=zeros(1,16); % the state of C(z) 124 | Cw=zeros(1,16); % the weight of C(z) 125 | Cyx=zeros(1,16); % the state for the estimate of control signal 126 | Sx=zeros(size(Sw)); % the state for the secondary path 127 | Xhx=zeros(1,16); % the state of the filtered x(k) 128 | e_cont=zeros(1,T); % data buffer for the control error 129 | 130 | % send the first sample of control signal, 131 | k=1; 132 | Cx=[Xh(k) Cx(1:15)]; % update the controller state 133 | Cy=sum(Cx.*Cw); % calculate the controller output 134 | Sx=[Cy Sx(1:length(Sx)-1)]; % propagate to secondary path 135 | e_cont(k)=Yd(k)-sum(Sx.*Sw);% measure the residue 136 | 137 | % and start the FbLMS algorithm 138 | mu=0.1; % learning rate 139 | for k=2:T, % discrete time k 140 | Cyx=[Cy Cyx(1:15)]; % update the state for control signal 141 | Xh(k)=e_cont(k-1)+sum(Cyx.*Shw); % estimate reference signal 142 | 143 | Cx=[Xh(k) Cx(1:15)]; % update the controller state 144 | Cy=sum(Cx.*Cw); % calculate the controller output 145 | Sx=[Cy Sx(1:length(Sx)-1)]; % propagate to secondary path 146 | e_cont(k)=Yd(k)-sum(Sx.*Sw); % measure the residue 147 | 148 | Shx=[Xh(k) Shx(1:15)]; % update the state of Sh(z) 149 | Xhx=[sum(Shx.*Shw) Xhx(1:15)]; % calculate the filtered x(k) 150 | Cw=Cw+mu*e_cont(k)*Xhx; % adjust the controller weight 151 | end 152 | 153 | % Report the result 154 | figure 155 | subplot(2,1,1) 156 | plot([1:T], e_cont) 157 | ylabel('Amplitude'); 158 | xlabel('Discrete time k'); 159 | legend('Noise residue') 160 | subplot(2,1,2) 161 | plot([1:T], Yd) 162 | hold on 163 | plot([1:T], Yd-e_cont, 'r:') 164 | ylabel('Amplitude'); 165 | xlabel('Discrete time k'); 166 | legend('Noise signal', 'Control signal') 167 | -------------------------------------------------------------------------------- /without_secondary_estimate.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | 4 | % T = 1000; %simulation duration 5 | fs=8000; 6 | t=0:1/fs:1; 7 | T=length(t)-1; 8 | 9 | Pw=[0.9 -0.3 0.7 -0.28 0.5 -0.25 0.36 -0.22 0.3 -0.18 0.28 -0.15 0.22 -0.1 0.2 -0.1 0.14 -0.08 0.1 -0.05 0.05 -0.03 0.02 -0.01 0.01 -0.01]; 10 | % Pw = exp(-(1:length(P))).*P; 11 | % Sw = fir1(13,0.3); 12 | Sw=Pw(13:end)*0.5; 13 | 14 | %% assume Sw = s_hat_w 15 | L = 16; %filter order 16 | X = randn(1,T); % define the input noise(source signal) 17 | d = filter(Pw,1,X); % desired signal (signal at the error microphone) 18 | x_hat = filter(Sw,1,X); 19 | 20 | % Initialization of Active Noise Control 21 | Cx = zeros(1,L); %reference signal vector of W(z) 22 | Cw = zeros(1,L); %coefficient vector of W(z) 23 | X_s = zeros(1,L); 24 | e = zeros(1,T); %define error value 25 | 26 | 27 | mu = 0.1 28 | for n = 1:T 29 | Cx = [x_hat(n) Cx(1:L-1)]; 30 | y = sum(Cx.*Cw); 31 | e(n) = d(n) - y; 32 | X_s = [x_hat(n) X_s(1:L-1)]; 33 | Cw = Cw + mu*e(n)*X_s; 34 | end 35 | figure 36 | subplot(2,1,1) 37 | plot([1:T],e) 38 | ylabel('Amplitude'); 39 | xlabel('Discrete time n'); 40 | legend('Noise residual'); 41 | 42 | subplot(2,1,2) 43 | plot([1:T],d) 44 | hold on 45 | plot([1:T],d-e,'r:') %d-e right; y wrong ????; 46 | ylabel('Amplitude'); 47 | xlabel('Discrete time n'); 48 | legend('Noise signal','Control signal'); 49 | 50 | ratio = abs(e.^2)./abs(d.^2); 51 | dB = 20*log10(ratio); 52 | figure 53 | plot(1:T,dB,'.',1:T,zeros(1,T)) --------------------------------------------------------------------------------