Mercurial > hg > aimmat
diff aim-mat/modules/usermodule/pitchstrength/genpitchstrength2.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/genpitchstrength2.m Tue Aug 16 14:37:17 2011 +0100 @@ -0,0 +1,239 @@ +% generating function for 'aim-mat' +% +% INPUT VALUES: +% +% RETURN VALUE: +% +% +% (c) 2003, University of Cambridge, Medical Research Council +% Christoph Lindner +% (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 ps_result=genpitchstrength(sai,options) + +target_frequency=options.target_frequency; + +if target_frequency > 0 + look_for_target_frequency=1; + minimum_allowed_frequency=target_frequency/options.allowed_frequency_deviation; + maximum_allowed_frequency=target_frequency*options.allowed_frequency_deviation; +else + look_for_target_frequency=0; +end + +if isfield(options,'resolved_harmonic_minimum') + resolved_harmonic_minimum=options.resolved_harmonic_minimum; +end + + +% find out about scaling: +maxval=-inf; +maxfreval=-inf; +maxsumval=-inf; + +nr_frames=length(sai); +for ii=1:nr_frames + maxval=max([maxval getmaximumvalue(sai{ii})]); + maxsumval=max([maxsumval getscalesumme(sai{ii})]); + maxfreval=max([maxfreval getscalefrequency(sai{ii})]); +end + + +for frame_number=1:nr_frames + current_frame = sai{frame_number}; + % current_frame = setallmaxvalue(current_frame, maxval); + frame_start_time(frame_number)=getcurrentframestarttime(current_frame); + tip(frame_number)=gettimeintervalprofile(current_frame,options); +end +frame_duration=frame_start_time(2)-frame_start_time(1); + +% calculate the averaged tips +% the first frames are not average, since not long enough time has +% passed. After that, the relevant last frames are averaged +tip_time=options.tip_average_time; +% time for pitch to drop to 1/2 (6dB) --in seconds +% this means so much per frame +ps_decay_constant=1-log(2)/(tip_time/frame_duration); + + +% % and again to sum them up +% for frame_number=1:nr_frames +% thisav=mute(tip(frame_number)); % take a copy of the original one +% figure(1243234) +% clf +% hold on +% count=0; +% for recent_frames_nr=frame_number-nr_frames_to_average:frame_number +% if recent_frames_nr > 0 +% thisav=thisav+tip(recent_frames_nr); +% count=count+1; +% plot(tip(recent_frames_nr),'g'); +% end +% end +% thisav=thisav/count; % the average +% plot(thisav,'r'); +% average_tip(frame_number)=thisav; +% end + +% is it necessary to calculate all, or can we start right at the end? +% if options.return_only_last==1 +% start_frame=length(sai); +% else % no we +start_frame=1; +% end + +emptysig=mute(tip(1)); +% mache ein Histogramm für jede Frequenz mit allem Maxima: +nr_points=getnrpoints(sai{1}); +histo=zeros(1,nr_points); + +waithand = waitbar(0,'Generating pitch strength'); +for frame_number=start_frame:nr_frames +% for frame_number=1:10 + + waitbar(frame_number/nr_frames, waithand); + + current_frame = sai{frame_number}; + current_frame = setallmaxvalue(current_frame, maxval); + current_frame = setscalesumme(current_frame, maxsumval); + current_frame = setscalefrequency(current_frame, maxfreval); + + interval_sig = tip(frame_number); + % interval_sig = average_tip(frame_number); + ps_result{frame_number}.frequency_sum = getfrequencysum(current_frame); + % Normalisation + interval_sig = interval_sig/getnrpoints( ps_result{frame_number}.frequency_sum); + ps_result{frame_number}.frequency_sum = ps_result{frame_number}.frequency_sum/getnrpoints(interval_sig)*options.scalefactor; + + opts.ps_options=options; + % do all relevant pitch calculations for this frame + result=find_pitches(interval_sig,opts); + + ps_result{frame_number}.interval_sum =emptysig; + ps_result{frame_number}.pitchstrength=0; + + + % sum all pitches for a histogram + peaks=result.peaks; + nr_peaks=length(peaks); + if nr_peaks>0 + for current_peak=1:nr_peaks + peak_time=peaks{current_peak}.t; + peak_x=peaks{current_peak}.x; + peak_height=peaks{current_peak}.y; + int_x=round(peak_x); + histo(int_x)=histo(int_x)+peak_height; + end + + shist=signal(histo,getsr(interval_sig)); + shistl=lowpass(shist,400); + peaks=IPeakPicker(shistl); + + % ignore the first peak on the left: +% speaks=sortstruct(peaks,'x'); +% peaks{1}.y=0; + + speaks=sortstruct(peaks,'y'); + + pitchstrength=speaks{1}.y; + final_dominant_frequency=1/speaks{1}.t; +% +% if mod(frame_number,10)==0 +% figure(43242) +% if frame_number<30 +% clf; +% hold on +% end +% plot(shist/50); +% % ax=axis; +% plot(shistl,'r'); hold on +% % axis(ax); +% fre=1/speaks{1}.t; +% plot(speaks{1}.x,speaks{1}.y,'o','MarkerFaceColor','g','MarkerEdgeColor','w','MarkerSize',10) +% text(speaks{1}.x,speaks{1}.y,sprintf('%2.0fHz %2.2f',final_dominant_frequency,pitchstrength)) +% for i=2:length(speaks)/2 +% fre=1/speaks{i}.t; +% plot(speaks{i}.x,speaks{i}.y,'o','MarkerFaceColor','m','MarkerEdgeColor','w','MarkerSize',5) +% text(speaks{i}.x,speaks{i}.y,sprintf('%2.0fHz %2.2f',fre,speaks{i}.y)) +% end +% time=frame_number*5; +% text(speaks{1}.x+400,speaks{1}.y,sprintf('Time: %3.0fms',time)); +% o=0; +% end + + ps_result{frame_number}.peaks = speaks; + ps_result{frame_number}.interval_sum =shistl; + + if look_for_target_frequency + count=0; + for ii=1:length(speaks) % construct all maxima + fre=1/speaks{ii}.t; + dist(ii)=abs(target_frequency-fre); + if fre> minimum_allowed_frequency && fre < maximum_allowed_frequency + count=count+1; + allowednumber(count)=ii; + allowedheights(count)=speaks{ii}.y; + end + end +% [minfredif,nearest_peak_number]=min(dist); +% fre=1/speaks{nearest_peak_number}.t; + % is the frequency allowed? + if count>0 +% if fre< minimum_allowed_frequency || fre > maximum_allowed_frequency + [highest_ps,best_number]=max(allowedheights); + best_peak_number=allowednumber(best_number); + + % gib das Verhältnis der peakstrength zu allen peaks + % zurück (ohne ihm selbst) + do_only_relationship=1; + if do_only_relationship + count=1; + for ii=1:length(speaks) + if ii~=best_peak_number + allps(count)=speaks{ii}.y; + count=count+1; + end + end + ps=speaks{best_peak_number}.y/mean(allps); + ps_result{frame_number}.pitchstrength=ps; + ps_result{frame_number}.dominant_frequency=1/speaks{best_peak_number}.t; + else + ps_result{frame_number}.pitchstrength=speaks{best_peak_number}.y; + ps_result{frame_number}.dominant_frequency=1/speaks{best_peak_number}.t; + end + else % no, nothing there +% ps_result{frame_number}.interval_sum = result.smoothed_signal; + ps_result{frame_number}.peaks = []; + ps_result{frame_number}.dominant_frequency=0; + ps_result{frame_number}.pitchstrength=0; + end % frequency allowance + else % free search was already done! + ps_result{frame_number}.dominant_frequency=final_dominant_frequency; + ps_result{frame_number}.pitchstrength=pitchstrength; + end % look for target frequency + else % no peaks found + ps_result{frame_number}.peaks = []; + ps_result{frame_number}.dominant_frequency=0; + ps_result{frame_number}.pitchstrength=0; + end + + % dynamic decrease of all pitch strengthes + histo=histo.*ps_decay_constant; + + + % Peak Picker for FrequencyProfile + p.dyn_thresh = options.dynamic_threshold_FP; + p.smooth_sigma = options.smooth_sigma_FP; + ps_result{frame_number}.peaks_frequency_sum = FPeakPicker(ps_result{frame_number}.frequency_sum, p); + % ps_result{frame_number}.channel_center_fq = getcf(sai{frame_number}); + ps_result{frame_number}.channel_center_fq = getcf(sai{frame_number}); + +end +close(waithand); + +