annotate aim-mat/tools/@signal/gen_jittered_clicktrains.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
rev   line source
bleeck@3 1 % This external file is included as part of the 'aim-mat' distribution package
bleeck@3 2 % (c) 2011, University of Southampton
bleeck@3 3 % Maintained by Stefan Bleeck (bleeck@gmail.com)
bleeck@3 4 % download of current version is on the soundsoftware site:
bleeck@3 5 % http://code.soundsoftware.ac.uk/projects/aimmat
bleeck@3 6 % documentation and everything is on http://www.acousticscale.org
tomwalters@0 7 function [target_signal,flanking_signal,only_regular_clicktrain,only_irregular_clicktrain]= ...
tomwalters@0 8 gen_jittered_clicktrains(orgsig,jitter,delay,target_fre,flanker_fre,Gain,FlankerMode,FlankerDelay,grafix)
tomwalters@0 9 %
tomwalters@0 10 % this funtion produces the stimuli needed in Krumbholz et al 2003 and
tomwalters@0 11 % many other regular and irregular filted click trains
tomwalters@0 12 % the clicktrain can be pure when TargetFrequency is =0 otherwise the
tomwalters@0 13 % click train filted with a band pass filter around the given frequency
tomwalters@0 14 %
tomwalters@0 15 % input:
tomwalters@0 16 % orgsig: original signal. Determines length and samperate. SR must be 25000!
tomwalters@0 17 % jitter:
tomwalters@0 18 % the amount of jitter in % (0=regular, 100= maximal jitter)
tomwalters@0 19 % delay:
tomwalters@0 20 % the repetition rate of the signal in ms
tomwalters@0 21 % target_fre:
tomwalters@0 22 % one of the following:
tomwalters@0 23 % 0 0.4 0.5657 0.8 1.1314 1.6 2.2627 3.2 4.5255 6.4
tomwalters@0 24 % if not precice, the nearest one will be taken
tomwalters@0 25 % if 0, then no target will be generated
tomwalters@0 26 % flanker_fre:
tomwalters@0 27 % one of the following:
tomwalters@0 28 % 0 0.4 0.5657 0.8 1.1314 1.6 2.2627 3.2 4.5255 6.4
tomwalters@0 29 % if not precice, the nearest one will be taken
tomwalters@0 30 % if 0, then no flanker will be generated
tomwalters@0 31
tomwalters@0 32 % flanker_mode:
tomwalters@0 33 % one of the following:
tomwalters@0 34 % m: Flanker band synchronous and irregular (highest threshold)
tomwalters@0 35 % t: Flanker band synchronous and regular (medium threshold)
tomwalters@0 36 % td5: Flanker band synchronous and regular shifted in timepoints (lowest threshold)
tomwalters@0 37 % sb1: Masker regular, flanker band irregular (Ranjnas Experiment)
tomwalters@0 38 % sb2: Masker regular, flanker band regular, but time shifted (Ranjnas other stimulus)
tomwalters@0 39 % sb3: Masker irregular, flanker band regular,
tomwalters@0 40 % sb4: NO masker, flanker band regular (returned in target_signal)
tomwalters@0 41
tomwalters@0 42 % flanker delay:
tomwalters@0 43 % the delay of the synchronous clicks in ms
tomwalters@0 44 % Gain:
tomwalters@0 45 % the gain of the signal against the masker positiv direction: more signal
tomwalters@0 46 % grafix says, if we want to see a plot of the signal or not
tomwalters@0 47
tomwalters@0 48 % possible usage:
tomwalters@0 49 % produce the stimulus as in the paper:
tomwalters@0 50 % gen_jittered_clicktrains(signal(1,25000),0,10,1.6,3.2,10,'td5',5,1);
tomwalters@0 51 % play(gen_jittered_clicktrains(signal(1,25000),0,10,3.2,0.8,3,'td5',5))
tomwalters@0 52 %
tomwalters@0 53 % to generate regular clicktrains use
tomwalters@0 54 % [a,b,c,d]=gen_jittered_clicktrains(signal(1,25000),0,10); play(c);
tomwalters@0 55 %
tomwalters@0 56 % to generate 20 % jitter use:
tomwalters@0 57 % [a,b,c,d]=gen_jittered_clicktrains(signal(1,25000),0.2,10); play(d);
tomwalters@0 58 %
tomwalters@0 59 % to filter at 3.2 Khz generate 20 % jitter use:
tomwalters@0 60 % [a,b,c,d]=gen_jittered_clicktrains(signal(1,25000),0.2,10,3.2); play(d);
tomwalters@0 61 %
tomwalters@0 62 % to generate one of Ranjnas stimuli (regular masker at first frequency and irregular target
tomwalters@0 63 % in a different frequency band use) here: regular 40 dB louder then irregular
tomwalters@0 64 % play(gen_jittered_clicktrains(signal(1,25000),1,10,1.6,3.2,40,'sb1',NaN,1)/20)
tomwalters@0 65 % the shift parameter is here ignored
tomwalters@0 66 %
tomwalters@0 67 %
tomwalters@0 68 % to generate one of Ranjnas stimuli (regular masker at first frequency and shifted target
tomwalters@0 69 % in a different frequency band use) here: regular 40 dB louder the shifted
tomwalters@0 70 % play(gen_jittered_clicktrains(signal(1,25000),NaN,10,1.6,3.2,40,'sb2',5,1))
tomwalters@0 71 % in this case the jitter is ignored
tomwalters@0 72
tomwalters@0 73 % return signals:
tomwalters@0 74 % target_signal is the target band with regular clicks plus irregular clicks with the ratio of "gain"
tomwalters@0 75 % flanking_signal is the flanking band which can be either regular or irregular
tomwalters@0 76 % only_regular_clicktrain is the regular clicks alone
tomwalters@0 77 % only_irregular_clicktrain is the irrregular clicks alone
tomwalters@0 78 %
tomwalters@0 79 % % no random please!
tomwalters@0 80 % rand('state',0);
tomwalters@0 81
tomwalters@0 82 % input variables:
tomwalters@0 83 % 1 2 3 4 5 6 7 8
tomwalters@0 84 %(orgsig,jitter,delay,flanker_fre,Gain,FlankerMode,FlankerDelay,grafix);
tomwalters@0 85
tomwalters@0 86
tomwalters@0 87
tomwalters@0 88
tomwalters@0 89 if nargin <9 grafix=0;end
tomwalters@0 90 if nargin <8 FlankerDelay=5; end
tomwalters@0 91 if nargin <7 FlankerMode='td5';end
tomwalters@0 92 if nargin <6 Gain=0;end
tomwalters@0 93 if nargin <5 flanker_fre=3.2;end
tomwalters@0 94 if nargin <4 target_fre=0;end
tomwalters@0 95 if nargin <3 delay=10;end
tomwalters@0 96 if nargin <2
tomwalters@0 97 jitter=1; % 100 % jitter
tomwalters@0 98 end
tomwalters@0 99
tomwalters@0 100 if jitter >1
tomwalters@0 101 disp('jitter must be smaller then 1 (100%)')
tomwalters@0 102 jitter=1;
tomwalters@0 103 end
tomwalters@0 104
tomwalters@0 105 % possible Target and Flanker frequencies:
tomwalters@0 106 f(1)=0.4;
tomwalters@0 107 f(2)=0.5657;
tomwalters@0 108 f(3)=0.8;
tomwalters@0 109 f(4)=1.1314;
tomwalters@0 110 f(5)=1.6;
tomwalters@0 111 f(6)=2.2627;
tomwalters@0 112 f(7)=3.2;
tomwalters@0 113 f(8)=4.5255;
tomwalters@0 114 f(9)=6.4;
tomwalters@0 115
tomwalters@0 116 % TargetFrq = 1.6; % fixed
tomwalters@0 117 % change into the directory with the filter coeffiencs in
tomwalters@0 118 orgdira=which('signal');
tomwalters@0 119 orgdir=fileparts(orgdira);
tomwalters@0 120 od=cd(fullfile(orgdir,'FIR filter coefficients'));
tomwalters@0 121
tomwalters@0 122 % load filter for Target
tomwalters@0 123 if target_fre==0
tomwalters@0 124 TargetFrq=0;
tomwalters@0 125 else
tomwalters@0 126 % load the filter file for the appropriate frequency for the target
tomwalters@0 127 p=polyfit(1:9,log(f),1);
tomwalters@0 128 targ=round(solve(p,log(target_fre)));
tomwalters@0 129 TargetFrq = f(targ);
tomwalters@0 130 targetFIRFile = sprintf('bp%gw%g',TargetFrq,0.2);
tomwalters@0 131 targetFIRFile(findstr(targetFIRFile,'.')) = '_';
tomwalters@0 132 FId = fopen([targetFIRFile '.txt'],'rt');
tomwalters@0 133 fgetl(FId);
tomwalters@0 134 targetFIR = fscanf(FId,'%g',151)';
tomwalters@0 135 fclose(FId);
tomwalters@0 136 end
tomwalters@0 137
tomwalters@0 138 % load filter for Flanker
tomwalters@0 139 if flanker_fre==0
tomwalters@0 140 FlankerFrq=0;
tomwalters@0 141 else
tomwalters@0 142 % load the filter file for the appropriate frequency for the flanker
tomwalters@0 143 p=polyfit(1:9,log(f),1);
tomwalters@0 144 flank=round(solve(p,log(flanker_fre)));
tomwalters@0 145 FlankerFrq = f(flank);
tomwalters@0 146 flankerFIRFile = sprintf('bp%gw%g',FlankerFrq,0.2);
tomwalters@0 147 flankerFIRFile(findstr(flankerFIRFile,'.')) = '_';
tomwalters@0 148 FId = fopen([flankerFIRFile '.txt'],'rt');
tomwalters@0 149 fgetl(FId);
tomwalters@0 150 flankerFIR = fscanf(FId,'%g',151)';
tomwalters@0 151 fclose(FId);
tomwalters@0 152 end
tomwalters@0 153 cd(od); % go back to the old directory
tomwalters@0 154
tomwalters@0 155 SR = 1000/getsr(orgsig);% all in ms
tomwalters@0 156 sig_length =getlength(orgsig)*1000;
tomwalters@0 157 % the filter coefficients only work when the sr is 25000!
tomwalters@0 158 if getsr(orgsig)~=25000 && target_fre>0
tomwalters@0 159 disp('gen_jittered_clicktrains::warning: filtering only works for a sample rate of 25000')
tomwalters@0 160 end
tomwalters@0 161
tomwalters@0 162 rise_time = 25;
tomwalters@0 163 timepoints = 0:SR:sig_length;
tomwalters@0 164 TPts = max(size(timepoints));
tomwalters@0 165 DigAmp = 1;
tomwalters@0 166 SDelay = round(delay/SR);
tomwalters@0 167
tomwalters@0 168 regular_clickstream = zeros(1,TPts);
tomwalters@0 169 regular_clickstream(1:SDelay:TPts) = DigAmp;
tomwalters@0 170
tomwalters@0 171 % RANDOMISE THE TARGET
tomwalters@0 172 irregular_clickstream = zeros(1,TPts);
tomwalters@0 173 % randomisation in the range of the jitter boundary
tomwalters@0 174 jitter_time=SDelay*jitter;
tomwalters@0 175 % Idx = ceil(rand*SDelay*2);
tomwalters@0 176 idx = [];count=1;
tomwalters@0 177 while isempty(idx)|| max(idx)<TPts % go thorugh every cycle and jitter every pulse by a bit
tomwalters@0 178 rand_click_offset=ceil(rand*jitter_time-jitter_time/2);
tomwalters@0 179 if isempty(idx)
tomwalters@0 180 idx = count*SDelay+rand_click_offset;
tomwalters@0 181 else
tomwalters@0 182 idx = [idx count*SDelay+rand_click_offset];
tomwalters@0 183 end
tomwalters@0 184 count=count+1;
tomwalters@0 185 end
tomwalters@0 186 idx=idx(1:end-1); % subtract the last one, because its after the end
tomwalters@0 187 irregular_clickstream(idx)= DigAmp;
tomwalters@0 188
tomwalters@0 189 % RANDOMISE ALSO THE FLANKER
tomwalters@0 190 irregular_clickstream_2 = zeros(1,TPts);
tomwalters@0 191 % randomisation in the range of the jitter boundary
tomwalters@0 192 jitter_time=SDelay*jitter;
tomwalters@0 193 % Idx = ceil(rand*SDelay*2);
tomwalters@0 194 idx = [];count=1;
tomwalters@0 195 while isempty(idx)|| max(idx)<TPts % go thorugh every cycle and jitter every pulse by a bit
tomwalters@0 196 rand_click_offset=ceil(rand*jitter_time-jitter_time/2);
tomwalters@0 197 if isempty(idx)
tomwalters@0 198 idx = count*SDelay+rand_click_offset;
tomwalters@0 199 else
tomwalters@0 200 idx = [idx count*SDelay+rand_click_offset];
tomwalters@0 201 end
tomwalters@0 202 count=count+1;
tomwalters@0 203 end
tomwalters@0 204 idx=idx(1:end-1); % subtract the last one, because its after the end
tomwalters@0 205 irregular_clickstream_2(idx)= DigAmp;
tomwalters@0 206
tomwalters@0 207
tomwalters@0 208 if strcmp(FlankerMode,'sb1') ||strcmp(FlankerMode,'sb2') % in this case the masker is always regular and the target irregular
tomwalters@0 209 targetReg = envelope_signal(min(max(DigAmp*10^(Gain/20),DigAmp),regular_clickstream*10^(Gain/20)),rise_time,SR);
tomwalters@0 210 elseif strcmp(FlankerMode,'sb3') % in this case the target is irregular
tomwalters@0 211 targetReg = envelope_signal(min(max(DigAmp*10^(Gain/20),DigAmp),irregular_clickstream*10^(Gain/20)),rise_time,SR);
tomwalters@0 212 elseif strcmp(FlankerMode,'sb4') % in this case there is no target
tomwalters@0 213 targetReg = zeros(size(regular_clickstream));
tomwalters@0 214 else
tomwalters@0 215 targetReg = envelope_signal(min(max(DigAmp*10^(Gain/20),DigAmp),regular_clickstream*10^(Gain/20)+irregular_clickstream),rise_time,SR);
tomwalters@0 216 end
tomwalters@0 217 targetIrr = envelope_signal(min(max(DigAmp*10^(Gain/20),DigAmp),irregular_clickstream_2*10^(Gain/20)+irregular_clickstream),rise_time,SR);
tomwalters@0 218
tomwalters@0 219 if FlankerFrq~=0
tomwalters@0 220 if strcmp(FlankerMode,'td5') || strcmp(FlankerMode,'t')
tomwalters@0 221 flanker = regular_clickstream;
tomwalters@0 222 elseif strcmp(FlankerMode,'m')
tomwalters@0 223 flanker = irregular_clickstream;
tomwalters@0 224 elseif strcmp(FlankerMode,'sb1')
tomwalters@0 225 flanker = irregular_clickstream;
tomwalters@0 226 elseif strcmp(FlankerMode,'sb2')
tomwalters@0 227 flanker = [zeros(1,round(FlankerDelay/SR)) regular_clickstream(1:TPts-round(FlankerDelay/SR))];
tomwalters@0 228 elseif strcmp(FlankerMode,'sb3')
tomwalters@0 229 flanker = regular_clickstream;
tomwalters@0 230 elseif strcmp(FlankerMode,'sb4')
tomwalters@0 231 % flanker = regular_clickstream;
tomwalters@0 232 flanker =envelope_signal(min(max(DigAmp*10^(-Gain/20),DigAmp),regular_clickstream*10^(-Gain/20)),rise_time,SR);
tomwalters@0 233
tomwalters@0 234 end
tomwalters@0 235 if FlankerDelay>0 && strcmp(FlankerMode,'td5')
tomwalters@0 236 flanker = [zeros(1,round(FlankerDelay/SR)) flanker(1:TPts-round(FlankerDelay/SR))];
tomwalters@0 237 end
tomwalters@0 238 else
tomwalters@0 239 flanker = zeros(1,TPts);
tomwalters@0 240 end
tomwalters@0 241 flanker = envelope_signal(flanker,rise_time,SR);
tomwalters@0 242
tomwalters@0 243
tomwalters@0 244 % filter the resulting streams in the right frequency bands
tomwalters@0 245 if FlankerFrq~=0
tomwalters@0 246 f_flanker=filter(flankerFIR,1,flanker);
tomwalters@0 247 else
tomwalters@0 248 f_flanker=flanker;
tomwalters@0 249 end
tomwalters@0 250 if target_fre>0 % only filter, when neccessary
tomwalters@0 251 f_targetReg=filter(targetFIR,1,targetReg);
tomwalters@0 252 f_targetIrr=filter(targetFIR,1,targetIrr);
tomwalters@0 253 else
tomwalters@0 254 f_targetReg=targetReg;
tomwalters@0 255 f_targetIrr=targetIrr;
tomwalters@0 256 end
tomwalters@0 257
tomwalters@0 258 signal_flank=signal(f_flanker);
tomwalters@0 259 signal_flank=setsr(signal_flank,1000/SR);
tomwalters@0 260 target_signal=signal(f_targetReg);
tomwalters@0 261 flanking_signal=signal(f_targetIrr);
tomwalters@0 262 target_signal=setsr(target_signal,1000/SR);
tomwalters@0 263 flanking_signal=setsr(flanking_signal,1000/SR);
tomwalters@0 264 if strcmp(FlankerMode,'sb1') || strcmp(FlankerMode,'sb2')
tomwalters@0 265 % in this case, the target is the signal plus the flanker:
tomwalters@0 266 target_signal=target_signal+signal_flank;
tomwalters@0 267 else
tomwalters@0 268 % Signal zu Flanker addieren (stimmt von der Amplitude her wohl nicht, aber
tomwalters@0 269 % für den Moment wirds tun)
tomwalters@0 270 target_signal=target_signal+signal_flank;
tomwalters@0 271 flanking_signal=flanking_signal+signal_flank;
tomwalters@0 272 end
tomwalters@0 273
tomwalters@0 274 %generate the pure random and regular click trains as well
tomwalters@0 275 only_regular_clickstream=envelope_signal(min(max(DigAmp*10^(Gain/20),DigAmp),regular_clickstream*10^(Gain/20)),rise_time,SR);
tomwalters@0 276 if target_fre>0 % only filter, when neccessary
tomwalters@0 277 only_regular_clickstream=filter(targetFIR,1,only_regular_clickstream);
tomwalters@0 278 end
tomwalters@0 279 only_regular_clicktrain=signal(only_regular_clickstream);
tomwalters@0 280 only_regular_clicktrain=setsr(only_regular_clicktrain,1000/SR);
tomwalters@0 281 only_irregular_clickstream=envelope_signal(min(max(DigAmp*10^(Gain/20),DigAmp),irregular_clickstream*10^(Gain/20)),rise_time,SR);
tomwalters@0 282 if target_fre>0 % only filter, when neccessary
tomwalters@0 283 only_irregular_clickstream=filter(targetFIR,1,only_irregular_clickstream);
tomwalters@0 284 end
tomwalters@0 285 only_irregular_clicktrain=signal(only_irregular_clickstream);
tomwalters@0 286 only_irregular_clicktrain=setsr(only_irregular_clicktrain,1000/SR);
tomwalters@0 287
tomwalters@0 288 % plotte ein paar hübsche Bilder dazu
tomwalters@0 289 % figure(4)
tomwalters@0 290 % subplot(2,2,1)
tomwalters@0 291 % plot(target_signal);
tomwalters@0 292 % subplot(2,2,2)
tomwalters@0 293 % plot(powerspectrum(target_signal));
tomwalters@0 294 % subplot(2,2,3)
tomwalters@0 295 % plot(flanking_signal);
tomwalters@0 296 % subplot(2,2,4)
tomwalters@0 297 % plot(powerspectrum(flanking_signal));
tomwalters@0 298 % savewave(target_signal,'regular');
tomwalters@0 299 % savewave(flanking_signal,'irregular');
tomwalters@0 300
tomwalters@0 301 % savewave(target_signal,'stimulus');
tomwalters@0 302
tomwalters@0 303 if grafix
tomwalters@0 304 figure(4)
tomwalters@0 305 subplot(2,1,1)
tomwalters@0 306 plot(target_signal);
tomwalters@0 307 subplot(2,1,2)
tomwalters@0 308 plot(powerspectrum(target_signal));
tomwalters@0 309 end
tomwalters@0 310
tomwalters@0 311 % ********** envelope_signal **********
tomwalters@0 312 function out = envelope_signal(in,rise_time,SR)
tomwalters@0 313 APts = length(in);
tomwalters@0 314 GPts = round(rise_time/SR);
tomwalters@0 315 if APts<2*GPts
tomwalters@0 316 error('==> Signal must be loger than gate!')
tomwalters@0 317 end
tomwalters@0 318 env = cos(pi*(0:GPts-1)/(2*(GPts-1))).^2;
tomwalters@0 319 out = [1-env ones(1,APts-2*GPts) env].*in;