Skip to content
Stroop_170904.m 7.54 KiB
Newer Older
Julian Kosciessa's avatar
Julian Kosciessa committed
function Stroop_170904(subjectsPath, setup)

% 170904 JQK | adapted from http://peterscarfe.com/stroopdemo.html
%            | merged with parts of BasicSoundInputDemo for audio recording
%            | removed parts related to RT encoding by button press

%% create individual directory

StroopPath = [subjectsPath, 'Stroop/']; mkdir(StroopPath);

%% set Stroop parameters

expInfo.Stroop.durITI = 1;
expInfo.Stroop.durResp = 2;

%% startup PTB

% Setup PTB with some default values
PsychDefaultSetup(2);

% Perform basic initialization of the sound driver:
InitializePsychSound;

% Open the default audio device [], with mode 2 (== Only audio capture),
% and a required latencyclass of zero 0 == no low-latency mode, as well as
% a frequency of 44100 Hz and 2 sound channels for stereo capture.
% This returns a handle to the audio device:
freq = 44100;
pahandle = PsychPortAudio('Open', [], 2, 0, freq, 2);

% Preallocate an internal audio recording  buffer with a capacity of 5 seconds:
PsychPortAudio('GetAudioData', pahandle, 5);

rng('default');
rng('shuffle');
expInfo.Stroop.seed = rng;

% Set the screen number to the external secondary monitor if there is one
% connected
displayList = Screen('screens');
displayIdx = displayList(setup.screen);
KbName('UnifyKeyNames'); % Make sure keyboard mapping is the same on all supported operating systems
oldVerbosityLevel = Screen('Preference', 'Verbosity', 2); % show errors and warnings

if setup.DEBUG == 1
    Screen('Preference', 'SkipSyncTests', 1);
    PsychDebugWindowConfiguration(0, setup.opacity);
else
    clear Screen; %PsychDebugWindowConfiguration([], 1);
end

% % Define black, white and grey
% white = WhiteIndex(displayIdx);
% grey = white / 2;
% black = BlackIndex(displayIdx);

screenInfo = openExperiment(50,50,displayIdx); clc; % open drawing canvas
if numel(Screen('screens')) == 1
  HideCursor(screenInfo.curWindow);
end
Screen('TextFont', screenInfo.curWindow, 'Helvetica');
Screen('TextSize', screenInfo.curWindow, 20);
Screen('TextStyle', screenInfo.curWindow, 0); % regular
Screen('TextColor', screenInfo.curWindow, 255); % white
ifi = Screen('GetFlipInterval', screenInfo.curWindow); % Query the frame duration

% initiate black background
Screen('FillRect', screenInfo.curWindow, [255/2 255/2 255/2])

% Flip to clear
Screen('Flip', screenInfo.curWindow);

% Query the frame duration
ifi = Screen('GetFlipInterval', screenInfo.curWindow);

% Set the text size
Screen('TextSize', screenInfo.curWindow, 60);

% Query the maximum priority level
topPriorityLevel = MaxPriority(screenInfo.curWindow);

% Get the centre coordinate of the screenInfo.curWindow
[xCenter, yCenter] = RectCenter(screenInfo.screenRect);

% Set the blend funciton for the screen
Screen('BlendFunction', screenInfo.curWindow, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');

% Do dummy calls to GetSecs, WaitSecs, KbCheck(-1) to make sure
% they are loaded and ready when we need them - without delays
% in the wrong moment:
KbCheck(-1);
WaitSecs(0.1);
GetSecs;

%----------------------------------------------------------------------
%                       Timing Information
%----------------------------------------------------------------------

% Interstimulus interval time in seconds and frames
isiTimeSecs = expInfo.Stroop.durITI;
isiTimeFrames = round(isiTimeSecs / ifi);

% Numer of frames to wait before re-drawing
waitframes = 1;

expInfo.Stroop.Timing = [];

%----------------------------------------------------------------------
%                     Colors in words and RGB
%----------------------------------------------------------------------

% We are going to use three colors for this demo. Red, Green and blue.
expInfo.Stroop.wordList = {'Rot', 'Grn', 'Blau'};
rgbColors = [255 0 0; 0 255 0; 0 0 255];

% Make the matrix which will determine our condition combinations
condMatrixBase = [sort(repmat([1 2 3], 1, 3)); repmat([1 2 3], 1, 3)];

trialsPerCondition = 9;

% Duplicate the condition matrix to get the full number of trials
condMatrix = repmat(condMatrixBase, 1, trialsPerCondition);

% Get the size of the matrix
[~, numTrials] = size(condMatrix);

% Randomise the conditions
shuffler = Shuffle(1:numTrials);
condMatrixShuffled = condMatrix(:, shuffler);

expInfo.Stroop.ColorCondsByTrial = condMatrixShuffled;
expInfo.Stroop.ColorCondsName = {'Row1: word'; 'Row2: color'};

%----------------------------------------------------------------------
%                       Experimental loop
%----------------------------------------------------------------------

% Animation loop: we loop for the total number of trials
for trial = 1:numTrials

    % Word and color number
    wordNum = condMatrixShuffled(1, trial);
    colorNum = condMatrixShuffled(2, trial);

    % The color word and the color it is drawn in
    theWord = expInfo.Stroop.wordList(wordNum);
    theColor = rgbColors(colorNum, :);

    % If this is the first trial we present a start screen and wait for a
    % key-press
    if trial == 1
        DrawFormattedText(screenInfo.curWindow, 'Bennenen Sie bitte die Wortfarbe. \n\n Drcken Sie eine Taste, um zu beginnen.',...
            'center', 'center', [0 0 0]);
        vbl = Screen('Flip', screenInfo.curWindow);
        expInfo.Stroop.Timing = [expInfo.Stroop.Timing; {'ExpOnset'}, {vbl}];
        KbStrokeWait;
    end

    % Flip again to sync us to the vertical retrace at the same time as
    % drawing our fixation point
    Screen('DrawDots', screenInfo.curWindow, [xCenter; yCenter], 10, [0 0 0], [], 2);
    if trial == 1
        flipWhen = 0;
    else
        flipWhen = StimOnset+expInfo.Stroop.durResp-ifi/2;
    end
    ITIOnset = Screen('Flip', screenInfo.curWindow, flipWhen);
    expInfo.Stroop.Timing = [expInfo.Stroop.Timing; {'FixOnset'}, {ITIOnset}];
    % set Onset for next stimulus
    flipWhen = ITIOnset+expInfo.Stroop.durITI-ifi/2;

    while GetSecs() < ITIOnset+expInfo.Stroop.durITI-100
        pause(.001)
    end

    if trial ~= 1
        % get audio from previous trial
        StroopAudio.audio{trial-1} = PsychPortAudio('GetAudioData', pahandle);
        PsychPortAudio('Stop', pahandle);
        expInfo.Stroop.Timing = [expInfo.Stroop.Timing; {'GetAudio'}, {GetSecs()}];
        AudioEncoded = 1;
    end
    
    % start next audio recording at specified time
    PsychPortAudio('Start', pahandle, [], flipWhen);
        
    % The person should be asked to respond to either the written word or
    % the color the word is written in.
    % Present the word, start audio recording.
    
    DrawFormattedText(screenInfo.curWindow, char(theWord), 'center', 'center', theColor);
    AudioEncoded = 0;
    StimOnset = Screen('Flip', screenInfo.curWindow, flipWhen);
    expInfo.Stroop.Timing = [expInfo.Stroop.Timing; {'StroopStart'}, {StimOnset}];
    % We retrieve status once to get access to SampleRate:
    if trial == 1
        StroopAudio.s = PsychPortAudio('GetStatus', pahandle);
    end
end

% record last audio response and exit PTB screen
DrawFormattedText(screenInfo.curWindow, 'Sie haben die Stroop-Aufgabe nun beendet. \n\n Vielen Dank!','center', 'center', [0 0 0]);
vbl = Screen('Flip', screenInfo.curWindow, StimOnset+expInfo.Stroop.durResp-ifi/2);
expInfo.Stroop.Timing = [expInfo.Stroop.Timing; {'EndScreen'}, {vbl}];
while GetSecs() < StimOnset+expInfo.Stroop.durResp+expInfo.Stroop.durITI-100
    pause(.001);
end
PsychPortAudio('Stop', pahandle);
StroopAudio.audio{trial} = PsychPortAudio('GetAudioData', pahandle);
expInfo.Stroop.Timing = [expInfo.Stroop.Timing; {'GetAudio'}, {GetSecs()}];
PsychPortAudio('Close', pahandle);

%% save data

save([StroopPath,setup.subj(1:4), '_StroopData.mat'], 'StroopAudio', 'expInfo');

% KbStrokeWait;
pause(2);
sca;

end