annotate multithreshold 1.46/nextStimulus.m @ 7:573c75007cf4

new intpow functions
author Ray Meddis <rmeddis@essex.ac.uk>
date Fri, 27 May 2011 14:29:28 +0100
parents f233164f4c86
children 8c7a18d89610
rev   line source
rmeddis@0 1 function errormsg=nextStimulus(handles)
rmeddis@0 2 % Handles everything concerned with the stimulus presentation
rmeddis@0 3 % called from startNewRun in subjGUI
rmeddis@0 4
rmeddis@0 5 global experiment stimulusParameters withinRuns betweenRuns
rmeddis@0 6 experiment.status='presentingStimulus';
rmeddis@0 7 errormsg='';
rmeddis@0 8
rmeddis@0 9 % interrupt by 'stop' button
rmeddis@0 10 if experiment.stop
rmeddis@0 11 disp('******** experiment manually stopped *****************')
rmeddis@0 12 experiment.status= 'waitingForStart';
rmeddis@0 13 addToMsg('manually stopped',1)
rmeddis@0 14 return
rmeddis@0 15 end
rmeddis@0 16
rmeddis@0 17 % -----------------------------------------choose catch trials at random
rmeddis@0 18 % catch trials are for subject threshold measurements only
rmeddis@0 19 % this is the only place where withinRuns.catchTrial is set
rmeddis@0 20 if experiment.allowCatchTrials
rmeddis@0 21 if withinRuns.trialNumber==1;
rmeddis@0 22 % first trial is never a catch trial
rmeddis@0 23 withinRuns.catchTrial=0;
rmeddis@0 24 withinRuns.catchTrialCount=0; % reset count on first trial
rmeddis@0 25 elseif withinRuns.trialNumber==2 ...
rmeddis@0 26 && withinRuns.catchTrialCount==0
rmeddis@0 27 % second trial is always a catch trial
rmeddis@0 28 withinRuns.catchTrial=1;
rmeddis@0 29 withinRuns.catchTrialCount=1; % this must be the first
rmeddis@0 30 elseif withinRuns.thisIsRepeatTrial
rmeddis@0 31 % for requested repeats do not change catch trial status
rmeddis@0 32 withinRuns.thisIsRepeatTrial=0; % reset toggle
rmeddis@0 33 else
rmeddis@0 34 % choose whether or not to have a catch trial
rmeddis@0 35 R=rand;
rmeddis@0 36 if R<stimulusParameters.catchTrialRate
rmeddis@0 37 % catch trial
rmeddis@0 38 withinRuns.catchTrial=1;
rmeddis@0 39 addToMsg('Catch Trial',1)
rmeddis@0 40 withinRuns.catchTrialCount=withinRuns.catchTrialCount+1;
rmeddis@0 41 else
rmeddis@0 42 % not a catch trial
rmeddis@0 43 withinRuns.catchTrial=0;
rmeddis@0 44 end
rmeddis@0 45 end
rmeddis@0 46 else
rmeddis@0 47 % no catch trials for statistical evaluations or 2AIFC or (poss) MAP
rmeddis@0 48 withinRuns.catchTrial=0;
rmeddis@0 49 end
rmeddis@0 50
rmeddis@0 51 %------------ during stimulus presentation show appropriate button images
rmeddis@0 52 switch experiment.ear
rmeddis@0 53 case {'statsModelLogistic', 'statsModelRareEvent',...
rmeddis@0 54 'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh'}
rmeddis@0 55 % no buttons shown
rmeddis@0 56 otherwise
rmeddis@0 57 switch experiment.threshEstMethod
rmeddis@0 58 case {'2I2AFC++', '2I2AFC+++'}
rmeddis@0 59 %Except for 2I2AFC
rmeddis@0 60 % For 2I2AFC the buttons on the screen ab initio
rmeddis@0 61 set(handles.frame1,'visible','off')
rmeddis@0 62 set(handles.pushbuttonGO,'visible','off')
rmeddis@0 63 set(handles.pushbuttoNotSure,'visible','off')
rmeddis@0 64 set(handles.pushbuttonWrongButton,'visible','off')
rmeddis@0 65 set(handles.pushbutton3,'visible','off')
rmeddis@0 66 set(handles.pushbutton0,'visible','off')
rmeddis@0 67 set(handles.pushbutton1,'visible','on')
rmeddis@0 68 set(handles.pushbutton2,'visible','on')
rmeddis@0 69 drawnow
rmeddis@0 70 otherwise
rmeddis@0 71 % i.e. single interval/ maxLikelihood
rmeddis@0 72 set(handles.frame1,'backgroundColor','w')
rmeddis@0 73 set(handles.frame1,'visible','off')
rmeddis@0 74 set(handles.pushbuttoNotSure,'visible','off')
rmeddis@0 75 set(handles.pushbuttonWrongButton,'visible','off')
rmeddis@0 76 set(handles.pushbutton3,'visible','off')
rmeddis@0 77 set(handles.pushbutton2,'visible','off')
rmeddis@0 78 set(handles.pushbutton1,'visible','off')
rmeddis@0 79 set(handles.pushbutton0,'visible','off')
rmeddis@0 80 pause(.1)
rmeddis@0 81 end
rmeddis@0 82 end
rmeddis@0 83
rmeddis@0 84 set(handles.textMSG,'BackgroundColor','w', 'ForegroundColor', 'b')
rmeddis@0 85
rmeddis@0 86 % Now the serious business of crafting and presenting the stimulus
rmeddis@0 87 errormsg= stimulusMakeAndPlay (handles);
rmeddis@0 88
rmeddis@0 89 if ~isempty(errormsg)
rmeddis@0 90 % e.g. clipping. subjGUI will service the error
rmeddis@0 91 return
rmeddis@0 92 end
rmeddis@0 93
rmeddis@0 94 % after playing the stimulus, reset the subjectGUI
rmeddis@0 95 switch experiment.ear
rmeddis@0 96 case {'statsModelLogistic', 'statsModelRareEvent',...
rmeddis@0 97 'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh'}
rmeddis@0 98 % no changes required if model used
rmeddis@0 99 % NB these changes do occur is 'MAPmodelListen' is selected
rmeddis@0 100 otherwise
rmeddis@0 101 switch experiment.threshEstMethod
rmeddis@0 102 case {'2I2AFC++', '2I2AFC+++'}
rmeddis@0 103 % buttons already visible
rmeddis@0 104 otherwise
rmeddis@0 105 % single interval now make buttons visible
rmeddis@0 106 set(handles.frame1,'visible','on')
rmeddis@0 107 set(handles.pushbuttoNotSure,'visible','on')
rmeddis@0 108 % set(handles.pushbuttonWrongButton,'visible','on')
rmeddis@0 109 set(handles.pushbutton0,'visible','on')
rmeddis@0 110 set(handles.pushbutton1,'visible','on')
rmeddis@0 111 set(handles.pushbutton2,'visible','on')
rmeddis@0 112 set(handles.pushbutton3,'visible','on')
rmeddis@0 113 end
rmeddis@0 114 end
rmeddis@0 115
rmeddis@0 116 switch experiment.paradigm
rmeddis@0 117 case 'SRT'
rmeddis@0 118 set(handles.frame1,'backgroundColor','w')
rmeddis@0 119 set(handles.frame1,'visible','off')
rmeddis@0 120 set(handles.pushbuttoNotSure,'visible','off')
rmeddis@0 121 set(handles.pushbuttonWrongButton,'visible','off')
rmeddis@0 122 set(handles.pushbutton3,'visible','off')
rmeddis@0 123 set(handles.pushbutton2,'visible','off')
rmeddis@0 124 set(handles.pushbutton1,'visible','off')
rmeddis@0 125 set(handles.pushbutton0,'visible','off')
rmeddis@0 126 set(handles.editdigitInput,'visible','on')
rmeddis@0 127 set(handles.editdigitInput,'string',[])
rmeddis@0 128 pause(.2)
rmeddis@0 129 uicontrol(handles.editdigitInput)
rmeddis@0 130
rmeddis@0 131 otherwise
rmeddis@0 132 set(handles.editdigitInput,'visible','off')
rmeddis@0 133 end
rmeddis@0 134
rmeddis@0 135
rmeddis@0 136 experiment.status='waitingForResponse';
rmeddis@0 137 % home again
rmeddis@0 138
rmeddis@0 139 % ------------------------------------------------------------------------------------------stimulusMakeAndPlay
rmeddis@0 140 function errormsg=stimulusMakeAndPlay (handles)
rmeddis@0 141 global experiment stimulusParameters betweenRuns withinRuns expGUIhandles audio
rmeddis@0 142 % creates the stimulus and plays it; there are two stimuli; cue and test
rmeddis@0 143 % called from nextStimulus
rmeddis@0 144
rmeddis@0 145 errormsg='';
rmeddis@0 146
rmeddis@0 147 % first post the subjects instructions on subjGUI
rmeddis@0 148 set(handles.textMSG,'string', stimulusParameters.subjectText)
rmeddis@0 149
rmeddis@0 150 % select the new levels of the between runs variables
rmeddis@0 151 num=betweenRuns.runNumber;
rmeddis@0 152 cmd=(['stimulusParameters.' betweenRuns.variableName1 '= ' ...
rmeddis@0 153 num2str(betweenRuns.var1Sequence(num)) ';']);
rmeddis@0 154 % e.g. stimulusParameters.targetFrequency= 1000;
rmeddis@0 155 eval(cmd);
rmeddis@0 156
rmeddis@0 157 cmd=(['stimulusParameters.' betweenRuns.variableName2 '= ' ...
rmeddis@0 158 num2str(betweenRuns.var2Sequence(num)) ';']);
rmeddis@0 159 % e.g. stimulusParameters.targetDuration= 0.1;
rmeddis@0 160 eval(cmd);
rmeddis@0 161
rmeddis@0 162 switch experiment.paradigm
rmeddis@0 163 % target level may vary between runs
rmeddis@0 164 case {'trainingIFMC', 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms','IFMC_16ms'}
rmeddis@0 165 idx=floor(num/length(betweenRuns.variableList1)-0.01)+1;
rmeddis@0 166 cmd=(['stimulusParameters.targetLevel = ' ...
rmeddis@0 167 num2str(stimulusParameters.targetLevels(idx)) ';']);
rmeddis@0 168 eval(cmd);
rmeddis@0 169 if withinRuns.trialNumber==1
rmeddis@0 170 disp(['targetLevel=' num2str(stimulusParameters.targetLevel)])
rmeddis@0 171 end
rmeddis@0 172 end
rmeddis@0 173
rmeddis@0 174
rmeddis@0 175 % for more readable code use shorter variable names;
rmeddis@0 176 % NB these may change below; these are only the starting values
rmeddis@0 177
rmeddis@0 178 targetType= stimulusParameters.targetType;
rmeddis@0 179 targetDuration= stimulusParameters.targetDuration;
rmeddis@0 180 targetLevel= stimulusParameters.targetLevel;
rmeddis@0 181 targetFrequency= stimulusParameters.targetFrequency;
rmeddis@0 182
rmeddis@0 183 maskerType= stimulusParameters.maskerType;
rmeddis@0 184 maskerDuration= stimulusParameters.maskerDuration;
rmeddis@0 185 maskerLevel= stimulusParameters.maskerLevel;
rmeddis@0 186 maskerRelativeFrequency= stimulusParameters.maskerRelativeFrequency;
rmeddis@0 187 maskerFrequency= maskerRelativeFrequency*targetFrequency;
rmeddis@0 188
rmeddis@0 189 gapDuration= stimulusParameters.gapDuration;
rmeddis@0 190
rmeddis@0 191 rampDuration= stimulusParameters.rampDuration;
rmeddis@0 192 AFCsilenceDuration=stimulusParameters.AFCsilenceDuration; % 2I2AFC gap
rmeddis@0 193 backgroundLevel= stimulusParameters.backgroundLevel;
rmeddis@0 194
rmeddis@0 195 % Set level of within runs variable
rmeddis@0 196 % this is the first change to one of the values shown above
rmeddis@0 197 cmd=[stimulusParameters.WRVname '= withinRuns.variableValue;' ];
rmeddis@0 198 % e.g.: maskerLevel= withinRuns.variableValue;
rmeddis@0 199 eval(cmd);
rmeddis@0 200
rmeddis@0 201 % cue and test stimuli are identical except for a single difference
rmeddis@0 202 % depending on the paradigm
rmeddis@0 203 cueTestDifference= stimulusParameters.cueTestDifference;
rmeddis@0 204 % cue characteristics before adding cue differences
rmeddis@0 205 cueTargetLevel=targetLevel;
rmeddis@0 206 cueMaskerFrequency=maskerFrequency;
rmeddis@0 207 cueMaskerDuration=maskerDuration;
rmeddis@0 208 cueMaskerLevel=maskerLevel;
rmeddis@0 209 cueTargetFrequency=targetFrequency;
rmeddis@0 210 cueGapDuration=gapDuration;
rmeddis@0 211
rmeddis@0 212 % ----------------------------paradigm sensitive cue and masker settings
rmeddis@0 213 % switch off unwanted components and base cue on target values
rmeddis@0 214 % for catch trials switch off the target
rmeddis@0 215 switch experiment.paradigm
rmeddis@0 216 % OHIO is a temporary special arrangement
rmeddis@0 217 case{'OHIOrand','OHIOspect','OHIOtemp','OHIOspectemp','OHIOabs'}
rmeddis@0 218 % these values must be set in MAPparamsOHIO
rmeddis@0 219 targetFrequency=experiment.OHIOfrequencies;
rmeddis@0 220 numOHIOtones=stimulusParameters.numOHIOtones;
rmeddis@0 221 maskerType='OHIO';
rmeddis@0 222 targetType='OHIO';
rmeddis@0 223
rmeddis@0 224 % globalStimParams.beginSilences says when each tone begins
rmeddis@0 225 % targetFrequency specifies the frequency of each tone
rmeddis@0 226 % targetLevel is the level of each tone
rmeddis@0 227 switch experiment.paradigm
rmeddis@0 228 case 'OHIOabs'
rmeddis@0 229 % only one tone
rmeddis@0 230 targetFrequency=targetFrequency(numOHIOtones);
rmeddis@0 231 globalStimParams.beginSilences=0.01;
rmeddis@0 232 targetDuration=0.01;
rmeddis@0 233 case 'OHIOrand'
rmeddis@0 234 % select random frequencies from the list
rmeddis@0 235 x=rand(12,1); [x idx]=sort(x);
rmeddis@0 236 targetFrequency=targetFrequency(idx(1:numOHIOtones));
rmeddis@0 237 thresholds=experiment.OHIOthresholds;
rmeddis@0 238 targetLevel=thresholds(idx(1:numOHIOtones))+targetLevel;
rmeddis@0 239 globalStimParams.beginSilences=0.01:0.02:...
rmeddis@0 240 0.01+0.02*(numOHIOtones-1);
rmeddis@0 241 targetDuration=numOHIOtones*0.02;
rmeddis@0 242 case 'OHIOspect'
rmeddis@0 243 % only one tone with multiple frequencies
rmeddis@0 244 targetFrequency=fliplr(targetFrequency);
rmeddis@0 245 targetFrequency=targetFrequency(1:numOHIOtones);
rmeddis@0 246 thresholds=experiment.OHIOthresholds;
rmeddis@0 247 thresholds=fliplr(thresholds);
rmeddis@0 248 targetLevel=thresholds(1:numOHIOtones)+targetLevel;
rmeddis@0 249 globalStimParams.beginSilences=...
rmeddis@0 250 repmat(0.01, 1, numOHIOtones);
rmeddis@0 251 targetDuration=0.02;
rmeddis@0 252 case 'OHIOspectemp'
rmeddis@0 253 % only one tone with multiple frequencies
rmeddis@0 254 targetFrequency=fliplr(targetFrequency);
rmeddis@0 255 targetFrequency=targetFrequency(1:numOHIOtones);
rmeddis@0 256 thresholds=experiment.OHIOthresholds;
rmeddis@0 257 thresholds=fliplr(thresholds);
rmeddis@0 258 targetLevel=thresholds(1:numOHIOtones)+targetLevel;
rmeddis@0 259 globalStimParams.beginSilences=0.01:0.02:...
rmeddis@0 260 0.01+0.02*(numOHIOtones-1);
rmeddis@0 261 targetDuration=numOHIOtones*0.02;
rmeddis@0 262 case 'OHIOtemp'
rmeddis@0 263 % use only one tone repeatedly
rmeddis@0 264 tonesToUse=10;
rmeddis@0 265 targetFrequency=targetFrequency(tonesToUse);
rmeddis@0 266 targetFrequency=repmat(targetFrequency,1,numOHIOtones);
rmeddis@0 267 thresholds=experiment.OHIOthresholds;
rmeddis@0 268 thresholds=thresholds(tonesToUse);
rmeddis@0 269 targetLevel=repmat(thresholds,1,numOHIOtones)+targetLevel;
rmeddis@0 270 globalStimParams.beginSilences=0.01:0.02:...
rmeddis@0 271 0.01+0.02*(numOHIOtones-1);
rmeddis@0 272 targetDuration=numOHIOtones*0.02;
rmeddis@0 273 end
rmeddis@0 274 % still in OHIO
rmeddis@0 275 % Dummy values to make things work although no masker or cue used
rmeddis@0 276 % target values have changed and this affects the cue values
rmeddis@0 277 cueMaskerLevel=targetLevel;
rmeddis@0 278 cueTargetLevel=targetLevel;
rmeddis@0 279 cueTargetFrequency=targetFrequency;
rmeddis@0 280 cueMaskerFrequency=targetFrequency;
rmeddis@0 281 maskerFrequency=targetFrequency;
rmeddis@0 282 maskerLevel=targetLevel;
rmeddis@0 283 disp(['OHIO frequencies= ' num2str(targetFrequency)])
rmeddis@0 284 end
rmeddis@0 285
rmeddis@0 286 % --- set cueTarget level according to assessment method
rmeddis@0 287 % cue-test difference applies only with singleInterval
rmeddis@0 288 switch experiment.threshEstMethod
rmeddis@0 289 case {'2I2AFC++', '2I2AFC+++'}
rmeddis@0 290 % For 2IFC the cue stimulus (masker + probe) is the 'no' window
rmeddis@0 291 % and the target stimulus (masker+probe) is the 'yes' window
rmeddis@0 292 % the order of presentation is decided at the last minute.
rmeddis@0 293 cueTargetLevel=-100; % the target is never in the 'no' window
rmeddis@0 294 cueMaskerLevel=maskerLevel; % masker level is the same in both
rmeddis@0 295 otherwise
rmeddis@0 296 % 'single interval' or max likelihood
rmeddis@0 297 switch experiment.paradigm
rmeddis@0 298 % cue target is more audible
rmeddis@0 299 case {'training','absThreshold', 'absThreshold_8', ...
rmeddis@0 300 'TENtest', 'threshold_duration','discomfort',...
rmeddis@0 301 'overShoot','overShootB','overShootMB1', ...
rmeddis@0 302 'overShootMB2', 'OHIO','OHIOabs','OHIOspect'}
rmeddis@0 303 cueTargetLevel=targetLevel+cueTestDifference;
rmeddis@0 304
rmeddis@0 305 case {'forwardMasking','forwardMaskingD','trainingIFMC', ...
rmeddis@0 306 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms', 'FMreProbe'}
rmeddis@0 307 % cue masker is weaker to make target more audible
rmeddis@0 308 cueMaskerLevel=maskerLevel-cueTestDifference;
rmeddis@0 309 end
rmeddis@0 310 end
rmeddis@0 311
rmeddis@0 312 % ----------------------------- catch trial
rmeddis@0 313 if withinRuns.catchTrial
rmeddis@0 314 targetLevel=-100; % no target
rmeddis@0 315 end
rmeddis@0 316
rmeddis@0 317 % -------------------------------------- Checks on excessive signal level
rmeddis@0 318
rmeddis@0 319 % clipping is relevant only for soundcard use (not modelling)
rmeddis@0 320 switch experiment.ear
rmeddis@0 321 case {'left', 'right', 'diotic',...
rmeddis@0 322 'dichotic', 'dioticLeft', 'dichoticRight'}
rmeddis@0 323 experiment.headphonesUsed=1;
rmeddis@0 324 otherwise
rmeddis@0 325 experiment.headphonesUsed=0;
rmeddis@0 326 end
rmeddis@0 327
rmeddis@0 328 % NB calibration *reduces* the level of the soundCard output
rmeddis@0 329 switch experiment.ear
rmeddis@0 330 case {'left', 'right', 'diotic',...
rmeddis@0 331 'dichotic', 'dioticLeft', 'dichoticRight'}
rmeddis@0 332 clippingLevel=91+stimulusParameters.calibrationdB;
rmeddis@0 333 soundCardMinimum=clippingLevel-20*log10(2^24);
rmeddis@0 334 otherwise
rmeddis@0 335 clippingLevel=inf;
rmeddis@0 336 soundCardMinimum=-inf;
rmeddis@0 337 end
rmeddis@0 338
rmeddis@0 339 % Check for extreme WRV values and abort if necessary
rmeddis@0 340 % WRVname specifies the value that changes from trial to trial
rmeddis@0 341 withinRuns.forceThreshold=[];
rmeddis@0 342 switch stimulusParameters.WRVname
rmeddis@0 343 % check for extreme values. Note that one of the tones might be switched off
rmeddis@0 344 case 'maskerLevel'
rmeddis@0 345 upperLevel=stimulusParameters.WRVlimits(2);
rmeddis@0 346 lowerLevel=stimulusParameters.WRVlimits(1);
rmeddis@0 347 if max(maskerLevel, cueMaskerLevel)> upperLevel
rmeddis@0 348 errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ...
rmeddis@0 349 ') is too high ***'];
rmeddis@0 350 withinRuns.forceThreshold=upperLevel;
rmeddis@0 351 withinRuns.forceThreshold=NaN;
rmeddis@0 352 return
rmeddis@0 353 end
rmeddis@0 354 if max(maskerLevel, cueMaskerLevel)< lowerLevel
rmeddis@0 355 errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ...
rmeddis@0 356 ') is too low ***'];
rmeddis@0 357 withinRuns.forceThreshold=lowerLevel;
rmeddis@0 358 withinRuns.forceThreshold=NaN;
rmeddis@0 359 return
rmeddis@0 360 end
rmeddis@0 361
rmeddis@0 362 if max(maskerLevel, cueMaskerLevel)> clippingLevel
rmeddis@0 363 errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ...
rmeddis@0 364 ') is clipping ***'];
rmeddis@0 365 withinRuns.forceThreshold=clippingLevel;
rmeddis@0 366 withinRuns.forceThreshold=NaN;
rmeddis@0 367 return
rmeddis@0 368 end
rmeddis@0 369
rmeddis@0 370 case 'targetLevel'
rmeddis@0 371 upperLevel=stimulusParameters.WRVlimits(2);
rmeddis@0 372 lowerLevel=stimulusParameters.WRVlimits(1);
rmeddis@0 373 if ~withinRuns.catchTrial
rmeddis@0 374 if max(targetLevel, cueTargetLevel)> upperLevel
rmeddis@0 375 errormsg=['target level (' ...
rmeddis@0 376 num2str(max(targetLevel, cueTargetLevel)) ...
rmeddis@0 377 ') is too high ***'];
rmeddis@0 378 withinRuns.forceThreshold=upperLevel;
rmeddis@0 379 withinRuns.forceThreshold=NaN;
rmeddis@0 380 return
rmeddis@0 381 end
rmeddis@0 382 if max(targetLevel, cueTargetLevel)< lowerLevel
rmeddis@0 383 errormsg=['target level (' ...
rmeddis@0 384 num2str(max(targetLevel, cueTargetLevel)) ...
rmeddis@0 385 ') is too low ***'];
rmeddis@0 386 withinRuns.forceThreshold=lowerLevel;
rmeddis@0 387 withinRuns.forceThreshold=NaN;
rmeddis@0 388 return
rmeddis@0 389 end
rmeddis@0 390 if max(targetLevel, cueTargetLevel)> clippingLevel
rmeddis@0 391 errormsg=['target level (' ...
rmeddis@0 392 num2str(max(targetLevel, cueTargetLevel)) ...
rmeddis@0 393 ') is clipping ***'];
rmeddis@0 394 withinRuns.forceThreshold=upperLevel;
rmeddis@0 395 withinRuns.forceThreshold=NaN;
rmeddis@0 396 return
rmeddis@0 397 end
rmeddis@0 398 end
rmeddis@0 399 case 'maskerDuration'
rmeddis@0 400 % this is odd! but harmless
rmeddis@0 401 if max(maskerDuration, cueMaskerDuration)> ...
rmeddis@0 402 stimulusParameters.WRVlimits(2)
rmeddis@0 403 errormsg=['maskerDuration (' ...
rmeddis@0 404 num2str(max(maskerDuration, cueMaskerDuration))...
rmeddis@0 405 ') is too long ***'];
rmeddis@0 406 withinRuns.forceThreshold=stimulusParameters.WRVlimits(2);
rmeddis@0 407 withinRuns.forceThreshold=NaN;
rmeddis@0 408 return
rmeddis@0 409 end
rmeddis@0 410
rmeddis@0 411 if min(maskerDuration, cueMaskerDuration)...
rmeddis@0 412 < stimulusParameters.WRVlimits(1)
rmeddis@0 413 errormsg=['maskerDuration (' num2str(maskerLevel) ...
rmeddis@0 414 ') too short ***'];
rmeddis@0 415 withinRuns.forceThreshold=stimulusParameters.WRVlimits(1);
rmeddis@0 416 withinRuns.forceThreshold=NaN;
rmeddis@0 417 return
rmeddis@0 418 end
rmeddis@0 419
rmeddis@0 420 % legacy programming
rmeddis@0 421 case 'gapDuration'
rmeddis@0 422 if gapDuration<0
rmeddis@0 423 errormsg=['gapDuration (' num2str(gapDuration) ...
rmeddis@0 424 ') is less than zero ***'];
rmeddis@0 425 return
rmeddis@0 426 end
rmeddis@0 427
rmeddis@0 428 case 'maskerFrequency'
rmeddis@0 429 switch experiment.paradigm
rmeddis@0 430 case 'bandwidth'
rmeddis@0 431 frequency=maskerFrequency';
rmeddis@0 432 if stimulusParameters.WRVstep<0
rmeddis@0 433 lowerLevel=stimulusParameters.targetFrequency;
rmeddis@0 434 upperLevel=stimulusParameters.targetFrequency*2;
rmeddis@0 435 else
rmeddis@0 436 lowerLevel=stimulusParameters.targetFrequency/3;
rmeddis@0 437 upperLevel=stimulusParameters.targetFrequency;
rmeddis@0 438 end
rmeddis@0 439
rmeddis@0 440 if frequency(1)>upperLevel || frequency(1)<lowerLevel
rmeddis@0 441 errormsg=['frequency out of range: ' ...
rmeddis@0 442 num2str(frequency)];
rmeddis@0 443 withinRuns.forceThreshold=frequency;
rmeddis@0 444 return
rmeddis@0 445 end
rmeddis@0 446 otherwise
rmeddis@0 447 end
rmeddis@0 448
rmeddis@0 449 case 'maskerRelativeFrequency'
rmeddis@0 450 if maskerRelativeFrequency<stimulusParameters.WRVlimits(1)
rmeddis@0 451 errormsg=['masker frequency (' ...
rmeddis@0 452 num2str(frequencyDifference) ...
rmeddis@0 453 ') is outside WRV limits ***'];
rmeddis@0 454 withinRuns.forceThreshold=stimulusParameters.WRVlimits(1) ;
rmeddis@0 455 return
rmeddis@0 456 end
rmeddis@0 457 if maskerRelativeFrequency>stimulusParameters.WRVlimits(2)
rmeddis@0 458 errormsg=['masker frequency (' ...
rmeddis@0 459 num2str(frequencyDifference) ...
rmeddis@0 460 ') is outside WRV limits ***'];
rmeddis@0 461 withinRuns.forceThreshold=stimulusParameters.WRVlimits(2) ;
rmeddis@0 462 return
rmeddis@0 463 end
rmeddis@0 464
rmeddis@0 465 end
rmeddis@0 466
rmeddis@0 467 % --------------------------------Ear ----------------------------------
rmeddis@0 468 globalStimParams.ears='specified';
rmeddis@0 469 % ear: 1=left, 2=right
rmeddis@0 470 switch experiment.ear
rmeddis@0 471 case 'left'
rmeddis@0 472 maskerEar=1;
rmeddis@0 473 targetEar=1;
rmeddis@0 474 case 'right'
rmeddis@0 475 maskerEar=2;
rmeddis@0 476 targetEar=2;
rmeddis@0 477 case 'dichoticLeft'
rmeddis@0 478 maskerEar=2;
rmeddis@0 479 targetEar=1;
rmeddis@0 480 case 'dichoticRight'
rmeddis@0 481 maskerEar=1;
rmeddis@0 482 targetEar=2;
rmeddis@0 483 case 'diotic'
rmeddis@0 484 maskerEar=1;
rmeddis@0 485 targetEar=1;
rmeddis@0 486 globalStimParams.ears='diotic';
rmeddis@0 487 case {'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh', 'MAPmodelListen',...
rmeddis@0 488 'statsModelLogistic', 'statsModelRareEvent'}
rmeddis@0 489 maskerEar=1;
rmeddis@0 490 targetEar=1;
rmeddis@0 491 end
rmeddis@0 492
rmeddis@0 493 backgroundType=stimulusParameters.backgroundType;
rmeddis@0 494 switch stimulusParameters.backgroundType
rmeddis@0 495 case {'noiseDich', 'pinkNoiseDich'}
rmeddis@0 496 % case 'Dich'
rmeddis@0 497 % dich means put the background in the ear opposite to the target
rmeddis@0 498 backgroundType=backgroundType(1:end-4);
rmeddis@0 499 switch targetEar
rmeddis@0 500 case 1
rmeddis@0 501 backgroundEar=2;
rmeddis@0 502 case 2
rmeddis@0 503 backgroundEar=1;
rmeddis@0 504 end
rmeddis@0 505 otherwise
rmeddis@0 506 % case {'none','noise', 'pinkNoise', 'TEN','babble'}
rmeddis@0 507 backgroundEar=targetEar;
rmeddis@0 508 end
rmeddis@0 509
rmeddis@0 510 % ------------------------------- Make Stimulus -------------------
rmeddis@0 511 % single interval up/down plays cue then target stimulus
rmeddis@0 512 % 2IFC uses cue stimulus as interval with no target
rmeddis@0 513 globalStimParams.FS=stimulusParameters.sampleRate;
rmeddis@0 514 dt=1/stimulusParameters.sampleRate;
rmeddis@0 515 globalStimParams.dt=dt;
rmeddis@0 516 stimulusParameters.dt=dt; % for use later
rmeddis@0 517
rmeddis@0 518 % calibration of sound output
rmeddis@0 519 correctiondB=stimulusParameters.calibrationdB;
rmeddis@0 520 globalStimParams.audioOutCorrection=10^(correctiondB/20);
rmeddis@0 521 % the output will be reduced by this amount in stimulusCreate
rmeddis@0 522 % i.e. audio=audio/globalStimParams.audioOutCorrection
rmeddis@0 523 % A 91 dB level will yield a peak amp of 1 for calibration=0
rmeddis@0 524 % A 91 dB level will yield a peak amp of 0.4467 for calibration=7
rmeddis@0 525 % A 98 dB level will yield a peak amp of 1 for calibration=7
rmeddis@0 526
rmeddis@0 527 precedingSilence=stimulusParameters.stimulusDelay;
rmeddis@0 528 % all stimuli have 20 ms terminal silence.
rmeddis@0 529 % this is clearance for modelling late-ringing targets
rmeddis@0 530 terminalSilence=.03;
rmeddis@0 531
rmeddis@0 532 % Now compute overall duration of the stimulus
rmeddis@0 533 % note that all endsilence values are set to -1
rmeddis@0 534 % so that they will fill with terminal silence as required to make
rmeddis@0 535 % components equal in length
rmeddis@0 536 % We need to find the longest possible duration
rmeddis@0 537 duration(1)=precedingSilence+maskerDuration+cueGapDuration...
rmeddis@0 538 +targetDuration+terminalSilence;
rmeddis@0 539 duration(2)=precedingSilence+maskerDuration+gapDuration...
rmeddis@0 540 +targetDuration+ terminalSilence;
rmeddis@0 541 % If the gap is negative we need to ignore it when estimating total length
rmeddis@0 542 duration(3)=precedingSilence+maskerDuration+ terminalSilence;
rmeddis@0 543 globalStimParams.overallDuration=max(duration);
rmeddis@0 544 globalStimParams.nSignalPoints=...
rmeddis@0 545 round(globalStimParams.overallDuration/globalStimParams.dt);
rmeddis@0 546
rmeddis@0 547 % ----------------------------------------------cue stimulus
rmeddis@0 548 % cue masker
rmeddis@0 549 componentNo=1;
rmeddis@0 550 precedingSilence=stimulusParameters.stimulusDelay;
rmeddis@0 551 stimComponents(maskerEar,componentNo).type=maskerType;
rmeddis@0 552 stimComponents(maskerEar,componentNo).toneDuration=cueMaskerDuration;
rmeddis@0 553 stimComponents(maskerEar,componentNo).frequencies=cueMaskerFrequency;
rmeddis@0 554 stimComponents(maskerEar,componentNo).amplitudesdB=cueMaskerLevel;
rmeddis@0 555 stimComponents(maskerEar,componentNo).beginSilence=precedingSilence;
rmeddis@0 556 stimComponents(maskerEar,componentNo).endSilence=-1;
rmeddis@0 557 stimComponents(maskerEar,componentNo).AMfrequency=0;
rmeddis@0 558 stimComponents(maskerEar,componentNo).AMdepth=0;
rmeddis@0 559 if rampDuration<maskerDuration
rmeddis@0 560 % ramps must be shorter than the signal
rmeddis@0 561 stimComponents(maskerEar,componentNo).rampOnDur=rampDuration;
rmeddis@0 562 stimComponents(maskerEar,componentNo).rampOffDur=rampDuration;
rmeddis@0 563 else
rmeddis@0 564 % or squeeze the ramp in
rmeddis@0 565 stimComponents(maskerEar,componentNo).rampOnDur=maskerDuration/2;
rmeddis@0 566 stimComponents(maskerEar,componentNo).rampOffDur=maskerDuration/2;
rmeddis@0 567 end
rmeddis@0 568 stimComponents(maskerEar,componentNo).phases=...
rmeddis@0 569 stimulusParameters.maskerPhase;
rmeddis@0 570 stimComponents(maskerEar,componentNo).niterations=0; % for IRN only
rmeddis@0 571 % stimComponents(targetEar,componentNo)
rmeddis@0 572
rmeddis@0 573 % cue target
rmeddis@0 574 componentNo=2;
rmeddis@0 575 precedingSilence=precedingSilence + maskerDuration+cueGapDuration;
rmeddis@0 576 stimComponents(targetEar,componentNo).type=targetType;
rmeddis@0 577 stimComponents(targetEar,componentNo).toneDuration=targetDuration;
rmeddis@0 578 stimComponents(targetEar,componentNo).frequencies=cueTargetFrequency;
rmeddis@0 579 stimComponents(targetEar,componentNo).amplitudesdB=cueTargetLevel;
rmeddis@0 580 stimComponents(targetEar,componentNo).beginSilence=precedingSilence;
rmeddis@0 581 stimComponents(targetEar,componentNo).endSilence=-1;
rmeddis@0 582 stimComponents(targetEar,componentNo).AMfrequency=0;
rmeddis@0 583 stimComponents(targetEar,componentNo).AMdepth=0;
rmeddis@0 584 if rampDuration<targetDuration
rmeddis@0 585 % ramps must be shorter than the signal
rmeddis@0 586 stimComponents(targetEar,componentNo).rampOnDur=rampDuration;
rmeddis@0 587 stimComponents(targetEar,componentNo).rampOffDur=rampDuration;
rmeddis@0 588 else
rmeddis@0 589 stimComponents(targetEar,componentNo).rampOnDur=0;
rmeddis@0 590 stimComponents(targetEar,componentNo).rampOffDur=0;
rmeddis@0 591 end
rmeddis@0 592 stimComponents(targetEar,componentNo).phases=...
rmeddis@0 593 stimulusParameters.targetPhase;
rmeddis@0 594 % stimComponents(targetEar,componentNo)
rmeddis@0 595
rmeddis@0 596 % background same ear as target
rmeddis@0 597 componentNo=3;
rmeddis@0 598 stimComponents(backgroundEar,componentNo).type=backgroundType;
rmeddis@0 599 switch backgroundType
rmeddis@0 600 case 'TEN'
rmeddis@0 601 fileName=['..' filesep '..' filesep ...
rmeddis@0 602 'multithresholdResources' filesep ...
rmeddis@0 603 'backgrounds and maskers'...
rmeddis@0 604 filesep 'ten.wav'];
rmeddis@0 605 [tenNoise, FS]=wavread(fileName);
rmeddis@0 606 tenNoise=resample(tenNoise, globalStimParams.FS, FS);
rmeddis@0 607 stimComponents(backgroundEar,componentNo).type='file';
rmeddis@0 608 stimComponents(backgroundEar,componentNo).stimulus=tenNoise';
rmeddis@0 609 end
rmeddis@0 610 stimComponents(backgroundEar,componentNo).toneDuration=...
rmeddis@0 611 globalStimParams.overallDuration;
rmeddis@0 612 stimComponents(backgroundEar,componentNo).amplitudesdB=backgroundLevel;
rmeddis@0 613 stimComponents(backgroundEar,componentNo).beginSilence=0;
rmeddis@0 614 stimComponents(backgroundEar,componentNo).endSilence=-1;
rmeddis@0 615 stimComponents(backgroundEar,componentNo).AMfrequency=0;
rmeddis@0 616 stimComponents(backgroundEar,componentNo).AMdepth=0;
rmeddis@0 617 stimComponents(backgroundEar,componentNo).rampOnDur=rampDuration;
rmeddis@0 618 stimComponents(backgroundEar,componentNo).rampOffDur=rampDuration;
rmeddis@0 619
rmeddis@0 620 [cueStimulus, errormsg]=...
rmeddis@0 621 stimulusCreate(globalStimParams, stimComponents, 0);
rmeddis@0 622 if ~isempty(errormsg) % e.g. limits exceeded
rmeddis@0 623 errormsg
rmeddis@0 624 return
rmeddis@0 625 end
rmeddis@0 626
rmeddis@0 627 % ------------------------------------------ test stimulus
rmeddis@0 628 % masker
rmeddis@0 629 componentNo=1;
rmeddis@0 630 precedingSilence=stimulusParameters.stimulusDelay;
rmeddis@0 631 stimComponents(maskerEar,componentNo).type=maskerType;
rmeddis@0 632 stimComponents(maskerEar,componentNo).toneDuration=maskerDuration;
rmeddis@0 633 stimComponents(maskerEar,componentNo).frequencies=maskerFrequency;
rmeddis@0 634 stimComponents(maskerEar,componentNo).amplitudesdB=maskerLevel;
rmeddis@0 635 stimComponents(maskerEar,componentNo).beginSilence=precedingSilence;
rmeddis@0 636 stimComponents(maskerEar,componentNo).endSilence=-1;
rmeddis@0 637 stimComponents(maskerEar,componentNo).AMfrequency=0;
rmeddis@0 638 stimComponents(maskerEar,componentNo).AMdepth=0;
rmeddis@0 639 if rampDuration<maskerDuration
rmeddis@0 640 % ramps must be shorter than the signal
rmeddis@0 641 stimComponents(maskerEar,componentNo).rampOnDur=rampDuration;
rmeddis@0 642 stimComponents(maskerEar,componentNo).rampOffDur=rampDuration;
rmeddis@0 643 else
rmeddis@0 644 stimComponents(maskerEar,componentNo).rampOnDur=maskerDuration/2;
rmeddis@0 645 stimComponents(maskerEar,componentNo).rampOffDur=maskerDuration/2;
rmeddis@0 646 end
rmeddis@0 647 stimComponents(maskerEar,componentNo).phases=...
rmeddis@0 648 stimulusParameters.maskerPhase;
rmeddis@0 649 stimComponents(maskerEar,componentNo).niterations=0; % for IRN only
rmeddis@0 650
rmeddis@0 651 % target
rmeddis@0 652 componentNo=2;
rmeddis@0 653 targetDelay=precedingSilence+ maskerDuration+ gapDuration;
rmeddis@0 654 stimComponents(targetEar,componentNo).type=targetType;
rmeddis@0 655 stimComponents(targetEar,componentNo).toneDuration=targetDuration;
rmeddis@0 656 stimComponents(targetEar,componentNo).frequencies=targetFrequency;
rmeddis@0 657 stimComponents(targetEar,componentNo).amplitudesdB=targetLevel;
rmeddis@0 658 stimComponents(targetEar,componentNo).beginSilence=targetDelay;
rmeddis@0 659 stimComponents(targetEar,componentNo).endSilence=-1;
rmeddis@0 660 stimComponents(targetEar,componentNo).AMfrequency=0;
rmeddis@0 661 stimComponents(targetEar,componentNo).AMdepth=0;
rmeddis@0 662 if rampDuration<targetDuration
rmeddis@0 663 % ramps must be shorter than the signal
rmeddis@0 664 stimComponents(targetEar,componentNo).rampOnDur=rampDuration;
rmeddis@0 665 stimComponents(targetEar,componentNo).rampOffDur=rampDuration;
rmeddis@0 666 else
rmeddis@0 667 stimComponents(targetEar,componentNo).rampOnDur=0;
rmeddis@0 668 stimComponents(targetEar,componentNo).rampOffDur=0;
rmeddis@0 669 end
rmeddis@0 670 stimComponents(targetEar,componentNo).phases=stimulusParameters.targetPhase;
rmeddis@0 671 % stimComponents(targetEar,componentNo)
rmeddis@0 672
rmeddis@0 673 % background same ear as target
rmeddis@0 674 componentNo=3;
rmeddis@0 675 stimComponents(backgroundEar,componentNo).type=backgroundType;
rmeddis@0 676 switch backgroundType
rmeddis@0 677 case 'TEN'
rmeddis@0 678 fileName=['..' filesep '..' filesep ...
rmeddis@0 679 'multithresholdResources' filesep ...
rmeddis@0 680 'backgrounds and maskers'...
rmeddis@0 681 filesep 'ten.wav'];
rmeddis@0 682 [tenNoise, FS]=wavread(fileName);
rmeddis@0 683
rmeddis@0 684 tenNoise=resample(tenNoise, globalStimParams.FS, FS);
rmeddis@0 685 stimComponents(backgroundEar,componentNo).type='file';
rmeddis@0 686 stimComponents(backgroundEar,componentNo).stimulus=tenNoise';
rmeddis@0 687 end
rmeddis@0 688 stimComponents(backgroundEar,componentNo).toneDuration=...
rmeddis@0 689 globalStimParams.overallDuration;
rmeddis@0 690 stimComponents(backgroundEar,componentNo).amplitudesdB=backgroundLevel;
rmeddis@0 691 stimComponents(backgroundEar,componentNo).beginSilence=0;
rmeddis@0 692 stimComponents(backgroundEar,componentNo).endSilence=-1;
rmeddis@0 693 stimComponents(backgroundEar,componentNo).rampOnDur=rampDuration;
rmeddis@0 694 stimComponents(backgroundEar,componentNo).rampOffDur=rampDuration;
rmeddis@0 695 stimComponents(backgroundEar,componentNo).AMfrequency=0;
rmeddis@0 696 stimComponents(backgroundEar,componentNo).AMdepth=0;
rmeddis@0 697
rmeddis@0 698 % timings used when evaluating MAP peripheral model
rmeddis@0 699 % this is the Slope during which spikes are counted
rmeddis@0 700 switch experiment.paradigm
rmeddis@0 701 case 'gapDetection'
rmeddis@0 702 % gap is the 'target' in this case
rmeddis@0 703 stimulusParameters.testTargetBegins=...
rmeddis@0 704 stimulusParameters.stimulusDelay...
rmeddis@0 705 +stimulusParameters.maskerDuration;
rmeddis@0 706 stimulusParameters.testTargetEnds=...
rmeddis@0 707 stimulusParameters.testTargetBegins+withinRuns.variableValue;
rmeddis@0 708 % case 'SRT'
rmeddis@0 709 % set(handles.editdigitInput,'visible','off')
rmeddis@0 710 otherwise
rmeddis@0 711 stimulusParameters.testTargetBegins=targetDelay;
rmeddis@0 712 stimulusParameters.testTargetEnds=targetDelay+targetDuration;
rmeddis@0 713 end
rmeddis@0 714
rmeddis@0 715 % ------------------------------------------------------------- play!
rmeddis@0 716 % Create and play stimulus (as required by different paradigms)
rmeddis@0 717 switch experiment.ear
rmeddis@0 718 case {'statsModelLogistic', 'statsModelRareEvent'}
rmeddis@0 719 audio=[0;0]; % no need to compute stimulus
rmeddis@0 720
rmeddis@0 721 otherwise % create the stimulus
rmeddis@0 722 [targetStimulus, errormsg]= ...
rmeddis@0 723 stimulusCreate(globalStimParams, stimComponents, 0);
rmeddis@0 724
rmeddis@0 725 if ~isempty(errormsg) % e.g. limits exceeded
rmeddis@0 726 errormsg
rmeddis@0 727 return
rmeddis@0 728 end
rmeddis@0 729
rmeddis@0 730 switch experiment.ear
rmeddis@0 731 case {'MAPmodel' , 'MAPmodelMultiCh', 'MAPmodelSingleCh', 'MAPmodelListen'}
rmeddis@0 732 % model requires no calibration correction;
rmeddis@0 733 % signal is already in Pascals
rmeddis@0 734 globalStimParams.audioOutCorrection=1;
rmeddis@0 735 % use only the targetStimulus for the MAP model
rmeddis@0 736 audio=targetStimulus;
rmeddis@0 737
rmeddis@0 738 otherwise % left, right diotic dichotic
rmeddis@0 739 if stimulusParameters.includeCue
rmeddis@0 740 audio= [cueStimulus; targetStimulus];
rmeddis@0 741 else % no cue
rmeddis@0 742 audio=targetStimulus;
rmeddis@0 743 end
rmeddis@0 744 end
rmeddis@0 745
rmeddis@0 746 % playtime
rmeddis@0 747 % order of the cue and test stimuli varies for 2AFC
rmeddis@0 748 switch experiment.threshEstMethod
rmeddis@0 749 case {'2I2AFC++', '2I2AFC+++'}
rmeddis@0 750 % intervening silence (currently none; masking delay serves this purpose)
rmeddis@0 751 IAFCinterveningSilence=zeros(round(AFCsilenceDuration/dt),2);
rmeddis@0 752 if rand>0.5 % put test stimulus first
rmeddis@0 753 stimulusParameters.testTargetBegins=targetDelay ;
rmeddis@0 754 stimulusParameters.testTargetEnds= ...
rmeddis@0 755 targetDelay+targetDuration;
rmeddis@0 756 stimulusParameters.testNonTargetBegins=...
rmeddis@0 757 length(cueStimulus)*dt ...
rmeddis@0 758 + AFCsilenceDuration +targetDelay ;
rmeddis@0 759 stimulusParameters.testNonTargetEnds=...
rmeddis@0 760 length(cueStimulus)*dt ...
rmeddis@0 761 + AFCsilenceDuration+targetDelay+targetDuration;
rmeddis@0 762
rmeddis@0 763 set(handles.pushbutton1,'backgroundcolor','r'), drawnow
rmeddis@0 764 y=audioplayer(targetStimulus, globalStimParams.FS, 24);
rmeddis@0 765 playblocking(y)
rmeddis@0 766 set(handles.pushbutton1,'backgroundcolor',...
rmeddis@0 767 get(0,'defaultUicontrolBackgroundColor')), drawnow
rmeddis@0 768 y=audioplayer(IAFCinterveningSilence, ...
rmeddis@0 769 globalStimParams.FS, 24);
rmeddis@0 770 playblocking(y)
rmeddis@0 771 set(handles.pushbutton2,'backgroundcolor','r'), drawnow
rmeddis@0 772 y=audioplayer(cueStimulus, globalStimParams.FS, 24);
rmeddis@0 773 playblocking(y)
rmeddis@0 774 set(handles.pushbutton2,'backgroundcolor',...
rmeddis@0 775 get(0,'defaultUicontrolBackgroundColor')), drawnow
rmeddis@0 776 withinRuns.stimulusOrder='targetFirst';
rmeddis@0 777 audio= [targetStimulus; IAFCinterveningSilence; ...
rmeddis@0 778 cueStimulus]; % for plotting purposes later
rmeddis@0 779
rmeddis@0 780 else % put test stimulus second
rmeddis@0 781 stimulusParameters.testTargetBegins=...
rmeddis@0 782 length(cueStimulus)*dt ...
rmeddis@0 783 + AFCsilenceDuration +targetDelay ;
rmeddis@0 784 stimulusParameters.testTargetEnds=...
rmeddis@0 785 length(cueStimulus)*dt ...
rmeddis@0 786 + AFCsilenceDuration+targetDelay+targetDuration;
rmeddis@0 787 stimulusParameters.testNonTargetBegins=targetDelay ;
rmeddis@0 788 stimulusParameters.testNonTargetEnds=...
rmeddis@0 789 targetDelay+targetDuration;
rmeddis@0 790
rmeddis@0 791 set(handles.pushbutton1,'backgroundcolor','r'),drawnow
rmeddis@0 792 y=audioplayer(cueStimulus, globalStimParams.FS, 24);
rmeddis@0 793 playblocking(y)
rmeddis@0 794 set(handles.pushbutton1,'backgroundcolor',...
rmeddis@0 795 get(0,'defaultUicontrolBackgroundColor')), drawnow
rmeddis@0 796 y=audioplayer(IAFCinterveningSilence, ...
rmeddis@0 797 globalStimParams.FS, 24);
rmeddis@0 798 playblocking(y)
rmeddis@0 799 set(handles.pushbutton2,'backgroundcolor','r'), drawnow
rmeddis@0 800 y=audioplayer(targetStimulus, globalStimParams.FS, 24);
rmeddis@0 801 playblocking(y)
rmeddis@0 802 set(handles.pushbutton2,'backgroundcolor',...
rmeddis@0 803 get(0,'defaultUicontrolBackgroundColor')), drawnow
rmeddis@0 804 withinRuns.stimulusOrder='targetSecond';
rmeddis@0 805 audio= [cueStimulus; IAFCinterveningSilence; ...
rmeddis@0 806 targetStimulus]; % for plotting purposes later
rmeddis@0 807 end
rmeddis@0 808 otherwise % singleInterval
rmeddis@0 809 if strcmp(experiment.ear,'MAPmodel') ...
rmeddis@0 810 || strcmp(experiment.ear,'MAPmodelMultiCh') ...
rmeddis@0 811 || strcmp(experiment.ear,'MAPmodelSingleCh') ...
rmeddis@0 812 ||strcmp(experiment.ear,'MAPmodelListen')
rmeddis@0 813 % don't play for MAPmodel
rmeddis@0 814 switch experiment.ear
rmeddis@0 815 % except on special request
rmeddis@0 816 case {'MAPmodelListen'}
rmeddis@0 817 y=audioplayer(audio, globalStimParams.FS, 24);
rmeddis@0 818 playblocking(y) % suspends operations until completed
rmeddis@0 819 end
rmeddis@0 820 else
rmeddis@0 821 y=audioplayer(audio, globalStimParams.FS, 24);
rmeddis@0 822 playblocking(y)
rmeddis@0 823 end % if experiment.ear
rmeddis@0 824 end % switch experiment.threshEstMethod
rmeddis@0 825 end % switch experiment.ear
rmeddis@0 826
rmeddis@0 827
rmeddis@0 828 % switch experiment.ear
rmeddis@0 829 % case {'MAPmodel', 'MAPmodelListen', 'MAPmodelMultiCh','MAPmodelSingleCh'}
rmeddis@0 830 % % save audio for later reference or for input to MAP model
rmeddis@0 831 % wavwrite(audio/max(audio), globalStimParams.FS,32,'stimulus')
rmeddis@0 832 % end
rmeddis@0 833
rmeddis@0 834 % Panel 1
rmeddis@0 835 % graphical presentation of the stimulus
rmeddis@0 836 % NB shown *after* the stimulus has been presented
rmeddis@0 837 axes(expGUIhandles.axes1), cla
rmeddis@0 838 % plot is HW rectified and plotted as dB re 28e-6
rmeddis@0 839 % calibration is ignored
rmeddis@0 840 t=dt:dt:dt*length(audio);
rmeddis@0 841 plot(t,stimulusParameters.calibrationdB+20*log10((abs(audio)+1e-10)/28e-6))
rmeddis@0 842 % set(gca,'xtick',[])
rmeddis@0 843 ylim([-20 100])
rmeddis@0 844 ylabel('stimulus (dB SPL)')
rmeddis@0 845 xlim([0 t(end)])
rmeddis@0 846 grid on
rmeddis@0 847 header=[betweenRuns.variableName1 ': ' ...
rmeddis@0 848 num2str(betweenRuns.var1Sequence(betweenRuns.runNumber))];
rmeddis@0 849 header=[header ' ' num2str(...
rmeddis@0 850 betweenRuns.var2Sequence(betweenRuns.runNumber)) ':' ...
rmeddis@0 851 betweenRuns.variableName2 ];
rmeddis@0 852 title(header)
rmeddis@0 853