The <call> variant of all branches stores the location of the next item before performing the branch allowing limited subroutine like behavior with the <return> keyword that resumes execution at the item following the item with the call keyword. Calls cannot be nested
unless a call stack is first created with the
<CallStack> parameter. Branch diagnostics will not reflect the call variant (ie, a call keyword will be referenced as a branch).
Because the variable that stores the RT for branches to make decisions against is not cleared until another RT is gathered the subroutine can continue to make tests allowing very flexible feedback routines, for example the following items could provide acoustic feedback:
f20 <nfb>
<!branchdiagnostics>
0 "Acoustic Feedback Example" <bu 40>;
~10 <biw 20>;
0 d20 <wav> "correct"
<return>;
~20 <binr 30>;
0 d20 <wav> "wrong" <return>;
30 d20 <wav> "noresponse" <return>;
~40;
+100 * "target" / <call -10> c;
+110 * "target" / <call -10> c;
The ~ (<SkipDisplay> synonym) is in there to make those items execute as rapidly as possible and the d20 is similarly to make those items execute quickly, the delay value is large enough to allow the audio to be read from disk. Alternatively the RT gathering item's frames could be marked time critical and the feedback items delay all set to 1, the timing errors for feedback would then be ignored and it would be presented as rapidly as possible.
The
<mwb> documentation has a
non-call based version of this same auditory feedback task that's designed for
custom feedback for each item in the instances where you want to give clues and
have subjects repeat items till they get them right.
You'll notice we have a commented out branch diagnostics
keyword in there
<!branchdiagnostics>. While that's inactive with the bang in
front of it if you take that out you'll be able to trace what the item file is
doing by looking in the diagnostics or the data file. You would not want
to leave that uncommented in actual data as the spew into the data file can be
excessive...
Another example is where you might want to warn subjects if they are too slow
but still gather their RTs without having the time limit truncate the RT:
f20 <nfb>
<timeout 8000> <!branchdiagnostics>
0 "RT warning Feedback Example" <bu 1000>;
~999 <bi 998, lastxt .lt. 0>;
~997 <bi 996, lastxt .gt. 4000>;
995 "correct" <return>;
996 "correct, but too slow" <return>;
~998 <bi 994, lastxt .lt. -4000>;
993 "incorrect" <return>;
~994 <bi 992, lasxt .eq. -8000>;
991 "incorrect and too slow" <return>;
992 "too long" <return>;
~1000;
+100 * "target" / <call -999> c;
+110 * "target" / <call -999> c;
Another reasonably common sort thing to want to do is to limit the subject to a certain amount of time to complete the task. Here we have a section of the item file that isn't limited (the 100's) followed by a time limited section (the 200's). Our example limits it to ten seconds, you'll want to substitute your limit (in milliseconds) for the 10000 in the example.
f20 <cr> <!branchdiagnostics>
0 "Timelimit Example" <bu 1000>;
~999 <bi 998, millisectime .lt. c1>;
0
"Time Limit" <lastframe>;
~998 <return>;
~1000;
+100 * "target" / ;
+110 *
"target" / ;
0 "Time limit starts now" <set c1 = millisectime + 10000>;
+200 * "target" / <call -999>;
+210 * "target" / <call -999>;
+220 *
"target" / <call -999>;
+230 * "target" / <call -999>;
0 "The End" <lastframe>;
In addition the Probabilistic Selection Task example has probabilistic feedback where the same answer is not always right or wrong (as well as using a bunch of other quite advanced techniques).