expyfun.ExperimentController

class expyfun.ExperimentController(exp_name, audio_controller=None, response_device=None, stim_rms=0.01, stim_fs=24414, stim_db=65, noise_db=45, output_dir='data', window_size=None, screen_num=None, full_screen=True, force_quit=None, participant=None, monitor=None, trigger_controller=None, session=None, check_rms='windowed', suppress_resamp=False, version=None, safe_flipping=None, n_channels=2, trigger_duration=0.01, joystick=False, verbose=None)[source]

Interface for hardware control (audio, buttonbox, eye tracker, etc.)

Parameters:
exp_namestr

Name of the experiment.

audio_controllerstr | dict | None

If audio_controller is None, the type will be read from the system configuration file. If a string, can be ‘sound_card’ or ‘tdt’, and the remaining audio parameters will be read from the machine configuration file. If a dict, must include a key ‘TYPE’ that is one of the supported types; the dict can contain other parameters specific to the backend (see TDTController and SoundCardController).

response_devicestr | None

Must be ‘keyboard’, ‘cedrus’, or ‘tdt’. If None, the type will be read from the machine configuration file.

stim_rmsfloat

The RMS amplitude that the stimuli were generated at (strongly recommended to be 0.01).

stim_fsint | float

The sampling frequency that the stimuli were generated with (samples per second).

stim_dbfloat

The desired dB SPL at which to play the stimuli.

noise_dbfloat

The desired dB SPL at which to play the dichotic noise.

output_dirstr | None

An absolute or relative path to a directory in which raw experiment data will be stored. If output_folder does not exist, it will be created. Data will be saved to output_dir/SUBJECT_DATE. If None, no output data or logs will be saved (ONLY FOR TESTING!).

window_sizelist | array | None

Window size to use. If list or array, it must have two elements. If None, the default will be read from the system config, falling back to [1920, 1080] if no system config is found.

screen_numint | None

Screen to use. If None, the default will be read from the system config, falling back to 0 if no system config is found.

full_screenbool

Should the experiment window be fullscreen?

force_quitlist

Keyboard key(s) to utilize as an experiment force-quit button. Can be a zero-element list for no force quit support. If None, defaults to ['lctrl', 'rctrl']. Using ['escape'] is not recommended due to default handling of ‘escape’ in pyglet.

participantstr | None

If None, a GUI will be used to acquire this information.

monitordict | None

Monitor properties. If dict, must include keys SCREEN_WIDTH, SCREEN_DISTANCE, and SCREEN_SIZE_PIX. Generally this can be None if the width and distance have been set properly for the machine in use.

trigger_controllerstr | None

If None, the type will be read from the system configuration file. If a string, must be ‘dummy’, ‘parallel’, ‘sound_card’, or ‘tdt’. By default the mode is ‘dummy’, since setting up the parallel port can be a pain. Can also be a dict with entries ‘TYPE’ (‘parallel’), and ‘TRIGGER_ADDRESS’ (None).

sessionstr | None

If None, a GUI will be used to acquire this information.

check_rmsstr | None

Method to use in checking stimulus RMS to ensure appropriate levels. Possible values are None, wholefile, and windowed (the default); see set_rms_checking for details.

suppress_resampbool

If True, will suppress resampling of stimuli to the sampling frequency of the sound output device.

versionstr | None

A length-7 string passed to expyfun.assert_version() to ensure that the expected version of the expyfun codebase is being used when running experiments. To override version checking (e.g., during development) use version='dev'.

safe_flippingbool | None

If False, do not use glFinish when flipping. This can restore 60 Hz on Linux systems where 30 Hz framerates occur, but the timing is not necessarily guaranteed, as the flip may return before the stimulus has actually flipped (check with A-V sync test).

n_channelsint

The number of audio playback channels. Defaults to 2 (must be 2 if a TDT is used).

trigger_durationfloat

The trigger duration to use (sec). Must be 0.01 for TDT.

joystickbool

Whether or not to enable joystick control.

verbosebool, str, int, or None

If not None, override default verbose level (see expyfun.verbose).

Returns:
exp_controllerinstance of ExperimentController

The experiment control interface.

Notes

When debugging, it’s useful to use the flush_logs() method to get information (based on the level of verbosity) printed to the console.

call_on_every_flip(function)[source]

Add a function to be executed on every flip.

Parameters:
functionfunction | None

The function to call. If None, all the “on every flip” functions will be cleared.

Notes

See flip_and_play for order of operations. Can be called multiple times to add multiple functions to the queue. If the function must be called with arguments, use functools.partial() before passing to call_on_every_flip.

call_on_next_flip(function)[source]

Add a function to be executed on next flip only.

Parameters:
functionfunction | None

The function to call. If None, all the “on every flip” functions will be cleared.

Notes

See flip_and_play for order of operations. Can be called multiple times to add multiple functions to the queue. If the function must be called with arguments, use functools.partial() before passing to call_on_next_flip.

check_force_quit()[source]

Check to see if any force quit keys were pressed.

close()[source]

Close all connections in experiment controller.

property current_time

Timestamp from the experiment master clock.

property data_fname

Date filename

delete_video()[source]

Delete the video.

estimate_screen_fs(n_rep=10)[source]

Estimate screen refresh rate using repeated flip() calls

Useful for verifying that a system is operating at the proper sample rate.

Parameters:
n_repint

Number of flips to use. The higher the number, the more accurate the estimate but the more time will be consumed.

Returns:
screen_fsfloat

The screen refresh rate.

flip(when=None)[source]

Flip screen, then run any “on-flip” functions.

Parameters:
whenfloat | None

Time to flip. If None, flip immediately. Note that due to flip timing limitations, this is only a guaranteed minimum (not absolute) wait time before the flip completes. As a result, in some cases when should be set to a value smaller than your true intended flip time.

Returns:
flip_timefloat

The timestamp of the screen flip.

Notes

Order of operations is: screen flip, functions added with call_on_next_flip, followed by functions added with call_on_every_flip.

flush()[source]

Flush logs and data files.

property fs

Playback frequency of the audio controller (samples / second).

get_clicks(live_buttons=None, timestamp=True, relative_to=None)[source]

Get the entire keyboard / button box buffer.

Parameters:
live_buttonslist | None

List of strings indicating acceptable buttons. None accepts all mouse clicks.

timestampbool

Whether the mouse click should be timestamped. If True, returns the button click time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time listen_clicks was last called.

Returns:
clickslist of tuple

Returns a list of the clicks between min_wait and max_wait. If timestamp==True, each entry is a tuple (str, int, int, float) indicating the button clicked and its timestamp. If timestamp==False, each entry is a tuple (str, int, int) indicating the button clicked.

get_joystick_button_presses(timestamp=True, relative_to=None, kind='presses', return_kinds=False)[source]

Get the entire joystick buffer.

This will also clear events that are not requested per type.

Parameters:
timestampbool

Whether the keypress should be timestamped. If True, returns the button press time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time listen_presses was last called.

kindstring

Which button events to return. One of presses, releases or both. (default presses)

return_kindsbool

Return the kinds of presses.

Returns:
presseslist

Returns a list of tuples with button events. Each tuple’s first value will be the button pressed. If timestamp==True, the second value is the time for the event. If return_kinds==True, then the last value is a string indicating if this was a button press or release event.

get_joystick_value(kind)[source]

Get the current joystick x direction.

Parameters:
kindstr

Can be “x”, “y”, “hat_x”, “hat_y”, “z”, “rz”, “rx”, or “ry”.

Returns:
xfloat

Value in the range -1 to 1.

get_mouse_position(units='pix')[source]

Mouse position in screen coordinates

Parameters:
unitsstr

Units to return. See check_units for options.

Returns:
positionndarray

The mouse position.

get_presses(live_keys=None, timestamp=True, relative_to=None, kind='presses', return_kinds=False)[source]

Get the entire keyboard / button box buffer.

This will also clear events that are not requested per type.

Parameters:
live_keyslist | None

List of strings indicating acceptable keys or buttons. Other data types are cast as strings, so a list of ints will also work. None accepts all keypresses.

timestampbool

Whether the keypress should be timestamped. If True, returns the button press time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time listen_presses was last called.

kindstring

Which key events to return. One of presses, releases or both. (default presses)

return_kindsbool

Return the kinds of presses.

Returns:
presseslist

Returns a list of tuples with key events. Each tuple’s first value will be the key pressed. If timestamp==True, the second value is the time for the event. If return_kinds==True, then the last value is a string indicating if this was a key press or release event.

get_time()[source]

Return current master clock time

Returns:
timefloat

Time since ExperimentController was created.

property id_types

Trial ID types needed for each trial.

identify_trial(**ids)[source]

Identify trial type before beginning the trial

Parameters:
**idskeyword arguments

Ids to stamp, e.g. ec_id='TL90,MR45'. Use `id_types` to see valid options. Typical choices are ``ec_id, el_id, and ttl_id for experiment controller, eyelink, and TDT (or parallel port) respectively. If the value passed is a dict, its entries will be passed as keywords to the underlying function.

listen_clicks()[source]

Start listening for mouse clicks.

listen_joystick_button_presses()[source]

Start listening for joystick buttons.

listen_presses()[source]

Start listening for keypresses.

load_buffer(samples)[source]

Load audio data into the audio buffer

Parameters:
samplesnp.array

Audio data as floats scaled to (-1,+1), formatted as numpy array with shape (1, N), (2, N), or (N,) dtype float32.

load_video(file_name, pos=(0, 0), units='norm', center=True)[source]

Load a video.

Parameters:
file_namestr

The filename.

postuple

The screen position.

unitsstr

Units for pos. See check_units for options.

centerbool

If True, center the video.

move_mouse_to(pos, units='norm')[source]

Move the mouse position to the specified position.

Parameters:
posarray-like

2-element array-like with X and Y.

unitsstr

Units to use. See check_units for options.

property noise_db

Sound power in dB of the background noise.

property on_every_flip_functions

Current stack of functions called on every flip.

property on_next_flip_functions

Current stack of functions to be called on next flip.

play()[source]

Start audio playback

Returns:
play_timefloat

The timestamp of the audio playback.

refocus()[source]

Attempt to grab operating system window manager / keyboard focus.

This implements platform-specific trickery to bring the window to the top and capture keyboard focus in cases where keyboard input from a subject is mandatory (e.g., when using keyboard as a response device).

Notes

For Windows, the solution as adapted from:

This function currently does nothing on Linux and OSX.

screen_prompt(text, max_wait=inf, min_wait=0, live_keys=None, timestamp=False, clear_after=True, pos=[0, 0], color='white', font_name='Arial', font_size=24, wrap=True, units='norm', attr=True, click=False)[source]

Display text and (optionally) wait for user continuation

Parameters:
textstr | list

The text to display. It will automatically wrap lines. If list, the prompts will be displayed sequentially.

max_waitfloat

The maximum amount of time to wait before returning. Can be np.inf to wait until the user responds.

min_waitfloat

The minimum amount of time to wait before returning. Useful for avoiding subjects missing instructions.

live_keyslist | None

The acceptable list of buttons or keys to use to advance the trial. If None, all buttons / keys will be accepted. If an empty list, the prompt displays until max_wait seconds have passed.

timestampbool

If True, output the timestamp as well.

clear_afterbool

If True, the screen will be cleared before returning.

poslist | tuple

x, y position of the text. In the default units (-1 to 1, with positive going up and right) the default is dead center (0, 0).

colormatplotlib color

The text color.

font_namestr

The name of the font to use.

font_sizefloat

The font size (in points) to use.

wrapbool

Whether or not the text will wrap to fit in screen, appropriate for multi-line text. Inappropriate for text requiring precise positioning or centering.

unitsstr

Units for pos. See check_units for options. Applies to pos but not font_size.

attrbool

Should the text be interpreted with pyglet’s decode_attributed method? This allows inline formatting for text color, e.g., 'This is {color (255, 0, 0, 255)}red text'.

clickbool

Whether to use clicks to advance rather than key presses.

Returns:
pressedtuple | str | None

If timestamp==True, returns a tuple (str, float) indicating the first key pressed and its timestamp (or (None, None) if no acceptable key was pressed between min_wait and max_wait). If timestamp==False, returns a string indicating the first key pressed (or None if no acceptable key was pressed).

screen_text(text, pos=[0, 0], color='white', font_name='Arial', font_size=24, wrap=True, units='norm', attr=True, log_data=True)[source]

Show some text on the screen.

Parameters:
textstr

The text to be rendered.

poslist | tuple

x, y position of the text. In the default units (-1 to 1, with positive going up and right) the default is dead center (0, 0).

colormatplotlib color

The text color.

font_namestr

The name of the font to use.

font_sizefloat

The font size (in points) to use.

wrapbool

Whether or not the text will wrap to fit in screen, appropriate for multi-line text. Inappropriate for text requiring precise positioning or centering.

unitsstr

Units for pos. See check_units for options. Applies to pos but not font_size.

attrbool

Should the text be interpreted with pyglet’s decode_attributed method? This allows inline formatting for text color, e.g., 'This is {color (255, 0, 0, 255)}red text'.

log_databool

Whether or not to write a line in the log file.

Returns:
Instance of visual.Text
screenshot()[source]

Capture the current displayed buffer

This method must be called before flipping, because it captures the back buffer.

Returns:
dataarray, shape (h, w, 4)

Screen pixel colors.

set_background_color(color='black')[source]

Set and draw a solid background color

Parameters:
colormatplotlib color

The background color.

Notes

This should be called before anything else is drawn to the buffer, since it will draw a filled rectangle over everything. On subsequent flips, the rectangle will automatically be “drawn” because glClearColor will be set so the buffer starts out with the appropriate background color.

set_noise_db(new_db)[source]

Set the level of the background noise.

Parameters:
new_dbfloat

The new level.

set_rms_checking(check_rms)[source]

Set the RMS checking flag.

Parameters:
check_rmsstr | None

Method to use in checking stimulus RMS to ensure appropriate levels. 'windowed' uses a 10ms window to find the max RMS in each channel and checks to see that it is within 6 dB of the stated stim_rms. 'wholefile' checks the RMS of the stimulus as a whole, while None disables RMS checking.

set_stim_db(new_db)[source]

Set the level of the stimuli.

Parameters:
new_dbfloat

The new level.

set_visible(visible=True, flip=True)[source]

Set the window visibility

Parameters:
visiblebool

The visibility.

flipbool

If visible is True, call flip after setting visible. This fixes an issue with the window background color not being set properly for the first draw after setting visible; by default (at least on Linux) the background is black when the window is restored, regardless of what the glClearColor had been set to.

stamp_triggers(ids, check='binary', wait_for_last=True)[source]

Stamp binary values

Parameters:
idsint | list of int

Value(s) to stamp.

checkstr

If ‘binary’, enforce standard binary value stamping of only values [1, 2, 4, 8]. If ‘int4’, enforce values as integers between 1 and 15.

wait_for_lastbool

If True, wait for last trigger to be stamped before returning. If False, don’t wait at all (if possible).

Notes

This may be (nearly) instantaneous, or take a while, depending on the type of triggering (TDT, sound card, or parallel).

start_noise()[source]

Start the background masker noise

start_stimulus(start_of_trial=True, flip=True, when=None)[source]

Play audio, (optionally) flip screen, run any “on_flip” functions.

Parameters:
start_of_trialbool

If True, it checks to make sure that the trial ID has been stamped appropriately. Set to False only in cases where flip_and_play is to be used mid-trial (should be rare!).

flipbool

If False, don’t flip the screen.

whenfloat | None

Time to start stimulus. If None, start immediately. Note that due to flip timing limitations, this is only a guaranteed minimum (not absolute) wait time before the flip completes (if flip is True). As a result, in some cases when should be set to a value smaller than your true intended flip time.

Returns:
flip_timefloat

The timestamp of the screen flip.

Notes

Order of operations is: screen flip (optional), audio start, then (only if flip=True) additional functions added with call_on_next_flip and call_on_every_flip.

property stim_db

Sound power in dB of the stimuli.

property stim_fs

Sampling rate at which the stimuli were generated.

stop(wait=False)[source]

Stop audio buffer playback and reset cursor to beginning of buffer

Parameters:
waitbool

If True, try to wait until the end of the sound stimulus (not guaranteed to yield accurate timings!).

stop_noise()[source]

Stop the background masker noise

system_beep()[source]

Play a system beep

This will play through the system audio, not through the audio controller (unless that is set to be the system audio). This is useful for e.g., notifying that it’s time for an eye-tracker calibration.

text_input(stop_key='return', instruction_string='Type response below', pos=[0, 0], color='white', font_name='Arial', font_size=24, wrap=True, units='norm', all_caps=True)[source]

Allows participant to input text and view on the screen.

Parameters:
stop_keystr

The key to exit text input mode.

instruction_stringstr

A string after the text entry to tell the participant what to do.

poslist | tuple

x, y position of the text. In the default units (-1 to 1, with positive going up and right) the default is dead center (0, 0).

colormatplotlib color

The text color.

font_namestr

The name of the font to use.

font_sizefloat

The font size (in points) to use.

wrapbool

Whether or not the text will wrap to fit in screen, appropriate for multi-line text. Inappropriate for text requiring precise positioning or centering.

unitsstr

Units for pos. See check_units for options. Applies to pos but not font_size.

all_capsbool

Whether the text should be displayed in all caps.

Returns:
textstr

The final input string.

toggle_cursor(visibility, flip=False)[source]

Show or hide the mouse

Parameters:
visibilitybool

If True, show; if False, hide.

flipbool

If True, flip after toggling.

trial_ok()[source]

Report that the trial was okay and do post-trial tasks.

For example, logs and data files can be flushed at the end of each trial.

wait_for_click_on(objects, max_wait=inf, min_wait=0.0, live_buttons=None, timestamp=True, relative_to=None)[source]

Returns the first click after min_wait over a visual object.

Parameters:
objectslist | Rectangle | Circle

A list of objects (or a single object) that the user may click on. Supported types are: Rectangle, Circle

max_waitfloat

Duration after which control is returned if no button is clicked.

min_waitfloat

Duration for which to ignore button clicks.

live_buttonslist | None

List of strings indicating acceptable buttons. None accepts all mouse clicks.

timestampbool

Whether the mouse click should be timestamped. If True, returns the mouse click time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time wait_one_click was called.

Returns:
clickedtuple | str | None

If timestamp==True, returns a tuple (str, int, int, float) indicating the first valid button clicked and its timestamp (or (None, None, None, None) if no acceptable button was clicked between min_wait and max_wait). If timestamp==False, returns a tuple (str, int, int) indicating the first button clicked (or (None, None, None) if no acceptable key was clicked).

indexthe index of the object in the list of objects that was clicked

on. Returns None if time ran out before a valid click. If objects were overlapping, it returns the index of the object that comes first in the objects argument.

wait_for_clicks(max_wait=inf, min_wait=0.0, live_buttons=None, timestamp=True, relative_to=None, visible=None)[source]

Returns all clicks between min_wait and max_wait.

Parameters:
max_waitfloat

Duration after which control is returned if no button is clicked.

min_waitfloat

Duration for which to ignore button clicks.

live_buttonslist | None

List of strings indicating acceptable buttons. None accepts all mouse clicks.

timestampbool

Whether the mouse click should be timestamped. If True, returns the mouse click time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time wait_one_click was called.

visibleNone | bool

Whether to show the cursor while in the function. None has no effect and is the default. A boolean will show it (or not) while the function has control and then set visibility back to its previous value afterwards.

Returns:
clickslist of tuple

Returns a list of the clicks between min_wait and max_wait. If timestamp==True, each entry is a tuple (str, int, int, float) indicating the button clicked and its timestamp. If timestamp==False, each entry is a tuple (str, int, int) indicating the button clicked.

wait_for_presses(max_wait, min_wait=0.0, live_keys=None, timestamp=True, relative_to=None)[source]

Returns all button presses between min_wait and max_wait.

Parameters:
max_waitfloat

Duration after which control is returned.

min_waitfloat

Duration for which to ignore keypresses (force-quit keys will still be checked at the end of the wait).

live_keyslist | None

List of strings indicating acceptable keys or buttons. Other data types are cast as strings, so a list of ints will also work. None accepts all keypresses.

timestampbool

Whether the keypresses should be timestamped. If True, returns the button press time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp is False. If None, timestamps are relative to the time wait_for_presses was called.

Returns:
presseslist

If timestamp==False, returns a list of strings indicating which keys were pressed. Otherwise, returns a list of tuples (str, float) of keys and their timestamps.

wait_one_click(max_wait=inf, min_wait=0.0, live_buttons=None, timestamp=True, relative_to=None, visible=None)[source]

Returns only the first mouse button clicked after min_wait.

Parameters:
max_waitfloat

Duration after which control is returned if no button is clicked.

min_waitfloat

Duration for which to ignore button clicks.

live_buttonslist | None

List of strings indicating acceptable buttons. None accepts all mouse clicks.

timestampbool

Whether the mouse click should be timestamped. If True, returns the mouse click time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time wait_one_click was called.

visibleNone | bool

Whether to show the cursor while in the function. None has no effect and is the default. A boolean will show it (or not) while the function has control and then set visibility back to its previous value afterwards.

Returns:
clickedtuple | str | None

If timestamp==True, returns a tuple (str, int, int, float) indicating the first button clicked and its timestamp (or (None, None, None, None) if no acceptable button was clicked between min_wait and max_wait). If timestamp==False, returns a tuple (str, int, int) indicating the first button clicked (or (None, None, None) if no acceptable key was clicked).

wait_one_press(max_wait=inf, min_wait=0.0, live_keys=None, timestamp=True, relative_to=None)[source]

Returns only the first button pressed after min_wait.

Parameters:
max_waitfloat

Duration after which control is returned if no key is pressed.

min_waitfloat

Duration for which to ignore keypresses (force-quit keys will still be checked at the end of the wait).

live_keyslist | None

List of strings indicating acceptable keys or buttons. Other data types are cast as strings, so a list of ints will also work. None accepts all keypresses.

timestampbool

Whether the keypress should be timestamped. If True, returns the button press time relative to the value given in relative_to.

relative_toNone | float

A time relative to which timestamping is done. Ignored if timestamp==False. If None, timestamps are relative to the time wait_one_press was called.

Returns:
pressedtuple | str | None

If timestamp==True, returns a tuple (str, float) indicating the first key pressed and its timestamp (or (None, None) if no acceptable key was pressed between min_wait and max_wait). If timestamp==False, returns a string indicating the first key pressed (or None if no acceptable key was pressed).

wait_secs(secs)[source]

Wait a specified number of seconds.

Parameters:
secsfloat

Number of seconds to wait.

wait_until(timestamp)[source]

Wait until the given time is reached.

Parameters:
timestampfloat

A time to wait until, evaluated against the experiment master clock.

Returns:
remaining_timefloat

The difference between timestamp and the time wait_until was called.

Notes

Unlike wait_secs, there is no guarantee of precise timing with this function. It is the responsibility of the user to do choose a reasonable timestamp (or equivalently, do a reasonably small amount of processing prior to calling wait_until).

property window

Pyglet visual window handle.

write_data_line(event_type, value=None, timestamp=None)[source]

Add a line of data to the output CSV.

Parameters:
event_typestr

Type of event (e.g., keypress, screen flip, etc.)

valueNone | str

Anything that can be cast to a string is okay here.

timestampfloat | None

The timestamp when the event occurred. If None, will use the time the data line was written from the master clock.

Notes

Writing a data line does not cause the file to be flushed.

Examples using expyfun.ExperimentController

Run a very basic experiment

Run a very basic experiment

Run a simple experiment

Run a simple experiment

Experiment drawing methods

Experiment drawing methods

Sound level test and visual size calibration

Sound level test and visual size calibration

Experiment using eye-tracking pupillometry

Experiment using eye-tracking pupillometry

ProgressBar demo

ProgressBar demo

Display text with different formatting methods

Display text with different formatting methods

KeyPressAndRelease demo

KeyPressAndRelease demo

Adaptive tracking for two trial types and tracker reconstruction from .tab

Adaptive tracking for two trial types and tracker reconstruction from .tab

Experiment with eye-tracking

Experiment with eye-tracking

Use joystick controls

Use joystick controls

Mouse click demo

Mouse click demo

Keypress demo

Keypress demo

Video playing made simple

Video playing made simple

Use the CRM corpus

Use the CRM corpus

Examine and manipulate stimulus power

Examine and manipulate stimulus power

Video property control

Video property control

Audio sample rate test

Audio sample rate test

A-V sync test

A-V sync test