tomwalters@0: % tool tomwalters@0: % tomwalters@0: % INPUT VALUES: tomwalters@0: % tomwalters@0: % RETURN VALUE: tomwalters@0: % tomwalters@0: % bleeck@3: % (c) 2011, University of Southampton bleeck@3: % Maintained by Stefan Bleeck (bleeck@gmail.com) bleeck@3: % download of current version is on the soundsoftware site: bleeck@3: % http://code.soundsoftware.ac.uk/projects/aimmat bleeck@3: % documentation and everything is on http://www.acousticscale.org bleeck@3: tomwalters@0: tomwalters@0: function pitch=combfrePtiPdots(framestruct_a); tomwalters@0: % combined graphic of frequency axis and time interval axis tomwalters@0: % on one axis tomwalters@0: % plots one graphic that consists of two parts: tomwalters@0: % the frequency profile and the interval profile on one axis tomwalters@0: tomwalters@0: if nargin < 2 tomwalters@0: grafix=0; % for debugging tomwalters@0: end tomwalters@0: dot_scaler=200; % wie gross Punkte dargestellt werden sollen in Punkt tomwalters@0: tomwalters@0: % wie weit die Intervallsumme runterskaliert werden muss, damit die Zahlen vernünftigt werden tomwalters@0: norm_intervalhight=100; tomwalters@0: % wie weit die spektrale Summe runterskaliert werden muss, damit die Zahlen vernünftigt werden tomwalters@0: norm_spektralhight=10; tomwalters@0: tomwalters@0: % how big must the contrast of the envelope be to be recognised as one pitch tomwalters@0: envcontrast_threshold=0.15; tomwalters@0: tomwalters@0: % A single factor, that can vary between tomwalters@0: % 0 = complete attention to temporal structure tomwalters@0: % 1 = complete attention to spectral structure tomwalters@0: spectral_attention_factor=0.5; tomwalters@0: tomwalters@0: if ~isstruct(framestruct_a) tomwalters@0: framestruct.current_frame=framestruct_a; tomwalters@0: else tomwalters@0: framestruct=framestruct_a; tomwalters@0: end tomwalters@0: tomwalters@0: if isfield(framestruct_a,'plot_only_highest') % if only one dot per line shell be plotted tomwalters@0: plot_only_highest=framestruct_a.plot_only_highest; tomwalters@0: else tomwalters@0: plot_only_highest=0; tomwalters@0: end tomwalters@0: tomwalters@0: if isfield(framestruct_a,'plot_bw') % on paper work with different colors tomwalters@0: plot_bw=framestruct_a.plot_bw; tomwalters@0: else tomwalters@0: plot_bw=0; tomwalters@0: end tomwalters@0: tomwalters@0: if isfield(framestruct_a,'normalise') % normalize the frame to a fixed value to get rid of effects of loudness and strobing points tomwalters@0: normalise=framestruct_a.normalise; tomwalters@0: else tomwalters@0: normalise=0; tomwalters@0: end tomwalters@0: tomwalters@0: % ob vorher die Region unten rechts rausgeworfen werden soll tomwalters@0: if ~isfield(framestruct_a,'extract_pitch_region'); tomwalters@0: extract_pitch_region=0; tomwalters@0: else tomwalters@0: extract_pitch_region=framestruct_a.extract_pitch_region; tomwalters@0: end tomwalters@0: tomwalters@0: current_frame=framestruct.current_frame; tomwalters@0: tomwalters@0: % Wheh normalized, it is assumed that the overall energy in the stimulus is tomwalters@0: % always the same tomwalters@0: if normalise tomwalters@0: current_frame=normaliseto(current_frame,1); tomwalters@0: end tomwalters@0: tomwalters@0: pitch_current_frame=current_frame; tomwalters@0: if extract_pitch_region tomwalters@0: % schmeisse die physikalisch nicht sinnvollen Bereiche raus! tomwalters@0: current_frame=extractpitchregion(current_frame); tomwalters@0: end tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % % hier werden die Quellen berechnet: tomwalters@0: parameters=framestruct; tomwalters@0: pitch=calcresidualprobability(pitch_current_frame,parameters); tomwalters@0: tomwalters@0: % calculate the sum of the frequencies tomwalters@0: fresumme=getfrequencysum(current_frame); tomwalters@0: tomwalters@0: nrchannels=getnrchannels(current_frame); tomwalters@0: smoothwidth=128/nrchannels; tomwalters@0: % smooth the sum with a smoothwidth of 1 tomwalters@0: fresumme=smooth(fresumme,smoothwidth); tomwalters@0: tomwalters@0: % calculate the sum from interval profile tomwalters@0: intsumme=getsum(current_frame); tomwalters@0: tomwalters@0: % scaling value, if in a movie tomwalters@0: scale_summe=getsumscale(current_frame); tomwalters@0: tomwalters@0: % start plotting: tomwalters@0: % clf; tomwalters@0: tomwalters@0: % bastel zwei lineare Funktionen zusammen: eine aus dem zeitlichen Verlauf, tomwalters@0: % und eine aus dem spektralen. tomwalters@0: minimum_time_interval=1; tomwalters@0: maximum_time_interval=32; tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % Die Intervallsumme muss von linear auf logarithmisch umgestellt werden tomwalters@0: nr_points=getnrpoints(intsumme); tomwalters@0: intervalsum=logsigx(intsumme,-maximum_time_interval/1000,-minimum_time_interval/1000,nr_points); tomwalters@0: intervalsum=setstarttime(intervalsum,0); tomwalters@0: % ab nun haben wir eine lineare Zeitachse mit logarithmischen Werten tomwalters@0: tomwalters@0: global fnull;global stepsperoctave; % brauch ich unten in den Unterfunktionen tomwalters@0: fnull=1000/maximum_time_interval; % per Definition die niedrigste Frequenz = Anfangsfrequenz der gesamten Achse tomwalters@0: tomwalters@0: % soviel "cent" hat die Zeitachse. tomwalters@0: stepsperoctave=log2(maximum_time_interval/minimum_time_interval)/getnrpoints(intervalsum); % soviel octaven/Pixel tomwalters@0: intervalsum=setsr(intervalsum,1/stepsperoctave); tomwalters@0: % intervalsum now goes from -32 to -1 ms in the interval profile tomwalters@0: % empirische Werte zum Skalieren auf einen einheitlichen Wert (1) tomwalters@0: intervalsum=scale(intervalsum,norm_intervalhight); tomwalters@0: tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % Die Frequenzsumme tomwalters@0: % plot the frequency profile in the same Graphic tomwalters@0: cfs=getcf(current_frame); tomwalters@0: minimum_fre=cfs(1); % the lowest frequency tomwalters@0: maximum_fre=cfs(end); % the lowest frequency tomwalters@0: tomwalters@0: total_length=f2p(maximum_fre); % gesamte Länge des Plots tomwalters@0: start_fre_profile=f2p(minimum_fre); % Startpunkt der Frequenzachse tomwalters@0: stop_int_profile=f2p(1000/minimum_time_interval); % Ende des Überlapps tomwalters@0: tomwalters@0: nr_addpoints=total_length-stop_int_profile; % soviel Punkte müssen hinten an die Intervallachse tomwalters@0: tsig=signal(zeros(floor(nr_addpoints),1),getsr(intervalsum)); % Ein Nullensignal mit den richtigen Daten tomwalters@0: intervalsum=append(intervalsum,tsig); % hänge es an die Intervallsumme hinten an tomwalters@0: % empirische Werte zum Skalieren auf einen einheitlichen Wert (1) tomwalters@0: tomwalters@0: % glätte die Frequenzachse: tomwalters@0: % intervalsum=smooth(intervalsum,smoothwidth); tomwalters@0: tomwalters@0: % Die Frequenzsumme muss von erb (oder cfs) auf logarithmisch umgestellt werden tomwalters@0: fresumme=erb2log(fresumme,cfs); tomwalters@0: tomwalters@0: nr_addpoints=start_fre_profile; % soviel Punkte müssen vor die Frequenzsumme gehängt werden tomwalters@0: tomwalters@0: % wieviel Punkte pro Octave in der Frequenzachse tomwalters@0: freoctrelation=log2(maximum_fre/minimum_fre)/getnrpoints(fresumme); % soviel octaven/Pixel tomwalters@0: fresumme=setsr(fresumme,1/freoctrelation); % anpassen der Zahl der Punkte auf die Intervalachse tomwalters@0: fresumme=changesr(fresumme,getsr(intervalsum)); tomwalters@0: tomwalters@0: tsig=signal(zeros(floor(nr_addpoints),1),getsr(fresumme)); % tomwalters@0: fresumme=scale(fresumme,norm_spektralhight); tomwalters@0: tomwalters@0: fresumme=append(tsig,fresumme); tomwalters@0: fresumme=setstarttime(fresumme,0); tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % plot it both tomwalters@0: if plot_bw tomwalters@0: han=plot(intervalsum,'k--'); tomwalters@0: set(han,'linewidth',1); tomwalters@0: else tomwalters@0: plot(intervalsum,'b'); tomwalters@0: end tomwalters@0: [intermaxpos,interminpos,intermax,intermin]=getminmax(intervalsum); tomwalters@0: intermaxpos=time2bin(intervalsum,intermaxpos); tomwalters@0: interminpos=time2bin(intervalsum,interminpos); tomwalters@0: hold on tomwalters@0: if plot_bw tomwalters@0: plot(fresumme,'k'); tomwalters@0: else tomwalters@0: plot(fresumme,'r'); tomwalters@0: end tomwalters@0: [fremaxpos,freminpos,fremax,fremin]=getminmax(fresumme); tomwalters@0: fremaxpos=time2bin(fresumme,fremaxpos); tomwalters@0: freminpos=time2bin(fresumme,freminpos); tomwalters@0: axis([1 getnrpoints(fresumme) 0 1]) tomwalters@0: % make x-Ticks tomwalters@0: nr_labels=8;ti=50*power(2,[0:7]);tix=f2p(ti);ti=round(ti*10)/10; tomwalters@0: set(gca,'XTick',tix);set(gca,'XTickLabel',ti); tomwalters@0: xlabel('Frequency [Hz]');ylabel('PitchStrength');title(''); tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: if plot_only_highest tomwalters@0: n=1; tomwalters@0: else tomwalters@0: n=length(pitch):-1:1; tomwalters@0: end tomwalters@0: tomwalters@0: % if ~isempty(pitch) % only, when temporal pitches occure tomwalters@0: frequencydots=sortstruct(pitch,'spektral_profile.activity'); tomwalters@0: for i=n tomwalters@0: % Plotte die blauen Punkte (Intervalle) tomwalters@0: pfre=pitch{i}.interval_profile.fre; tomwalters@0: xx=f2p(pfre); %das liegt wegen Rundungsfehlern zu weit links?? tomwalters@0: xx=getmaximumrightof(xx-1,intermaxpos,interminpos,intermax,intermin); tomwalters@0: hei=getbinvalue(intervalsum,xx); tomwalters@0: if i==1 tomwalters@0: radius=max(2,dot_scaler*pitch{i}.residuumpitchstrength); tomwalters@0: if plot_bw tomwalters@0: plot(xx,hei,'k.','MarkerSize',radius/2,'Marker','^','MarkerFaceColor','k'); tomwalters@0: else tomwalters@0: plot(xx,hei,'b.','MarkerSize',radius); tomwalters@0: end tomwalters@0: % text(xx+30,texthei*1.1,sprintf('%3.0f Hz %5.3f',pitch{i}.fre,pitch{i}.residuumpitchstrength)); % this is at a nice position tomwalters@0: % if pitch{i}.envcontrast > envcontrast_threshold tomwalters@0: a=text(xx+30,hei*1.2,sprintf('%3.0f Hz',pfre)); % this is at a nice position tomwalters@0: set(a,'Color','b'); tomwalters@0: % end tomwalters@0: else tomwalters@0: radius=max(2,dot_scaler*pitch{i}.residuumpitchstrength); tomwalters@0: plot(xx,hei,'b.','MarkerSize',radius); tomwalters@0: end tomwalters@0: tomwalters@0: % Plotte die roten Punkte (Frequenzen) tomwalters@0: pfre=chan2fre(current_frame,frequencydots{i}.spektral_profile.position); tomwalters@0: xx=f2p(pfre); % suche den Punkt auf dem nächsten Maximum um Rundungsfehler zu vermeiden tomwalters@0: xx2=getmaximumrightof(xx-1,fremaxpos,freminpos,fremax,fremin); tomwalters@0: if xx2/xx < 1.015 % wenn das nächste Maximum nah dran ist, dann wars ein Fehler tomwalters@0: xx=xx2; tomwalters@0: end tomwalters@0: hei=getbinvalue(fresumme,xx); tomwalters@0: radius=max(2,dot_scaler*frequencydots{i}.spektral_profile.hight); tomwalters@0: if plot_bw tomwalters@0: plot(xx,hei,'k.','MarkerSize',radius); tomwalters@0: else tomwalters@0: plot(xx,hei,'r.','MarkerSize',radius); tomwalters@0: end tomwalters@0: a=text(xx+30,hei*1.2,sprintf('%4.2f kHz',pfre/1000)); % this is at a nice position tomwalters@0: set(a,'Color','r'); tomwalters@0: tomwalters@0: end tomwalters@0: tomwalters@0: return tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: function f=p2f(pix) tomwalters@0: global fnull; tomwalters@0: global stepsperoctave; tomwalters@0: f=fnull*power(2,(pix-1)*stepsperoctave); tomwalters@0: return tomwalters@0: tomwalters@0: function p=f2p(fre) tomwalters@0: global fnull; tomwalters@0: global stepsperoctave; tomwalters@0: p=1/stepsperoctave*log2(fre/fnull)+1; tomwalters@0: return