DMDX Help.


Timing Notes.


Default frame duration.

    The default frame duration must be specified in the parameter line of an item file.  Failing to do so will make the default frame duration zero ticks leading to some decidedly unintuitive behavior, let me tell you.

Single frame display timing.

    When displaying a single frame while gathering an RT another frame must be specified after the single frame to erase it.  In DMDX you are specifying when the next frame is to be displayed and if there is no next frame the frame will stay displayed till erased by something else, be it feedback or the next item.  Here SHOE will be left on the screen till the subject responds or is timed out regardless of the %600:

^11 * "SHOE" %600 ;

   Instead a blank frame should be added at the end of the item:

^11 * "SHOE" %600 / ;

Comma frame delimiter timing.

    When using the comma frame delimiter the duration of the merged sequence must occur in the last frame of the series.  This is because a comma frame delimiter is exactly equivalent to %0 / ! so that %0 overrides any frame duration you specify (because frames are parsed left to right) in all frames except the last one.  For instance the following example will not be displayed for 600 ticks as intended but instead for whatever the default frame duration happens to be:

^11 * %600 "SHOE"@-3, "SLEEPY"@0, "DARK"@+2, "BEDROOM"@+3 / ;

  Instead the frame duration should be specified in the last frame of the series:

^11 * "SHOE"@-3, "SLEEPY"@0, "DARK"@+2, "BEDROOM"@+3 %600 / ;


Continuous Running considerations.

    The considerations outlined here were relevant prior to the introduction of the period modifier to the <Delay> keyword.  I've left this here for it's educational value and include the simpler solutions using period.

    An increasing number of people are using DMDX to control display sequences where physiological data is gathered by another machine, be it an fMRI machine or a BIOPAC.   These sequences are usually using continuous running and must have a rigidly fixed ISI using the delay parameter, which tend to put them beyond the considerations prevalent when delay and continuous running were coded making the overall desired result somewhat awkward (as if regular DMDX wasn't awkward enough anyway).   There are many considerations here, hopefully I can shed some light upon the most common of them however they're pretty much all rendered moot with the period modifier to the <Delay> keyword.

    The first consideration has to do with the duration of a frame.   When you specify a frame duration you are not actually specifying a frame duration, you are specifying the time at which to schedule the next frame for display.   Sounds straight forward and tautological even, however if there is no next frame in an item DMDX simply displays that frame and moves on to the next item, regardless of any frame duration specification.   Assuming we want a 40 tick presentation (a tick being the time from one vertical retrace of the monitor to the next) for three items the obvious solution to the above problem of a rigidly controlled fixed length display sequence is not the following:

d10 f30 <cr>
0 "start";
1 "first";
2 "second";
3 "third";
0 "stopped" l;


    The actual duration of the sequence from "start" to "stopped" is 33 ticks, 10 ticks per item for the delay parameter and 1 tick to display the word.   Once the word is displayed DMDX moves on to the next item, the request time (from which the delay is taken from) is the first time DMDX examines the display queue finding no more elements needing processing (because of the continuous running), so the f30 is meaningless in this example.

    The solution then is to give DMDX another frame:

d10 f29 <cr>
0 "start";
1 "first"/!;
2 "second"/!;
3 "third"/!;
0 "stopped" l;

    Here the duration is now our desired 120 ticks, 10 ticks per item for the delay, 29 ticks per item for the words and 1 tick per item for the frame that doesn't erase what's already on the screen.  Using <Delay period> it becomes the more intuitive solution (the f1 is in there simply because you're required to provide it):

<Delay period 40> f1 <cr>
0 "start";
1 "first";
2 "second";
3 "third";
0 "stopped" l;

    Note that we would get a display error on the "first" frame if we didn't request the end of the "start" instruction within 39 or so ticks however the period code looks for frames that would be late after an instruction and reschedules them.

    The next hurdle people encounter is displaying bitmaps, here the image can take a large portion of a second to load (or used to on hardware prevalent when this note was written in the late nineties or early noughties, these days it's less than a tenth of a second on most hardware and even less on newer stuff) so determining a value for the delay can be problematic.   The solution is a simple extension of the first item file but to deliberately have the delay determine almost the entire duration of the display.   Assuming we want a 3 second ISI and the refresh rate is 60Hz the following is required for a 9 second sequence:

d179 f30 <cr>
0 "start";
1 g "first";
2 g "second";
3 g "third";
0 "stopped" l;


    The f30 is superfluous, it isn't used but it's always a good idea to specify (later versions of DMDX require it).   Here each image is loaded as the previous is displayed allowing ample time to read the image files from disk.  The solution using <Delay period> would be the same except that you'd have <Delay period 180> instead of d179.

    Should individual frame require presentation for longer (or shorter) periods the delay can be overridden in individual frames, here we want second.bmp to be displayed for 6 seconds for a total sequence length of 12 seconds:

d179 f30 <cr>
0 "start";
1 g "first";
2 g "second";
3 d359 g "third";
0 "stopped" l;


    The above example will also work with <Delay period>, but the d option's value will be 360 instead of 359 -- note you're not using <Delay period 360> in the item, you're using d360 or <Delay 360>.  So:

<Delay period 180> f30 <cr>
0 "start";
1 g "first";
2 g "second";
3 <delay 360> g "third";
0 "stopped" l;

    Gathering RTs is more complicated (without using period).   You have to ensure that the display determines the duration of the item and you must set the subject RT timeout lower than the item display duration.   While theoretically you could leave the feedback enabled as it should have a constant display interval I don't think it's ever been put to the acid test and who knows what you'd have to do with the delay value (although of course using period provided you allow for the half second or so of the feedback then having feedback is straight forward):
   

d10 f29 <cr> t490 <nfb>
0 "start";
1 * "first"/!;
2 * "second"/!;
3 * "third"/!;
0 "stopped" l;

    Here f29 actually does something.   It will be gathering responses for a tad less than half a second followed by 11 ticks of time to assemble the next item during which the display will not have changed.  As usual using <Delay period> it's straight forward:

<Delay period 40> f1 <cr> t490 <nfb>
0 "start";
1 * "first";
2 * "second";
3 * "third";
0 "stopped" l;

    Lastly, gathering RTs and displaying bitmaps requires sectioning each item into two distinct portions, an active part where an RT is gathered and a passive part that is loading the next bitmap:
   

d59 f120 <cr> t1990 <nfb>
0 "start";
1 * g "first"/!;
2 * g "second"/!;
3 * g "third"/!;
0 "stopped" l;


    Here we still have a three second per item display, the first two seconds of which can have a response made and the last second is buffering time to load the next bitmap while the display still shows the previous bitmap.  A non-event using <Delay period> just bearing in mind that you don't want the timeout do be the full three seconds, leaving it a bit short so there's time to load bitmaps and so on:

<delay period 180> f1 <cr> t2500 <nfb>
0 "start";
1 * g "first";
2 * g "second";
3 * g "third";
0 "stopped" l;






DMDX Index.