1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
/*
* Psychtoolbox3/Source/Common/SCREENNominalFrameRate.c
*
* AUTHORS:
*
* Allen.Ingling@nyu.edu awi
* mario.kleiner.de@gmail.com mk
*
* PLATFORMS:
*
* All systems.
*
* HISTORY:
*
* 12/04/02 awi Created.
* 06/07/06 mk Extended to return float precision values on request.
* Extended to allow setting the framerate on systems that
* support this (Currently Linux only).
*
* DESCRIPTION:
*
* Return the the nominal frame rate as reported by the video subsystem/driver, or
* change the nominal frame rate on systems that support this.
*/
#include "Screen.h"
// If you change useString then also change the corresponding synopsis string in ScreenSynopsis.c
static char useString[] = "hz=Screen('NominalFrameRate', windowPtrOrScreenNumber [, mode] [, reqFrameRate]);";
// 1 1 2 3
static char synopsisString[] =
"Returns or sets the nominal video frame rate in Hz, as reported by your computer's video driver. "
"'FrameRate' is an alias for 'NominalFrameRate'. By default, this function returns the nominal "
"framerate, as reported by your operating system, rounded to the closest integral value. If you "
"set the optional 'mode' flag to 1, then the framerate is returned without rounding to the closest "
"integer, but at floating point precision, on systems that support this (MacOS-X and Linux). "
"GNU/Linux only: If you set the 'mode' flag to 2 and specify 'reqFrameRate', then Psychtoolbox "
"will try to change the current video refresh rate of the display: If 'reqFrameRate' is above "
"10.0, Screen will try to switch to a framerate as close as possible to 'reqFrameRate' Hz. If "
"'reqFrameRate' is a positive or negative value smaller than 10.0, then the video setting will be "
"changed by 'reqFrameRate' system dependent units. The new settings that would result are validated "
"to make sure they are safe for your display. Invalid settings are rejected, returning a value of "
"-1. On systems other than Linux, 0 is always returned to signal failure. On successfull framerate "
"change, the new resulting nominal framerate is returned with double precision. NOTE: 'reqFrameRate' "
"must be pretty close to the initial framerate, e.g. initial +/- 2 Hz. It is not possible to apply big "
"changes, e.g., from 60 Hz to 75 Hz. This function is meant for fine-tuning the video refresh interval "
"for the purpose of synchronizing different displays or the display and other stimulation- or acquisition "
"devices. You can compensate for small phase-shifts or deviations... "
"Due to manufacturing tolerances and other noise in your system, the real monitor refresh interval can "
"differ slightly from the nominal values returned by this function. To query the real, measured framerate "
"use Screen('GetFlipInterval') instead. ";
static char seeAlsoString[] = "FrameRate GetFlipInterval";
PsychError SCREENNominalFramerate(void)
{
PsychWindowRecordType *windowRecord;
int screenNumber, opmode;
double *rate;
double requestedHz;
//all sub functions should have these two lines
PsychPushHelp(useString, synopsisString, seeAlsoString);
if (PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none);};
//check to see if the user supplied superfluous arguments
PsychErrorExit(PsychCapNumOutputArgs(1));
PsychErrorExit(PsychCapNumInputArgs(3));
//get specified screen number and sanity check the number against the number of connected displays.
PsychCopyInScreenNumberArg(kPsychUseDefaultArgPosition, TRUE, &screenNumber);
// Get opmode. Defaults to zero for integral precision query:
opmode = 0;
PsychCopyInIntegerArg(2, FALSE, &opmode);
// Allocate a return matrix.
PsychAllocOutDoubleArg(1, FALSE, &rate);
// Backend override active for external display backend?
if (PsychIsWindowIndexArg(1) &&
PsychAllocInWindowRecordArg(1, TRUE, &windowRecord) &&
(windowRecord->imagingMode & kPsychNeedFinalizedFBOSinks)) {
// Yes: Report "made up" values injected from external backend, instead
// of the ones associated with this windows windowing system screen:
*rate = 1.0 / windowRecord->VideoRefreshInterval;
// Round it to closest integer, if opmode <= 0:
if (opmode <= 0) *rate = (double) ((int) (*rate + 0.5));
return(PsychError_none);
}
// Query mode (0 or 1)?
if (opmode<=1) {
// Query the float precision nominal frame rate and put it into the return value:
*rate=(double) PsychGetNominalFramerate(screenNumber);
}
else {
// Query new requested framerate or mode increment:
PsychCopyInDoubleArg(3, TRUE, &requestedHz);
// Set mode: This is currently only supported on GNU/Linux:
#if PSYCH_SYSTEM == PSYCH_LINUX
// Call the Set-function, it will process and return the new nominal framerate:
*rate=(double) PsychSetNominalFramerate(screenNumber, (float) requestedHz);
#else
// Return 0 to signal the unsupported feature:
*rate = 0;
#endif
}
// Round it to closest integer, if opmode <= 0:
if (opmode <= 0) *rate = (double) ((int) (*rate + 0.5));
// Done.
return(PsychError_none);
}
|