0001 function [y,yy]=nt_zapline(x,fline,nremove,p,plotflag)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 try, nt_greetings; catch, disp('You must download NoiseNools from http://audition.ens.fr/adc/NoiseTools/'); return; end
0031
0032 assert(nargin>=2, '!');
0033 if nargin<3||isempty(nremove); nremove=1; end
0034 if nargin<4; p=[]; end
0035 if ~isfield(p,'nfft'); p.nfft=512; end
0036 if ~isfield(p,'nkeep'); p.nkeep=[]; end
0037 if ~isfield(p,'niterations'); p.niterations=1; end
0038 if ~isfield(p,'fig1'); p.fig1=100; end
0039 if ~isfield(p, 'fig2'); p.fig2=101; end
0040 if nargin<5||isempty(plotflag); plotflag=0; end
0041
0042 if isempty(x); error('!'); end
0043 if nremove>=size(x,1); error('!'); end
0044 if fline>1/2; error('fline should be less than Nyquist'); end
0045 if size(x,1)<p.nfft; warning(['reducing nfft to ',num2str(size(x,1))]); p.nfft=2*floor(size(x,1)/2); end
0046
0047 if ~nargout || plotflag
0048
0049 y=nt_zapline(x,fline,nremove,p);
0050 disp('proportion of non-DC power removed:');
0051 disp(nt_wpwr(x-y)/nt_wpwr(nt_demean(x)));
0052
0053 figure(p.fig2); clf;
0054 subplot 121
0055 [pxx,f]=nt_spect_plot(x/sqrt(mean(x(:).^2)),p.nfft,[],[],1/fline);
0056 divisor=sum(pxx);
0057 semilogy(f,abs(pxx)/divisor);
0058 legend('raw'); legend boxoff
0059 set(gca,'ygrid','on','xgrid','on');
0060 xlabel('frequency (relative to line)');
0061 ylabel('relative power');
0062 yl1=get(gca,'ylim');
0063 hh=get(gca,'children');
0064 set(hh(1),'color','k')
0065 subplot 122
0066 [pxx,f]=nt_spect_plot((x-y)/sqrt(mean(x(:).^2)),p.nfft,[],[],1/fline);
0067 semilogy(f,abs(pxx)/divisor);
0068 hold on
0069 [pxx,f]=nt_spect_plot(y/sqrt(mean(x(:).^2)),p.nfft,[],[],1/fline);
0070 semilogy(f,abs(pxx)/divisor);
0071 hold on
0072 legend('noise', 'clean'); legend boxoff
0073 set(gca,'ygrid','on','xgrid','on');
0074 set(gca,'yticklabel',[]); ylabel([]);
0075 xlabel('frequency (relative to line)');
0076 yl2=get(gca,'ylim');
0077 hh=get(gca,'children');
0078 set(hh(2),'color',[1 .5 .5]);
0079 set(hh(1), 'linewidth', 0.25);
0080 set(hh(1), 'color', [ 0 .7 0]);
0081 set(hh(1),'linewidth', 2);
0082
0083 yl(1)=min(yl1(1),yl2(1)); yl(2)=max(yl1(2),yl2(2));
0084 subplot 121; ylim(yl); subplot 122; ylim(yl);
0085 drawnow;
0086 return
0087 end
0088 if ~nargout
0089 clear y yy
0090 return
0091 end
0092
0093 xx=nt_smooth(x,1/fline,p.niterations);
0094 if isempty(p.nkeep); p.nkeep=size(x,2); end
0095 xxxx=nt_pca(x-xx,[],p.nkeep);
0096
0097
0098 nHarmonics=floor((1/2)/fline);
0099 [c0,c1]=nt_bias_fft(xxxx,fline*(1:nHarmonics), p.nfft);
0100
0101 [todss,pwr0,pwr1]=nt_dss0(c0,c1);
0102 assert(size(todss,2)>0, '!');
0103 if ~nargout;
0104 figure(p.fig1); clf;
0105 plot(pwr1./pwr0, '.-'); xlabel('component'); ylabel('score'); title('DSS to enhance line frequencies');
0106 end
0107 xxxx=nt_mmat(xxxx,todss(:,1:nremove));
0108 xxx=nt_tsr(x-xx,xxxx);
0109 clear xxxx
0110
0111
0112 y=xx+xxx; clear xx xxx
0113 yy=x-y;
0114
0115
0116 if 0
0117 sr=400;
0118 nsamples=100000; nchans=100;
0119 signal=randn(nsamples,nchans);
0120 artifact=sin((1:nsamples)'/sr*2*pi*50);
0121 artifact=max(artifact,0).^3;
0122 artifact=3*nt_demean(artifact*randn(1,nchans));
0123 disp(nt_wpwr(artifact)/nt_wpwr(signal+artifact));
0124 nt_zapline(signal+artifact,50/sr);
0125 end
0126