annotate Copy_of_multithreshold 1.46/nextStimulus.m @ 28:02aa9826efe0

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