Mercurial > hg > aimmat
view 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 source
% 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