Mercurial > hg > aimmat
view aim-mat/modules/sai/ti2003/gen_ti2003.m @ 4:537f939baef0 tip
various bug fixes and changed copyright message
author | Stefan Bleeck <bleeck@gmail.com> |
---|---|
date | Tue, 16 Aug 2011 14:37:17 +0100 |
parents | 20ada0af3d7d |
children |
line wrap: on
line source
% generating function for 'aim-mat' %function returnframes=gen_ti2003(nap,strobes,options) % % INPUT VALUES: % % RETURN VALUE: % % time integration % (c) 2011, University of Southampton % Maintained by Stefan Bleeck (bleeck@gmail.com) % download of current version is on the soundsoftware site: % http://code.soundsoftware.ac.uk/projects/aimmat % documentation and everything is on http://www.acousticscale.org function returnframes=gen_ti2003(nap,strobes,options) % calculates the stablized image from the data given in options if isfield(options,'do_click_reduction'); do_click_reduction=options.do_click_reduction; if do_click_reduction try load(options.click_reduction_sai); catch error('cant load file for click reduction. Generate it with ''generate_clicktrain_normal'''); end % load click_frame; end else do_click_reduction=0; end if isfield(options,'single_channel_do') single_channel_do=logical(options.single_channel_do); else single_channel_do=logical(false); end if isfield(options,'do_times_nap_height') donapheight=options.do_times_nap_height; % if the strobe height has an influence else donapheight=0; % not per default end if isfield(options,'single_channel_channel_nr') single_channel_channel_nr=options.single_channel_channel_nr; else single_channel_channel_nr=0; end if isfield(options,'single_channel_time_step') single_channel_time_step=options.single_channel_time_step; graphic_times=single_channel_time_step:single_channel_time_step:getlength(nap); % each ms next_graphic=graphic_times(1); current_graphic=1; else next_graphic=[]; current_graphic=0; graphic_times=[]; end if isfield(options,'select_channel_center_frequency') % center frequency for the selection (off, if 0) select_channel_center_frequency=options.select_channel_center_frequency; if select_channel_center_frequency > 0 select_certain_channels=1; % upper and lower bound of selection in octaves select_channel_frequency_above=options.select_channel_frequency_range_above; select_channel_frequency_below=options.select_channel_frequency_range_below; % calculate, which channels are wanted, and wich are not min_selected_frequency=select_channel_center_frequency/power(2,select_channel_frequency_below); max_selected_frequency=select_channel_center_frequency*power(2,select_channel_frequency_above); %if 1, then all are calculated, and selected are plotted in other color if options.select_channel_calculate_all==1; select_certain_channels=0; end else select_certain_channels=0; end else select_certain_channels=0; end returnframes=[]; maxdelay=options.maxdelay; mindelay=options.mindelay; % the weight of a strobe is determined by the time since the last strobe % adjusted by the following constant: (decay from 100% to 0%) % delay_time_strobe_weight_decay=options.delay_time_strobe_weight_decay; len=getlength(nap); fps=options.frames_per_second; output_times=0:1/fps:len; output_times=output_times+getminimumtime(nap); nr_output_times=length(output_times); % so many pictures in the end output_counter=1; % construct the starting SAI with zeros sr=getsr(nap); sampletime=1/sr; nrdots_insai=round(options.maxdelay*sr); const_memory_decay=power(0.5,1/(options.buffer_memory_decay*sr)); % the amount per sampletime signal_start_time=getminimumtime(nap); nr_channels=getnrchannels(nap); % calculate the initial strobe times in the past for ii=1:nr_channels if length(strobes{ii}.strobes) > 0 next_strobe(ii)=strobes{ii}.strobes(1); % the next strobe in line else next_strobe(ii)=inf; % no strobe end last_strobe(ii)=-inf; % the last strobe in this channel current_strobe_nr(ii)=1; % the current number of the strobe which is processed nr_active_strobes(ii)=0; % the number of active strobes in memory last_strobe(ii)=-inf; % the last strobe was long ago strobe_adjust_phase(ii)=inf; % the next update of weights was_adjusted(ii)=0; end nr_maximal_strobes=100; stropo_time=zeros(nr_channels,nr_maximal_strobes); % no active strobes in queue copy_stropo_time=stropo_time; stropo_weight=zeros(nr_channels,nr_maximal_strobes); % no active strobes in queue stropo_org_weight=zeros(nr_channels,nr_maximal_strobes); % the weight of each strobe at generation point % calculate the inital strobe settings in one variable (accelleration) maxst=0; for ii=1:nr_channels % make strobes faster maxstg=length(strobes{ii}.strobes); maxst=max(maxst,maxstg); end allstrobes=zeros(nr_channels,maxst); for ii=1:nr_channels % make strobes faster nr_str_total=length(strobes{ii}.strobes); allstrobes(ii,1:nr_str_total)=strobes{ii}.strobes; allstrobesval(ii,1:nr_str_total)=strobes{ii}.strobe_vals; nrstrobes(ii)=nr_str_total; end do_fixed_weights=0; if strcmp(options.criterion,'fixed_weights') do_fixed_weights=1; fixed_weights=zeros(nr_channels,100); for ii=1:nr_channels a=strobes{ii}.strobe_weights; fixed_weights(ii,1:length(a))=a'; end end nr_dots=getnrpoints(nap); current_time=signal_start_time; times_per_ms=round(sr*0.005); % how often the bar should be updated cfs=getcf(nap); napvalues=getvalues(nap); count=0; tic; % copy some vairables weight_threshold=options.weight_threshold; strobe_weight_alpha=options.strobe_weight_alpha; delay_weight_change=options.delay_weight_change; % criterion=options.criterion; do_adjust_weights=options.do_adjust_weights; do_normalize=options.do_normalize; % if weights are do_normalized % each strobe induces strobes in neighboring channels in this % vicinity: if isfield(options,'erb_frequency_integration') erb_strobe_width=options.erb_frequency_integration; erbdensity=erbdensity(nap); nrintegrate=round(erbdensity*erb_strobe_width); do_interchannel_interaction=1; else do_interchannel_interaction=0; nrintegrate=0; end % if strcmp(criterion,'integrate_erbs') % % define the integration area for each channel in frequency and time % erbsearchwidth=options.erb_frequency_integration; % erbdensity=erbdensity(nap); % nrintegrate=round(erbdensity*erbsearchwidth); % % for ii=1:nr_channels % % the frequency window % a=ii+(-nrintegrate:nrintegrate); % a(find(a<0))=0; % a(find(a>nr_channels))=0; % a(find(a==ii))=0; % dont search in the identical channel % % neighboring_channels(ii,:)=a; % % % the time window % current_cf=cfs(ii); % timewindow_start(ii)=-1/current_cf; % timewindow_stop(ii)=1/current_cf; % end % end % % Beschleunigung der Berechnung durch vorziehen der Schleife: % der Einfluß der Zeit: je mehr Strobes da sind, % umso unwichtiger werden die älteren: % adapt the weights of all the old strobes weighfactor=ones(nr_maximal_strobes); if do_adjust_weights %only if wanted for ii=1:nr_maximal_strobes for jj=1:ii wfactor=power(1/(ii-jj+1),strobe_weight_alpha); weighfactor(ii,jj)=wfactor; end end end if single_channel_do==1 oldfigure=gcf; onechannelfigure=figure(1954211404); % some strange number that should not be an existing figure set(onechannelfigure,'name','Dynamic single channel'); set(onechannelfigure,'numbertitle','off'); end saibuffer=zeros(nr_channels,nrdots_insai); if nr_channels>1 waithand=waitbar(0,'generating SAI'); end for bintime=1:nr_dots if nr_channels>1 if mod(bintime,times_per_ms)==0 waitbar(bintime/nr_dots); end end current_time=current_time+sampletime; for channel_nr=1:nr_channels % for channel_nr=25 current_cf=cfs(channel_nr); if select_certain_channels if current_cf < min_selected_frequency || current_cf > max_selected_frequency continue; % outside wanted range, no need to calculate! end end nr_str_total=nrstrobes(channel_nr); channelallstrobes=allstrobes(channel_nr,1:nr_str_total); % all the strobes in this channel nr_active_str=nr_active_strobes(channel_nr); nr_current_str=current_strobe_nr(channel_nr); % find out, if a new strobe arrived this_strobe_time=next_strobe(channel_nr); % here is the next strobe if current_time > this_strobe_time % if we are beyond the next strpbe if nr_current_str < nrstrobes(channel_nr) % define the next strobe next_strobe(channel_nr) =channelallstrobes(nr_current_str + 1); else next_strobe(channel_nr)=inf; % if no more strobes we will never get here any more end nr_current_str=nr_current_str+1; % if strcmp(criterion,'integrate_erbs') % % find out, which weight this strobe has by integration over % % time and frequency of the neighbouring strobes % t1=timewindow_start(channel_nr)+current_time; % t2=timewindow_stop(channel_nr)+current_time; % strobeweight=zeros(nr_channels,1); % normalizer=0; % for chn=neighboring_channels(channel_nr,:); % if chn>0 % nrstr=nrstrobes(chn); % chstr=allstrobes(chn,1:nrstr); % all strobes in this channel % neistrobes=find(chstr>t1 & chstr<t2); % these are all strobes in this channel in the window % nr=length(neistrobes); % so many % dist=abs(channel_nr-chn); % weight=(1+nrintegrate-dist)/nrintegrate; % its influence depends on the distance % strobeweight(chn)=nr*weight; % normalizer=normalizer+weight; % end % end % new_strobe_weight=sum(strobeweight)/normalizer; % end nr_active_str=nr_active_str+1; stropo_time(channel_nr,nr_active_str)=this_strobe_time; % calculate the weight from the time, the last strobe was away: new_weight=(this_strobe_time-last_strobe(channel_nr))*current_cf/10; new_weight=min(1,new_weight); if do_fixed_weights==1 new_weight=fixed_weights(channel_nr,nr_current_str-1)/max(max(fixed_weights)); new_weight=min(1,new_weight); new_weight=max(0.00001,new_weight); end stropo_org_weight(channel_nr,nr_active_str)=new_weight; % the new strobe is there, but it is not effective jet! It will % become effective after: phasetime=current_time+1/current_cf*delay_weight_change; strobe_adjust_phase(channel_nr)=phasetime; was_adjusted(channel_nr)=0; last_strobe(channel_nr)=this_strobe_time; % remember last strobe end % a new strobe is in the line, but its not active yet! % is it time to make a new strobe active and adjust weights? logi1=logical(current_time >= strobe_adjust_phase(channel_nr)); logi2=~logical(was_adjusted(channel_nr)); % ugly, but accelerated logi3= nr_active_str>0; if logi1 && logi2 && logi3 % jetzt ist Zeit zum Adjusten, erst mal alle auf das % Orginalgewicht (Zahl der Zyclen) % % jetzt der Einfluß der Zeit: je mehr Strobes da sind, % % umso unwichtiger werden die älteren: % % adapt the weights of all the old strobes % weighfactor=ones(length(nr_active_str),1); % if do_adjust_weights %only if wanted % for ii=1:nr_active_str % wfactor=power(1/(nr_active_str-ii+1),strobe_weight_alpha); % weighfactor(ii)=wfactor; % end % else % stropo_weight=stropo_org_weight; % end if do_adjust_weights %only if wanted wfactor=weighfactor(nr_active_str,:); % und dann alle Strobes in diesem Kanal auf eins % normieren, damit die Summe über alle Aktivität in jedem % Channel immer gleich der Summe im Nap ist. % normalise them to 1 if do_normalize==1 if nr_active_str>1 sumweight=0; for ii=1:nr_active_str sumweight=sumweight+stropo_org_weight(channel_nr,ii)*wfactor(ii); end for ii=1:nr_active_str tmp=stropo_org_weight(channel_nr,ii)*wfactor(ii); tmp=tmp/sumweight; stropo_weight(channel_nr,ii)=tmp; end end end else stropo_weight=stropo_org_weight; end % do_normalize was_adjusted(channel_nr)=1; end % strobe has arrived % delete old strobe processes nr_deleted=0; for ii=1:nr_active_str-nr_deleted time_strobe=stropo_time(channel_nr,ii-nr_deleted); delay=current_time-time_strobe; weight=stropo_weight(channel_nr,ii-nr_deleted); if delay > maxdelay || weight < weight_threshold % forget this strobe stropo_time(channel_nr,ii-nr_deleted:end-1)=stropo_time(channel_nr,ii-nr_deleted+1:end); stropo_weight(channel_nr,ii-nr_deleted:end-1)=stropo_weight(channel_nr,ii-nr_deleted+1:end); stropo_org_weight(channel_nr,ii-nr_deleted:end-1)=stropo_org_weight(channel_nr,ii-nr_deleted+1:end); nr_deleted=nr_deleted+1; end end nr_active_str=nr_active_str-nr_deleted; % bug found by Federico Flego % if nr_active_str-count~=0, allstrobesval(channel_nr,:)=shift(allstrobesval(channel_nr,:),-(nr_active_str-count)); % end; % process all strobes for ii=1:nr_active_str time_strobe=stropo_time(channel_nr,ii); delay=current_time-time_strobe; if delay >= mindelay current_time_int=floor((current_time-signal_start_time)/sampletime); delayint=round(delay/sampletime); weight=stropo_weight(channel_nr,ii); % if donapheight==0 % if the strobe heigt has influence % weight=weight*allstrobesval(channel_nr,ii); % end oldval=saibuffer(channel_nr,delayint); newval=oldval+weight*napvalues(channel_nr,current_time_int); saibuffer(channel_nr,delayint)=newval; % put the new value in the buffer at the correct position % interchannel interaction if do_interchannel_interaction for jj=channel_nr-nrintegrate:channel_nr+nrintegrate if jj==ii || jj<1 || jj>nr_channels continue end oldval=saibuffer(jj,delayint); adjacent_weight=weight*(1-abs(jj-channel_nr)/(nrintegrate+1)); newval=oldval+adjacent_weight*napvalues(jj,current_time_int); saibuffer(jj,delayint)=newval; % put the new value in the buffer at the correct position end end end end % save for the next run current_strobe_nr(channel_nr)=nr_current_str; % strobe counter nr_active_strobes(channel_nr)=nr_active_str; % active strobe counter % special graphics, when only one channel: display signal, % threshold and strobe weights if single_channel_do && channel_nr==single_channel_channel_nr if current_time>=next_graphic if current_graphic<length(graphic_times) next_graphic=graphic_times(current_graphic+1); current_graphic=current_graphic+1; end extraplot(onechannelfigure,napvalues,sr,current_time,maxdelay,options,bintime,nr_active_str,saibuffer,stropo_time,stropo_weight,single_channel_channel_nr) end end end % nr channels % decay of the whole buffer: saibuffer=saibuffer*const_memory_decay; % output finished frames at the appropriate times if current_time >= output_times(output_counter) if do_click_reduction reduced_saibuffer=saibuffer; for channel_nr=1:nr_channels org_channel=saibuffer(channel_nr,:); org_sig=signal(org_channel); org_sig=setsr(org_sig,sr); clickvals_sig=getsinglechannel(click_frame,channel_nr); relevant_click_time=0.035; clicksig=getpart(clickvals_sig,0,relevant_click_time); % clicksig=changesr(clicksig,sr); org_sig_part=getpart(org_sig,0,relevant_click_time); maxval=max(org_sig); clicksig=scaletomaxvalue(clicksig,maxval); new_sig=org_sig-clicksig; new_sig=halfwayrectify(new_sig); grafix=0; if grafix==1 figure(324234) clf hold on plot(clicksig,'m'); plot(org_sig,'b'); plot(new_sig,'r'); end newvals=getvalues(new_sig); reduced_saibuffer(channel_nr,:)=newvals'; end resframes{output_counter}=reduced_saibuffer; else resframes{output_counter}=saibuffer; end output_counter=output_counter+1; if output_counter >nr_output_times break; % no need to go on! end end end if single_channel_do==1 figure(oldfigure); end % translate the arrays from data to frames nrfrms=length(resframes); start_time=getminimumtime(nap); % start time of first frame if nrfrms>1 interval=output_times(2)-output_times(1); else interval=0; % doesnt matter... end maxval=-inf; maxsumval=-inf; maxfreval=-inf; cfs=getcf(nap); if nr_channels>1 for ii=1:nrfrms cfr=frame(resframes{ii}); maxv=getmaximumvalue(cfr); maxval=max([maxv maxval]); maxs=max(getsum(cfr)); maxsumval=max([maxs maxsumval]); maxf=max(getfrequencysum(cfr)); maxfreval=max([maxf maxfreval]); end else maxfreval=1; maxsumval=1; maxval=1; end for ii=1:nrfrms cfr=frame(resframes{ii}); cfr=setsr(cfr,sr); cfr=setcurrentframenumber(cfr,ii); cfr=setcurrentframestarttime(cfr,start_time); cfr=setcf(cfr,cfs); start_time=start_time+interval; cfr=setscalesumme(cfr,maxsumval); cfr=setallmaxvalue(cfr,maxval); cfr=setallminvalue(cfr,0); cfr=setscalefrequency(cfr,maxfreval); returnframes{ii}=cfr; end if nr_channels>1 close(waithand); end % function for one channel: Plot some nice graphic function extraplot(onechannelfigure,napvalues,sr,current_time,maxdelay,options,bintime,nr_active_str,saibuffer,stropo_time,stropo_weight,channel_nr) persistent maxamp; % how big the biggest amplitude was so far if isempty(maxamp) maxamp=0; end figure(onechannelfigure); subplot(2,1,1); % the signal, threshold and strobes: cla single_channel= signal(napvalues(channel_nr,:),sr); maxval=max(single_channel); siglen=getlength(single_channel); threshold=getsinglechannel(options.thresholds,channel_nr); if current_time < maxdelay single_channel=getpart(single_channel,0,maxdelay); threshold=getpart(threshold,0,maxdelay); else % try single_channel=getpart(single_channel,current_time-maxdelay,current_time); % catch % a=0; % end threshold=getpart(threshold,current_time-maxdelay,current_time); end plot(single_channel,'-');hold on ax=axis; ax(4)=maxval*1.3; axis(ax); line([time2bin(single_channel,current_time) time2bin(single_channel,current_time)],[0 1],'Color','red'); title('nap, threshold and strobes'); thresholdvals=getvalues(threshold); if current_time<getlength(threshold) plotthtesbins=bintime; else plotthtesbins=getnrpoints(threshold); end plot(1:plotthtesbins,thresholdvals(1:plotthtesbins),'.-g','MarkerSize',1); for ii=1:nr_active_str time_strobe=stropo_time(channel_nr,ii); weight=stropo_weight(channel_nr,ii); x=time2bin(single_channel,time_strobe); y=gettimevalue(single_channel,time_strobe); gc=plot(x,y,'.r'); suze=log(2000*weight)*5; suze=max(suze,5); set(gc,'MarkerSize',suze); wei=sprintf('%2.0f',weight*100); text(x,y,wei,'HorizontalAlignment','center','FontSize',8); end subplot(2,1,2); % the saibuffer so far: buffer=signal(saibuffer(channel_nr,:),sr); buffer=reverse(buffer); maximum_time_interval=getmaximumtime(buffer); minimum_time_interval=getminimumtime(buffer); nrx=getnrpoints(buffer); plot(buffer); if max(buffer)>maxamp maxamp=max(buffer); end set(gca,'Ylim',[-0.00001 maxamp*1.1]); nr_labels=8; tix=1:(nrx-1)/nr_labels:nrx; xstep=(maximum_time_interval-minimum_time_interval)*1000/(nr_labels); %works from -35 to 5 ti=([minimum_time_interval*1000:xstep:maximum_time_interval*1000+1]); ti=ti(end:-1:1); ti=round(ti*10)/10; set(gca,'XScale','linear') set(gca,'XTick',tix); set(gca,'XTickLabel',ti); xlabel('delay (ms)'); title('buffer'); drawnow; return