Mercurial > hg > aimmat
diff aim-mat/modules/usermodule/pitchstrength/analyse_timeinterval_profile.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 | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aim-mat/modules/usermodule/pitchstrength/analyse_timeinterval_profile.m Tue Aug 16 14:37:17 2011 +0100 @@ -0,0 +1,338 @@ +% function [pitchstrength, dominant_time] = analyse_timeinterval_profile(ti_profile, peaks, a_priori, fqp_fq) +% +% To analyse the time interval profile of the auditory image +% +% INPUT VALUES: +% +% RETURN VALUE: +% + +% (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 result = analyse_timeinterval_profile(ti_profile,options) + +if nargin < 2 + options=[]; +end + +if isfield(options,'target_frequency') +end + +if ~isfield(options,'options') + target_frequency=0; +end + + +% for debug resons +plot_switch = 1; + + +intsum = ti_profile; +intsum_vals = getdata(intsum); +if plot_switch + minimum_time_interval=0; % in ms + maximum_time_interval=100; + figure(654654) + clf + tip = intsum_vals; + tip_x = bin2time(ti_profile, 1:length(tip)); % Get the times + tip_x = tip_x((tip_x>=(minimum_time_interval/1000)) & tip_x<=(maximum_time_interval/1000)); + tip = tip(time2bin(ti_profile, tip_x(1)):time2bin(ti_profile, tip_x(end))); + % tip_x is in ms. Change to Hz + tip_x = 1./tip_x; + plot(tip_x, tip, 'b'); + set(gca,'XScale','log'); + set(gca,'Ylim', [min(intsum)-10 max(intsum)+10]); + set(gca,'Xlim', [30 1500]); + hold on +end +if length(peaks)==0 + % If there is no peak than we just plot the function + pitchstrength = 0; + found_frequency = 0; + return +end + + +sig=envelope(intsum) + +% ++++++++++++ Part one: Peak finding ++++++++++ +% Calculate the envelope (curve of the peaks) + +% sort peaks from low time interval to a heigh one +% or from left to right +peaks_lr = sortstruct(peaks,'x'); % + +if plot_switch + px=[];py=[]; + for i=1:length(peaks) + px = [px tip_x(peaks{i}.x)]; + py = [py tip(peaks{i}.x)]; + end + plot(px,py,'kx'); +end + +% Create envelope of peaks +peak_envX = []; +peak_envY = []; +for i=1:length(peaks_lr) + peak_envX = [peak_envX peaks_lr{i}.x]; + peak_envY = [peak_envY peaks_lr{i}.y]; +end + +if plot_switch + plot(tip_x(peak_envX), peak_envY, ':k'); +end + + +% Find Maxima of the envelope +% create signal + +sig=buildfrompoints(sig,xx,yy) + + +peak_envsig = signal(length(peak_envX), 1); +peak_envsig = setvalues(peak_envsig, peak_envY); +params = 0; +peak_env_peaks = PeakPicker(peak_envsig, params); +% sort peaks of the envelope from low time interval to a heigh one +% or from left to right +peaks_env_peaks_lr = sortstruct(peak_env_peaks,'x'); % + +if plot_switch + for i=2:length(peaks_env_peaks_lr) % construct all maxima + fre=peaks_env_peaks_lr{i}.t; + plot(fre,gettimevalue(ti_profile,1/fre),'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',5); + end +end + +% % Now make sure, that highest peak is not the first peak of envelope +% peak_oi = peaks{1}; +% if (peak_oi.x == peak_envX(peaks_env_peaks_lr{1}.x)) +% % The first Peak is the heighest -> take second highest of envelope +% if (length(peak_env_peaks)>=2) +% poix = peak_envX(peak_env_peaks{2}.x); +% poiy = peak_env_peaks{2}.y; +% for i=1:length(peaks) +% if poix==peaks{i}.x +% peak_oi = peaks{i}; +% end +% end +% end +% end + + +% Stefans new method: +% Take the one with the highest contrast +if length(peaks_env_peaks_lr) > 1 + for i=2:length(peaks_env_peaks_lr) % construct all maxima + maxpeak=peaks_env_peaks_lr{i}.y; + minpeak1=peaks_env_peaks_lr{i}.left.y; + minpeak2=peaks_env_peaks_lr{i}.right.y; + minpeak=mean([minpeak1 minpeak2]); + + % the definition of pitch strength: Contrast + % contrast(i)=maxpeak/(mean([minpeak1 minpeak2])); + + % the difference between both + if maxpeak-minpeak > 0 + contrast(i)=(maxpeak-minpeak)/1000; + else + contrast(i)=0; + end + if plot_switch + fre=1/peaks{i}.t; + plot(fre,gettimevalue(ti_profile,1/fre),'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',5); + text(fre,gettimevalue(ti_profile,1/fre)*1.1,sprintf('%2.2f',contrast(i))); + end + end +else % there is only one peak + maxpeak=peaks{1}.y; + minpeak1=peaks{1}.left.y; + minpeak2=peaks{1}.right.y; + minpeak=mean([minpeak1 minpeak2]); + if maxpeak-minpeak > 0 + contrast(1)=(maxpeak-minpeak)/1000; + else + contrast(1)=0; + end +end + +[maxcontrast,wheremax]=max(contrast); + +peak_oi=peaks{wheremax}; + +pitchstrength= contrast(wheremax); +found_frequency = 1/peak_oi.t; + +if plot_switch + fre=found_frequency; + plot(fre,gettimevalue(ti_profile,1/fre),'Marker','o','Markerfacecolor','g','MarkeredgeColor','g','MarkerSize',pitchstrength*10); + text(fre*1.1,gettimevalue(ti_profile,1/fre)+5, ['highest pitchstrength found at ' num2str(round(fre)) 'Hz: ' num2str(fround(pitchstrength,2)) ],'VerticalAlignment','bottom','HorizontalAlignment','center','color','g','Fontsize',12); +end + +return + + + + +% maxpeak=maxstruct(peaks,'y'); + +if length(peaks_env_peaks_lr)>1 + for i=1:length(peaks) + % If second highes peak==peak with smallest time intervall -> take + % third highest !! + if peak_env_peaks{2}.x == peaks_env_peaks_lr{1}.x + poix = peak_envX(peak_env_peaks{3}.x); + else + poix = peak_envX(peak_env_peaks{2}.x); + end + if peaks{i}.x==poix + peak_oi = peaks{i}; + end + end +else + % pure sinusoid ??? + dominant_time = 0 + pitchstrength = 0.001; + return +end + + + +% Stefan's method on HCL +% Take second peak of envelope from short time intervals +if length(peaks_env_peaks_lr)>1 + for i=1:length(peaks) + % If second highes peak==peak with smallest time intervall -> take + % third highest !! + if peak_env_peaks{2}.x == peaks_env_peaks_lr{1}.x + poix = peak_envX(peak_env_peaks{3}.x); + else + poix = peak_envX(peak_env_peaks{2}.x); + end + if peaks{i}.x==poix + peak_oi = peaks{i}; + end + end +else + % pure sinusoid ??? + dominant_time = 0 + pitchstrength = 0.001; + return +end + +if plot_switch + plot(tip_x(peak_oi.x), peak_oi.y, 'ro'); +end + + + + + +% peak_oi contains the peak for quantification + + +% ++++++++++++ Part two: Quantification ++++++++++ + +% **** First method +% pitchstrength is mean of sum / mean of peaks +% psum = 0; +% for i = 1:length(peaks) +% psum = psum+peaks{i}.y; +% end +% psum = psum / length(peaks); +% pitchstrength = psum/peaks{1}.y; +% dominant_time = peaks{1}.x /getsr(ti_profile); +% if plot_switch +% hold off +% plot(ti_profile); +% hold on; +% plot(peaks{1}.x, peaks{1}.y, 'ko'); +% end + +% % ***** Second method +% % Heigh of neighbour peak / highest peak +% % First Peaks is the highest as pitchstrength of Peak Picker +% % Find lower neighbour (with shorter time interval) +% ioi=1; % index of interest +% dist = inf; +% for i=1:length(peaks) +% d = peak_oi.x - peaks{i}.x; +% if ((d<dist)&(d>0)) +% ioi = i; +% dist = d; +% end +% end +% pitchstrength = peaks{ioi}.y/ peak_oi.y; +% dominant_time = peak_oi.x /getsr(ti_profile); +% if plot_switch +% hold on; +% plot(peak_oi.x , peak_oi.y , 'ko'); +% plot(peaks{ioi}.x, peaks{ioi}.y, 'go'); +% end + +% % Third Method: +% Peak to mean valley ration - good with HCL +pitchstrength= mean([peak_oi.left.y peak_oi.right.y])/peak_oi.y; +dominant_time = peak_oi.x /getsr(ti_profile); + +% Adaptation +%pitchstrength = 1-pitchstrength; + +% +++++++++++++ Histogram of distances between two peaks ++++++++++ + +% +max_thresh = 1; %0.98; +% The linear TIP + +% Test if all other Peaks ar multiple of the highest peak + +% Start with the first peak +% Test how many peaks are mutiple of the first peak +%---x---x---x---x---x---x +% Take first peak of envelope. +poix = peak_envX(peak_env_peaks{1}.x); +for i=1:length(peaks_lr) + if peaks_lr {i}.x==poix + peak_first = peaks_lr{i}; + first_i=i; + end +end +nomult = 0; % Number of multible +max_delta = 0.1; % +for i=first_i:length(peaks_lr) + f = peaks_lr{i}.t / peak_first.t; + if abs(round(f)-f)<max_delta + nomult=nomult+1; + end +end +nomult; + +if plot_switch + figure(savecf) +end + +%---x---x---x---x---x---x + +% is there is a priori information? +% if (nargin>2) +% dominant_time = mb(h_index) / getsr(ti_profile); +% pitchstrength = 0; +% return +% end + + + +% ------------ subfunctions --------------------- + +% turns a vector (row) upside down +function y=upsidedown(x) +y=[]; +for i=length(x):-1:1 + y=[y x(i)]; +end