rmeddis@0: function errormsg=nextStimulus(handles) rmeddis@0: % Handles everything concerned with the stimulus presentation rmeddis@0: % called from startNewRun in subjGUI rmeddis@0: rmeddis@38: global experiment stimulusParameters withinRuns betweenRuns rmeddis@0: experiment.status='presentingStimulus'; rmeddis@0: errormsg=''; rmeddis@0: rmeddis@0: % interrupt by 'stop' button rmeddis@29: % if experiment.stop rmeddis@29: % disp('******** experiment manually stopped *****************') rmeddis@29: % experiment.status= 'waitingForStart'; rmeddis@29: % errormsg='manually stopped'; rmeddis@29: % addToMsg(errormsg,1) rmeddis@29: % return rmeddis@29: % end rmeddis@0: rmeddis@0: % -----------------------------------------choose catch trials at random rmeddis@0: % catch trials are for subject threshold measurements only rmeddis@0: % this is the only place where withinRuns.catchTrial is set rmeddis@0: if experiment.allowCatchTrials rmeddis@0: if withinRuns.trialNumber==1; rmeddis@0: % first trial is never a catch trial rmeddis@0: withinRuns.catchTrial=0; rmeddis@0: withinRuns.catchTrialCount=0; % reset count on first trial rmeddis@0: elseif withinRuns.trialNumber==2 ... rmeddis@0: && withinRuns.catchTrialCount==0 rmeddis@0: % second trial is always a catch trial rmeddis@0: withinRuns.catchTrial=1; rmeddis@0: withinRuns.catchTrialCount=1; % this must be the first rmeddis@0: elseif withinRuns.thisIsRepeatTrial rmeddis@0: % for requested repeats do not change catch trial status rmeddis@0: withinRuns.thisIsRepeatTrial=0; % reset toggle rmeddis@0: else rmeddis@0: % choose whether or not to have a catch trial rmeddis@0: R=rand; rmeddis@0: if R1 rmeddis@35: switch experiment.paradigm rmeddis@35: case {'trainingIFMC', 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms','IFMC_16ms'} rmeddis@35: idx=floor(thisRunNumber/length(betweenRuns.variableList1)-0.01)+1; rmeddis@35: cmd=(['stimulusParameters.targetLevel = ' ... rmeddis@35: num2str(stimulusParameters.targetLevels(idx)) ';']); rmeddis@35: eval(cmd); rmeddis@35: if withinRuns.trialNumber==1 rmeddis@35: disp(['targetLevel=' num2str(stimulusParameters.targetLevel)]) rmeddis@35: end rmeddis@35: end rmeddis@0: end rmeddis@0: rmeddis@0: rmeddis@0: % for more readable code use shorter variable names; rmeddis@0: % NB these may change below; these are only the starting values rmeddis@0: rmeddis@0: targetType= stimulusParameters.targetType; rmeddis@0: targetDuration= stimulusParameters.targetDuration; rmeddis@0: targetLevel= stimulusParameters.targetLevel; rmeddis@0: targetFrequency= stimulusParameters.targetFrequency; rmeddis@0: rmeddis@0: maskerType= stimulusParameters.maskerType; rmeddis@0: maskerDuration= stimulusParameters.maskerDuration; rmeddis@0: maskerLevel= stimulusParameters.maskerLevel; rmeddis@0: maskerRelativeFrequency= stimulusParameters.maskerRelativeFrequency; rmeddis@0: maskerFrequency= maskerRelativeFrequency*targetFrequency; rmeddis@0: rmeddis@0: gapDuration= stimulusParameters.gapDuration; rmeddis@0: rmeddis@0: rampDuration= stimulusParameters.rampDuration; rmeddis@0: AFCsilenceDuration=stimulusParameters.AFCsilenceDuration; % 2I2AFC gap rmeddis@0: backgroundLevel= stimulusParameters.backgroundLevel; rmeddis@0: rmeddis@0: % Set level of within runs variable rmeddis@0: % this is the first change to one of the values shown above rmeddis@0: cmd=[stimulusParameters.WRVname '= withinRuns.variableValue;' ]; rmeddis@0: % e.g.: maskerLevel= withinRuns.variableValue; rmeddis@0: eval(cmd); rmeddis@0: rmeddis@0: % cue and test stimuli are identical except for a single difference rmeddis@0: % depending on the paradigm rmeddis@0: cueTestDifference= stimulusParameters.cueTestDifference; rmeddis@0: % cue characteristics before adding cue differences rmeddis@0: cueTargetLevel=targetLevel; rmeddis@0: cueMaskerFrequency=maskerFrequency; rmeddis@0: cueMaskerDuration=maskerDuration; rmeddis@0: cueMaskerLevel=maskerLevel; rmeddis@0: cueTargetFrequency=targetFrequency; rmeddis@0: cueGapDuration=gapDuration; rmeddis@0: rmeddis@0: % ----------------------------paradigm sensitive cue and masker settings rmeddis@0: % switch off unwanted components and base cue on target values rmeddis@0: % for catch trials switch off the target rmeddis@0: rmeddis@0: % --- set cueTarget level according to assessment method rmeddis@0: % cue-test difference applies only with singleInterval rmeddis@0: switch experiment.threshEstMethod rmeddis@0: case {'2I2AFC++', '2I2AFC+++'} rmeddis@0: % For 2IFC the cue stimulus (masker + probe) is the 'no' window rmeddis@0: % and the target stimulus (masker+probe) is the 'yes' window rmeddis@0: % the order of presentation is decided at the last minute. rmeddis@0: cueTargetLevel=-100; % the target is never in the 'no' window rmeddis@0: cueMaskerLevel=maskerLevel; % masker level is the same in both rmeddis@0: otherwise rmeddis@0: % 'single interval' or max likelihood rmeddis@0: switch experiment.paradigm rmeddis@0: % cue target is more audible rmeddis@0: case {'training','absThreshold', 'absThreshold_8', ... rmeddis@0: 'TENtest', 'threshold_duration','discomfort',... rmeddis@0: 'overShoot','overShootB','overShootMB1', ... rmeddis@38: 'overShootMB2', 'OHIO','OHIOabs','OHIOspect'... rmeddis@38: 'OHIOrand', 'OHIOtemp', 'OHIOspectemp'} rmeddis@0: cueTargetLevel=targetLevel+cueTestDifference; rmeddis@0: rmeddis@0: case {'forwardMasking','forwardMaskingD','trainingIFMC', ... rmeddis@38: 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms', ... rmeddis@38: 'FMreProbe'} rmeddis@0: % cue masker is weaker to make target more audible rmeddis@0: cueMaskerLevel=maskerLevel-cueTestDifference; rmeddis@0: end rmeddis@0: end rmeddis@0: rmeddis@38: % thresholds (in dB SPL) of the single tone with 12 frequencies: rmeddis@38: % 1 2 3 4 5 6 7 8 9 10 11 12 rmeddis@38: % 494, 663, 870, 1125, 1442, 1838, 2338, 2957, 3725, 4689, 5866, 7334 rmeddis@38: rmeddis@38: % 2. ‘OHIOtemp’ is for measuring thresholds for temporally integrated rmeddis@38: % combinations of 2, 4, 8, and 12 tones presented simultaneously. rmeddis@38: % In our experiment, we used 4680Hz frequency. rmeddis@38: rmeddis@38: % 3. ‘OHIOspec’ is for measuring thresholds for spectrally integrated rmeddis@38: % combinations of 2(7335 and 5866Hz), 4(7334, 5866, 4680, and 3725Hz), rmeddis@38: % 8(7334, 5866, 4680, 3725, 2957, 2338, 1838, and rmeddis@38: % 1442Hz), and rmeddis@38: % 12(all 12 frequencies) tones presented simultaneously. rmeddis@38: rmeddis@38: % 4. ‘OHIOspectemp’ is for measuring thresholds for patterned signals rmeddis@38: % differing in both the spectral and temporal domains. rmeddis@38: % The frequency conditions are the same as that of ‘OHIOspec’. rmeddis@38: rmeddis@38: % 5. ‘OHIOrand’ is for measuring thresholds for spectrotemporally varying rmeddis@38: % signals with random frequency presentation. rmeddis@38: rmeddis@38: switch experiment.paradigm(1:3) rmeddis@38: case 'OHI' rmeddis@38: targetType='OHIO'; rmeddis@38: OHIOtype=experiment.paradigm; rmeddis@38: % 1. ‘OHIOabs’ paradigm is a baseline procedure for measuring absolute rmeddis@38: rmeddis@38: nTones=betweenRuns.var1Sequence(betweenRuns.runNumber); rmeddis@38: allFreqs=[494, 663, 870, 1125, 1442, 1838, 2338, 2957, 3725, 4689, 5866, 7334]; rmeddis@38: toneLevelBoost= ... rmeddis@38: [1 0 0 1 1 4 8 12 12 14 17 19 ]; rmeddis@38: rmeddis@38: rmeddis@38: % for nTones=nTonesList rmeddis@38: switch experiment.paradigm rmeddis@38: % case ' OHIOabs' rmeddis@38: % % one tone frequency at a time rmeddis@38: % stim.frequencies=allFreqs(1); rmeddis@38: % stim.amplitudesdB=0; rmeddis@38: rmeddis@38: case 'OHIOrand' rmeddis@38: % chose nTones frequencies at random rmeddis@38: x=rand(1,12); rmeddis@38: [sorted idx]=sort(x); rmeddis@38: cueTargetFrequency=allFreqs(idx(1:nTones)); rmeddis@38: cueTargetLevel=toneLevelBoost(idx)+... rmeddis@38: targetLevel + cueTestDifference; rmeddis@38: targetFrequency=allFreqs(idx(1:nTones)); rmeddis@38: targetLevel=targetLevel + toneLevelBoost(idx); rmeddis@38: rmeddis@38: case 'OHIOtemp' rmeddis@38: % 4680 Hz repeated nTones times rmeddis@38: cueTargetFrequency=4680*ones(1,nTones); rmeddis@38: cueTargetLevel=repmat(toneLevelBoost(10),1,nTones)+... rmeddis@38: targetLevel + cueTestDifference; rmeddis@38: targetFrequency=4680*ones(1,nTones); rmeddis@38: targetLevel= targetLevel+repmat(toneLevelBoost(10),1,nTones); rmeddis@38: rmeddis@38: case {'OHIOspect', 'OHIOspectemp'} rmeddis@38: % nTones frequencies either simulataneously or sequentially rmeddis@38: switch nTones rmeddis@38: case 2 rmeddis@38: cueTargetFrequency=[7335 5866]; rmeddis@38: targetFrequency=[7335 5866]; rmeddis@38: idx=[12 11]; rmeddis@38: cueTargetLevel=targetLevel + toneLevelBoost(idx)+cueTestDifference; rmeddis@38: targetLevel=targetLevel + toneLevelBoost(idx); rmeddis@38: case 4 rmeddis@38: cueTargetFrequency=[7334, 5866, 4680, 3725]; rmeddis@38: targetFrequency=[7334, 5866, 4680, 3725]; rmeddis@38: idx=[12:-1:9 ]; rmeddis@38: cueTargetLevel=targetLevel + toneLevelBoost(idx)+cueTestDifference; rmeddis@38: targetLevel=targetLevel + toneLevelBoost(idx); rmeddis@38: case 8 rmeddis@38: cueTargetFrequency=... rmeddis@38: [7334, 5866, 4680, 3725, 2957, 2338, 1838, 1442]; rmeddis@38: targetFrequency=... rmeddis@38: [7334, 5866, 4680, 3725, 2957, 2338, 1838, 1442]; rmeddis@38: idx=[12:-1:5 ]; rmeddis@38: cueTargetLevel=targetLevel + toneLevelBoost(idx)+cueTestDifference; rmeddis@38: targetLevel=targetLevel + toneLevelBoost(idx); rmeddis@38: case 12 rmeddis@38: cueTargetFrequency=allFreqs; rmeddis@38: targetFrequency=allFreqs; rmeddis@38: cueTargetLevel=targetLevel + toneLevelBoost(1:12)+cueTestDifference; rmeddis@38: targetLevel=targetLevel + toneLevelBoost(1:12); rmeddis@38: end rmeddis@38: end rmeddis@38: rmeddis@38: otherwise rmeddis@38: OHIOtype='none'; rmeddis@38: end rmeddis@38: rmeddis@38: switch experiment.paradigm(1:3) rmeddis@38: case 'OHI' rmeddis@38: rmeddis@38: switch experiment.threshEstMethod rmeddis@38: case {'2I2AFC++', '2I2AFC+++'} rmeddis@38: % the cue stimulus (masker + probe) is the 'no' window rmeddis@38: % the target stimulus (masker+probe) is the 'yes' window rmeddis@38: % the order of presentation is decided at the last minute. rmeddis@38: cueTargetLevel=-100; rmeddis@38: end rmeddis@38: rmeddis@38: rmeddis@38: switch experiment.paradigm rmeddis@38: case {'OHIOabs', 'OHIOspect'} rmeddis@38: OHIOtoneDuration=.02+stimulusParameters.stimulusDelay; rmeddis@38: globalStimParams.overallDuration=OHIOtoneDuration; rmeddis@38: otherwise rmeddis@38: OHIOtoneDuration=nTones*0.02+stimulusParameters.stimulusDelay; rmeddis@38: globalStimParams.overallDuration=OHIOtoneDuration; rmeddis@38: end rmeddis@38: end rmeddis@38: rmeddis@0: % ----------------------------- catch trial rmeddis@0: if withinRuns.catchTrial rmeddis@0: targetLevel=-100; % no target rmeddis@0: end rmeddis@0: rmeddis@17: % ----------------------------- calibration of sound output rmeddis@35: % seperate calibration for each frequency to match headphones rmeddis@17: calibrationCorrectiondB=stimulusParameters.calibrationdB; rmeddis@17: if calibrationCorrectiondB<-50 rmeddis@17: if maskerFrequency==targetFrequency rmeddis@17: load 'calibrationFile' % calibrationFrequency calibrationAttenutation rmeddis@17: idx=find(calibrationFrequency==targetFrequency); rmeddis@17: if isempty(idx) rmeddis@35: error('Calibration by file; frequency not found') rmeddis@17: else rmeddis@17: calibrationCorrectiondB=calibrationAttenutation(idx) rmeddis@17: end rmeddis@17: else rmeddis@17: error('calibration by file requested but masker frequency is not the same as target') rmeddis@17: end rmeddis@17: end rmeddis@17: rmeddis@17: rmeddis@0: % -------------------------------------- Checks on excessive signal level rmeddis@0: rmeddis@0: % clipping is relevant only for soundcard use (not modelling) rmeddis@0: switch experiment.ear rmeddis@0: case {'left', 'right', 'diotic',... rmeddis@0: 'dichotic', 'dioticLeft', 'dichoticRight'} rmeddis@0: experiment.headphonesUsed=1; rmeddis@0: otherwise rmeddis@0: experiment.headphonesUsed=0; rmeddis@0: end rmeddis@0: rmeddis@0: % NB calibration *reduces* the level of the soundCard output rmeddis@0: switch experiment.ear rmeddis@0: case {'left', 'right', 'diotic',... rmeddis@0: 'dichotic', 'dioticLeft', 'dichoticRight'} rmeddis@17: clippingLevel=91+calibrationCorrectiondB; rmeddis@0: soundCardMinimum=clippingLevel-20*log10(2^24); rmeddis@0: otherwise rmeddis@0: clippingLevel=inf; rmeddis@0: soundCardMinimum=-inf; rmeddis@0: end rmeddis@0: rmeddis@0: % Check for extreme WRV values and abort if necessary rmeddis@0: % WRVname specifies the value that changes from trial to trial rmeddis@0: withinRuns.forceThreshold=[]; rmeddis@0: switch stimulusParameters.WRVname rmeddis@0: % check for extreme values. Note that one of the tones might be switched off rmeddis@0: case 'maskerLevel' rmeddis@0: upperLevel=stimulusParameters.WRVlimits(2); rmeddis@0: lowerLevel=stimulusParameters.WRVlimits(1); rmeddis@0: if max(maskerLevel, cueMaskerLevel)> upperLevel rmeddis@0: errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ... rmeddis@0: ') is too high ***']; rmeddis@0: withinRuns.forceThreshold=upperLevel; rmeddis@0: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@0: if max(maskerLevel, cueMaskerLevel)< lowerLevel rmeddis@0: errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ... rmeddis@0: ') is too low ***']; rmeddis@0: withinRuns.forceThreshold=lowerLevel; rmeddis@0: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@0: rmeddis@0: if max(maskerLevel, cueMaskerLevel)> clippingLevel rmeddis@0: errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ... rmeddis@0: ') is clipping ***']; rmeddis@0: withinRuns.forceThreshold=clippingLevel; rmeddis@0: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@17: rmeddis@0: case 'targetLevel' rmeddis@0: upperLevel=stimulusParameters.WRVlimits(2); rmeddis@0: lowerLevel=stimulusParameters.WRVlimits(1); rmeddis@0: if ~withinRuns.catchTrial rmeddis@0: if max(targetLevel, cueTargetLevel)> upperLevel rmeddis@0: errormsg=['target level (' ... rmeddis@0: num2str(max(targetLevel, cueTargetLevel)) ... rmeddis@0: ') is too high ***']; rmeddis@0: withinRuns.forceThreshold=upperLevel; rmeddis@17: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@0: if max(targetLevel, cueTargetLevel)< lowerLevel rmeddis@0: errormsg=['target level (' ... rmeddis@0: num2str(max(targetLevel, cueTargetLevel)) ... rmeddis@0: ') is too low ***']; rmeddis@0: withinRuns.forceThreshold=lowerLevel; rmeddis@17: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@0: if max(targetLevel, cueTargetLevel)> clippingLevel rmeddis@0: errormsg=['target level (' ... rmeddis@0: num2str(max(targetLevel, cueTargetLevel)) ... rmeddis@0: ') is clipping ***']; rmeddis@0: withinRuns.forceThreshold=upperLevel; rmeddis@17: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@17: end rmeddis@0: case 'maskerDuration' rmeddis@0: % this is odd! but harmless rmeddis@0: if max(maskerDuration, cueMaskerDuration)> ... rmeddis@0: stimulusParameters.WRVlimits(2) rmeddis@0: errormsg=['maskerDuration (' ... rmeddis@0: num2str(max(maskerDuration, cueMaskerDuration))... rmeddis@0: ') is too long ***']; rmeddis@0: withinRuns.forceThreshold=stimulusParameters.WRVlimits(2); rmeddis@0: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@0: rmeddis@0: if min(maskerDuration, cueMaskerDuration)... rmeddis@0: < stimulusParameters.WRVlimits(1) rmeddis@0: errormsg=['maskerDuration (' num2str(maskerLevel) ... rmeddis@0: ') too short ***']; rmeddis@0: withinRuns.forceThreshold=stimulusParameters.WRVlimits(1); rmeddis@0: withinRuns.forceThreshold=NaN; rmeddis@0: return rmeddis@0: end rmeddis@0: rmeddis@38: case 'gapDuration' rmeddis@0: % legacy programming rmeddis@0: if gapDuration<0 rmeddis@0: errormsg=['gapDuration (' num2str(gapDuration) ... rmeddis@0: ') is less than zero ***']; rmeddis@0: return rmeddis@0: end rmeddis@0: rmeddis@0: case 'maskerFrequency' rmeddis@0: switch experiment.paradigm rmeddis@0: case 'bandwidth' rmeddis@0: frequency=maskerFrequency'; rmeddis@0: if stimulusParameters.WRVstep<0 rmeddis@0: lowerLevel=stimulusParameters.targetFrequency; rmeddis@0: upperLevel=stimulusParameters.targetFrequency*2; rmeddis@0: else rmeddis@0: lowerLevel=stimulusParameters.targetFrequency/3; rmeddis@0: upperLevel=stimulusParameters.targetFrequency; rmeddis@0: end rmeddis@0: rmeddis@0: if frequency(1)>upperLevel || frequency(1)stimulusParameters.WRVlimits(2) rmeddis@0: errormsg=['masker frequency (' ... rmeddis@0: num2str(frequencyDifference) ... rmeddis@0: ') is outside WRV limits ***']; rmeddis@0: withinRuns.forceThreshold=stimulusParameters.WRVlimits(2) ; rmeddis@0: return rmeddis@0: end rmeddis@0: rmeddis@0: end rmeddis@0: rmeddis@0: % --------------------------------Ear ---------------------------------- rmeddis@0: globalStimParams.ears='specified'; rmeddis@0: % ear: 1=left, 2=right rmeddis@0: switch experiment.ear rmeddis@0: case 'left' rmeddis@0: maskerEar=1; rmeddis@0: targetEar=1; rmeddis@0: case 'right' rmeddis@0: maskerEar=2; rmeddis@0: targetEar=2; rmeddis@0: case 'dichoticLeft' rmeddis@0: maskerEar=2; rmeddis@0: targetEar=1; rmeddis@0: case 'dichoticRight' rmeddis@0: maskerEar=1; rmeddis@0: targetEar=2; rmeddis@0: case 'diotic' rmeddis@0: maskerEar=1; rmeddis@0: targetEar=1; rmeddis@0: globalStimParams.ears='diotic'; rmeddis@0: case {'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh', 'MAPmodelListen',... rmeddis@0: 'statsModelLogistic', 'statsModelRareEvent'} rmeddis@0: maskerEar=1; rmeddis@0: targetEar=1; rmeddis@0: end rmeddis@0: rmeddis@0: backgroundType=stimulusParameters.backgroundType; rmeddis@0: switch stimulusParameters.backgroundType rmeddis@0: case {'noiseDich', 'pinkNoiseDich'} rmeddis@17: % case 'Dich' rmeddis@0: % dich means put the background in the ear opposite to the target rmeddis@0: backgroundType=backgroundType(1:end-4); rmeddis@0: switch targetEar rmeddis@0: case 1 rmeddis@0: backgroundEar=2; rmeddis@0: case 2 rmeddis@0: backgroundEar=1; rmeddis@0: end rmeddis@0: otherwise rmeddis@17: % case {'none','noise', 'pinkNoise', 'TEN','babble'} rmeddis@0: backgroundEar=targetEar; rmeddis@0: end rmeddis@0: rmeddis@0: % ------------------------------- Make Stimulus ------------------- rmeddis@0: % single interval up/down plays cue then target stimulus rmeddis@0: % 2IFC uses cue stimulus as interval with no target rmeddis@0: globalStimParams.FS=stimulusParameters.sampleRate; rmeddis@0: dt=1/stimulusParameters.sampleRate; rmeddis@0: globalStimParams.dt=dt; rmeddis@0: stimulusParameters.dt=dt; % for use later rmeddis@0: rmeddis@17: rmeddis@17: rmeddis@17: globalStimParams.audioOutCorrection=10^(calibrationCorrectiondB/20); rmeddis@0: % the output will be reduced by this amount in stimulusCreate rmeddis@0: % i.e. audio=audio/globalStimParams.audioOutCorrection rmeddis@0: % A 91 dB level will yield a peak amp of 1 for calibration=0 rmeddis@0: % A 91 dB level will yield a peak amp of 0.4467 for calibration=7 rmeddis@0: % A 98 dB level will yield a peak amp of 1 for calibration=7 rmeddis@0: rmeddis@0: precedingSilence=stimulusParameters.stimulusDelay; rmeddis@0: % all stimuli have 20 ms terminal silence. rmeddis@0: % this is clearance for modelling late-ringing targets rmeddis@0: terminalSilence=.03; rmeddis@0: rmeddis@0: % Now compute overall duration of the stimulus rmeddis@0: % note that all endsilence values are set to -1 rmeddis@0: % so that they will fill with terminal silence as required to make rmeddis@0: % components equal in length rmeddis@0: % We need to find the longest possible duration rmeddis@0: duration(1)=precedingSilence+maskerDuration+cueGapDuration... rmeddis@0: +targetDuration+terminalSilence; rmeddis@0: duration(2)=precedingSilence+maskerDuration+gapDuration... rmeddis@0: +targetDuration+ terminalSilence; rmeddis@0: % If the gap is negative we need to ignore it when estimating total length rmeddis@0: duration(3)=precedingSilence+maskerDuration+ terminalSilence; rmeddis@0: globalStimParams.overallDuration=max(duration); rmeddis@0: globalStimParams.nSignalPoints=... rmeddis@30: round(globalStimParams.overallDuration*globalStimParams.FS); rmeddis@0: rmeddis@38: % special case rmeddis@38: switch experiment.paradigm(1:3) rmeddis@38: case 'OHI' rmeddis@38: switch experiment.paradigm rmeddis@38: case {'OHIOabs', 'OHIOspect'} rmeddis@38: OHIOtoneDuration=.02+stimulusParameters.stimulusDelay; rmeddis@38: globalStimParams.overallDuration=OHIOtoneDuration; rmeddis@38: otherwise rmeddis@38: OHIOtoneDuration=nTones*0.02+stimulusParameters.stimulusDelay; rmeddis@38: globalStimParams.overallDuration=OHIOtoneDuration; rmeddis@38: end rmeddis@38: end rmeddis@38: rmeddis@38: rmeddis@0: % ----------------------------------------------cue stimulus rmeddis@0: % cue masker rmeddis@0: componentNo=1; rmeddis@0: precedingSilence=stimulusParameters.stimulusDelay; rmeddis@0: stimComponents(maskerEar,componentNo).type=maskerType; rmeddis@0: stimComponents(maskerEar,componentNo).toneDuration=cueMaskerDuration; rmeddis@0: stimComponents(maskerEar,componentNo).frequencies=cueMaskerFrequency; rmeddis@0: stimComponents(maskerEar,componentNo).amplitudesdB=cueMaskerLevel; rmeddis@0: stimComponents(maskerEar,componentNo).beginSilence=precedingSilence; rmeddis@0: stimComponents(maskerEar,componentNo).endSilence=-1; rmeddis@0: stimComponents(maskerEar,componentNo).AMfrequency=0; rmeddis@0: stimComponents(maskerEar,componentNo).AMdepth=0; rmeddis@0: if rampDuration0.5 % put test stimulus first rmeddis@0: stimulusParameters.testTargetBegins=targetDelay ; rmeddis@0: stimulusParameters.testTargetEnds= ... rmeddis@0: targetDelay+targetDuration; rmeddis@0: stimulusParameters.testNonTargetBegins=... rmeddis@0: length(cueStimulus)*dt ... rmeddis@0: + AFCsilenceDuration +targetDelay ; rmeddis@0: stimulusParameters.testNonTargetEnds=... rmeddis@0: length(cueStimulus)*dt ... rmeddis@0: + AFCsilenceDuration+targetDelay+targetDuration; rmeddis@0: rmeddis@0: set(handles.pushbutton1,'backgroundcolor','r'), drawnow rmeddis@0: y=audioplayer(targetStimulus, globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: set(handles.pushbutton1,'backgroundcolor',... rmeddis@0: get(0,'defaultUicontrolBackgroundColor')), drawnow rmeddis@0: y=audioplayer(IAFCinterveningSilence, ... rmeddis@0: globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: set(handles.pushbutton2,'backgroundcolor','r'), drawnow rmeddis@0: y=audioplayer(cueStimulus, globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: set(handles.pushbutton2,'backgroundcolor',... rmeddis@0: get(0,'defaultUicontrolBackgroundColor')), drawnow rmeddis@0: withinRuns.stimulusOrder='targetFirst'; rmeddis@0: audio= [targetStimulus; IAFCinterveningSilence; ... rmeddis@0: cueStimulus]; % for plotting purposes later rmeddis@0: rmeddis@0: else % put test stimulus second rmeddis@0: stimulusParameters.testTargetBegins=... rmeddis@0: length(cueStimulus)*dt ... rmeddis@0: + AFCsilenceDuration +targetDelay ; rmeddis@0: stimulusParameters.testTargetEnds=... rmeddis@0: length(cueStimulus)*dt ... rmeddis@0: + AFCsilenceDuration+targetDelay+targetDuration; rmeddis@0: stimulusParameters.testNonTargetBegins=targetDelay ; rmeddis@0: stimulusParameters.testNonTargetEnds=... rmeddis@0: targetDelay+targetDuration; rmeddis@0: rmeddis@0: set(handles.pushbutton1,'backgroundcolor','r'),drawnow rmeddis@0: y=audioplayer(cueStimulus, globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: set(handles.pushbutton1,'backgroundcolor',... rmeddis@0: get(0,'defaultUicontrolBackgroundColor')), drawnow rmeddis@0: y=audioplayer(IAFCinterveningSilence, ... rmeddis@0: globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: set(handles.pushbutton2,'backgroundcolor','r'), drawnow rmeddis@0: y=audioplayer(targetStimulus, globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: set(handles.pushbutton2,'backgroundcolor',... rmeddis@0: get(0,'defaultUicontrolBackgroundColor')), drawnow rmeddis@0: withinRuns.stimulusOrder='targetSecond'; rmeddis@0: audio= [cueStimulus; IAFCinterveningSilence; ... rmeddis@0: targetStimulus]; % for plotting purposes later rmeddis@0: end rmeddis@0: otherwise % singleInterval rmeddis@0: if strcmp(experiment.ear,'MAPmodel') ... rmeddis@0: || strcmp(experiment.ear,'MAPmodelMultiCh') ... rmeddis@0: || strcmp(experiment.ear,'MAPmodelSingleCh') ... rmeddis@0: ||strcmp(experiment.ear,'MAPmodelListen') rmeddis@0: % don't play for MAPmodel rmeddis@0: switch experiment.ear rmeddis@0: % except on special request rmeddis@0: case {'MAPmodelListen'} rmeddis@0: y=audioplayer(audio, globalStimParams.FS, 24); rmeddis@0: playblocking(y) % suspends operations until completed rmeddis@0: end rmeddis@0: else rmeddis@0: y=audioplayer(audio, globalStimParams.FS, 24); rmeddis@0: playblocking(y) rmeddis@0: end % if experiment.ear rmeddis@0: end % switch experiment.threshEstMethod rmeddis@0: end % switch experiment.ear rmeddis@0: rmeddis@0: rmeddis@0: % switch experiment.ear rmeddis@0: % case {'MAPmodel', 'MAPmodelListen', 'MAPmodelMultiCh','MAPmodelSingleCh'} rmeddis@0: % % save audio for later reference or for input to MAP model rmeddis@0: % wavwrite(audio/max(audio), globalStimParams.FS,32,'stimulus') rmeddis@0: % end rmeddis@0: rmeddis@0: % Panel 1 rmeddis@0: % graphical presentation of the stimulus rmeddis@0: % NB shown *after* the stimulus has been presented rmeddis@0: axes(expGUIhandles.axes1), cla rmeddis@0: % plot is HW rectified and plotted as dB re 28e-6 rmeddis@0: % calibration is ignored rmeddis@0: t=dt:dt:dt*length(audio); rmeddis@0: plot(t,stimulusParameters.calibrationdB+20*log10((abs(audio)+1e-10)/28e-6)) rmeddis@0: % set(gca,'xtick',[]) rmeddis@0: ylim([-20 100]) rmeddis@0: ylabel('stimulus (dB SPL)') rmeddis@0: xlim([0 t(end)]) rmeddis@0: grid on rmeddis@0: header=[betweenRuns.variableName1 ': ' ... rmeddis@0: num2str(betweenRuns.var1Sequence(betweenRuns.runNumber))]; rmeddis@0: header=[header ' ' num2str(... rmeddis@0: betweenRuns.var2Sequence(betweenRuns.runNumber)) ':' ... rmeddis@0: betweenRuns.variableName2 ]; rmeddis@0: title(header) rmeddis@0: