|
1 | 1 | %% Demo showing how to use the getResponse function |
2 | 2 |
|
3 | 3 | % This small script shows how to use the getReponse function |
4 | | -% (a wrapper around the KbQueue function from PTB) |
5 | 4 |
|
6 | | -% start with a clean slate |
7 | | -cd .. |
8 | | -clear; clc; |
| 5 | +% add parent directory to matlab path (so we can access the CPP_PTB functions) |
| 6 | +addpath(fullfile(pwd, '..')) |
| 7 | + |
| 8 | + |
| 9 | +%% start with a clean slate |
| 10 | +clear; |
| 11 | +clc; |
| 12 | + |
9 | 13 | if IsOctave |
10 | 14 | more off % for a better display experience |
11 | 15 | end |
12 | 16 |
|
13 | | -%% set parameters |
| 17 | +% use the default set up (use main keyboard and use the ESCAPE key to abort) |
| 18 | +cfg = setDefaultsPTB; |
14 | 19 |
|
15 | | -% cfg.responseBox would be the device number of the device used by the participant to give his/her |
16 | | -% response: like the button box in the scanner or a separate keyboard for a behavioral experiment |
17 | | -% |
18 | | -% cfg.keyboard would be the device number of the keyboard on which the experimenter will type or |
19 | | -% press the keys necessary to start or abort the experiment. |
| 20 | +% show the default option |
| 21 | +disp(cfg.keyboard) |
20 | 22 |
|
21 | | -% cfg.responseBox and cfg.keyboard can be different or the same. |
| 23 | +%% set parameters |
22 | 24 |
|
23 | | -% If you want to know the device number of all the keyboards and responses |
24 | | -% boxes connected to the computer you can use the following code. |
25 | | -% [cfg.keyboardNumbers, cfg.keyboardNames] = GetKeyboardIndices |
| 25 | +% Change the values set by defaults (for more info about the keyboard see the doc) |
| 26 | +% cfg.keyboard.keyboard = ?? |
| 27 | +% cfg.keyboard.responseBox = ?? |
| 28 | +% cfg.keyboard.escapeKey = ?? |
26 | 29 |
|
27 | | -% Using empty vectors should work for linux when to select the "main" |
28 | | -% keyboard. You might have to try some other values for Windows. To |
29 | | -% assigne a specific keyboard input the kb assigned value (see README) |
30 | | -cfg.keyboard = []; |
31 | | -cfg.responseBox = []; |
| 30 | +% Decide which device you want to collect responses from |
| 31 | +deviceNumber = []; % default device (PTB will find it for you) |
| 32 | +% deviceNumber = cfg.keyboard.keyboard; % the one you may have chosen as the main keyboard |
| 33 | +% deviceNumber = cfg.keyboard.responseBox; % the one you may have chosen as the response box |
32 | 34 |
|
33 | | -cfg.escapeKey = 'ESCAPE'; |
| 35 | +% if you want getResponse to ignore the key release |
| 36 | +getOnlyPress = 1; |
34 | 37 |
|
35 | 38 | % We set which keys are "valid", any keys other than those will be ignored |
36 | | -expParameters.responseKey = {}; |
| 39 | +cfg.keyboard.responseKey = {'a', 'b'}; |
37 | 40 |
|
| 41 | +% This would make sure that you listen to presses of the escape key |
| 42 | +cfg.keyboard.responseKey{end+1} = cfg.keyboard.escapeKey; |
38 | 43 |
|
39 | | -%% init |
40 | 44 |
|
41 | | -% Keyboard |
42 | | -% Make sure keyboard mapping is the same on all supported operating systems |
43 | | -% Apple MacOS/X, MS-Windows and GNU/Linux: |
44 | | -KbName('UnifyKeyNames'); |
45 | | - |
46 | | - |
47 | | -% we ask PTB to tell us which keyboard devices are connected to the computer |
48 | | -[cfg.keyboardNumbers, cfg.keyboardNames] = GetKeyboardIndices; |
49 | | - |
50 | | -cfg.keyboardNumbers |
51 | | -cfg.keyboardNames |
| 45 | +%% Final checks |
52 | 46 |
|
| 47 | +% Make sure keyboard mapping is the same on all supported operating systems |
| 48 | +KbName('UnifyKeyNames'); |
53 | 49 |
|
54 | 50 | % Test that the keyboards are correctly configured |
55 | 51 | testKeyboards(cfg); |
56 | 52 |
|
57 | | -% Give the time to the test key to be released and not listened |
| 53 | +% Give the time to the test key to be released and not listened to |
58 | 54 | WaitSecs(1); |
59 | 55 |
|
60 | | - |
61 | 56 | fprintf('\nDuring the next 5 seconds we will collect responses on the following keys: \n\n'); |
62 | | -if isempty(expParameters.responseKey) |
| 57 | +if isempty(cfg.keyboard.responseKey) |
63 | 58 | fprintf('\nALL KEYS\n\n'); |
64 | 59 | else |
65 | | - for iKey=1:numel(expParameters.responseKey) |
66 | | - fprintf('\n%s', expParameters.responseKey{iKey}); |
| 60 | + for iKey=1:numel(cfg.keyboard.responseKey) |
| 61 | + fprintf('\n%s', cfg.keyboard.responseKey{iKey}); |
67 | 62 | end |
68 | 63 | fprintf('\n\n'); |
69 | 64 | end |
70 | 65 |
|
71 | 66 |
|
72 | 67 | %% Run demo |
73 | 68 |
|
| 69 | +try |
| 70 | + |
74 | 71 | % Create the keyboard queue to collect responses. |
75 | | -getResponse('init', cfg, expParameters, 1); |
| 72 | +getResponse('init', deviceNumber, cfg); |
76 | 73 |
|
77 | 74 | % Start collecting responses for 5 seconds |
78 | 75 | % Each new key press is added to the queue of events recorded by KbQueue |
79 | 76 | startSecs = GetSecs(); |
80 | | -getResponse('start', cfg, expParameters, 1); |
| 77 | +getResponse('start', deviceNumber); |
81 | 78 |
|
82 | 79 | % Here we wait for 5 seconds but are still collecting responses. |
83 | 80 | % So you could still be doing something else (presenting audio and visual stim) and |
84 | 81 | % still collect responses. |
85 | 82 | WaitSecs(5); |
86 | 83 |
|
87 | 84 | % Check what keys were pressed (all of them) |
88 | | -responseEvents = getResponse('check', cfg, expParameters, 0); |
89 | | - |
90 | | -% The following line would only return key presses and not releases |
91 | | -% responseEvents = getResponse('check', cfg, expParameters, 1); |
| 85 | +% If the escapeKey was pressed at any time, it will only abort when you |
| 86 | +% getResponse('check') |
| 87 | +responseEvents = getResponse('check', deviceNumber, cfg, getOnlyPress); |
92 | 88 |
|
93 | 89 | % This can be used to flush the queue: empty all events that are still present in the queue |
94 | | -getResponse('flush', cfg, expParameters, 1); |
| 90 | +getResponse('flush', deviceNumber); |
| 91 | + |
| 92 | +% If you wan to stop listening to key presses. You could start listening again |
| 93 | +% later by calling: getResponse('start', deviceNumber) |
| 94 | +getResponse('stop', deviceNumber); |
95 | 95 |
|
96 | | -% If you wan to stop listening to key presses. |
97 | | -getResponse('stop', cfg, expParameters, 1); |
| 96 | +% If you wan to destroyt the queue: you would have to initialize it again |
| 97 | +getResponse('release', deviceNumber); |
98 | 98 |
|
99 | 99 |
|
100 | 100 | %% Now we look what keys were pressed and when |
|
106 | 106 | eventType = 'released'; |
107 | 107 | end |
108 | 108 |
|
109 | | - fprintf('\n%s was %s at time %.3f seconds\n', ... |
| 109 | + fprintf('\n %s was %s at time %.3f seconds\n', ... |
110 | 110 | responseEvents(iEvent).key_name, ... |
111 | 111 | eventType, ... |
112 | 112 | responseEvents(iEvent).onset - startSecs); |
113 | 113 |
|
114 | 114 | end |
| 115 | + |
| 116 | + |
| 117 | +catch ME |
| 118 | + |
| 119 | + getResponse('release', deviceNumber) |
| 120 | + |
| 121 | + switch ME.identifier |
| 122 | + |
| 123 | + case 'getResponse:abortRequested' |
| 124 | + warning('You pressed the escape key: will try to fail gracefully.') |
| 125 | + |
| 126 | + fprintf('\nWe did catch your abort signal.\n') |
| 127 | + |
| 128 | + otherwise |
| 129 | + rethrow(ME) % display other errors |
| 130 | + |
| 131 | + end |
| 132 | +end |
| 133 | + |
| 134 | + |
0 commit comments