function Showtime
% Showtime.mex (formely called "QT.mex") creates and shows QuickTime movies. 
% Each call corresponds quite closely to a QuickTime function. If you don't 
% already have it, you can download the latest version of QuickTime from Apple's web site:
% web http://www.apple.com/quicktime/download/ ;
% 
% Apple provides lots of QuickTime documentation (too much!):
% web http://developer.apple.com/techpubs/quicktime/qtdevdocs/RM/rmFuncsIndex.htm ;
% 
% The quickest way to get the hang of using Showtime.mex is probably to run ShowtimeDemo.m,
% and then read its code. 
% 
% ¥ Create a QuickTime movie:
% movie=Showtime('MovieCreate',filename,window)
% Showtime('VideoTrackCreate',movie,rows,columns,timescale,preload)
% Showtime('VideoMediaCreate',movie)
% Showtime('VideoMediaGraphicsModeSet',movie,graphicsMode,r,g,b)
% Showtime('VideoMediaSamplesAdd',movie,imageArray,pixelSize,frameDuration,isRGB)
% Showtime('VideoMediaSave',movie)
% Showtime('VideoTrackSamplesSet',movie,startInTrack,startInMedia,durationInMedia,mediaRate)
% Showtime('VideoTrackSave',movie)
% Showtime('MovieUserDataAdd',movie,annotation,OSType)
% Showtime('MovieSave',movie)
% 
% ¥ Show a QuickTime movie:
% movie=Showtime('GetFromFile',filename)
% error=Showtime('LoadIntoRam',movie)
% oldHz=Showtime('Rate',movie,[hz])
% oldMagnification=Showtime('Scale',movie,[magnification])
% oldWindow=Showtime('Window',movie,[window])
% Showtime('Fill',movie,[color],[rect])
% Showtime('Show',movie)
% Showtime('Dispose',movie)
% frame=Showtime('MovieFrameDisplay',movie,[frame,isRelative])
% 
% ¥ Add sound:
% movie=Showtime('Sound',array,[hz])
% Showtime('Add',movie,movie2)
% 
% ¥ Open a window:
% [windowPtr,rect]=Showtime('OpenWindow',screenNumber,[color],[rect]);
% Showtime('CloseWindow',windowPtr)
% NOTE:
% If you're also using Screen, then use Screen (not Showtime) to open and close
% all windows. Screen maintains an internal list of its windows, and won't
% always accept windows made by Showtime, whereas Showtime will always be happy to use
% Screen's windows.
% 
% ¥ Set the CLUT:
% clut=Showtime('GetClut',windowPtrOrScreenNumber,[bits]); % Ok.
% Showtime('SetClut',windowOrScreen,clut,[startEntry,bits]); % OBSOLETE. Not recommended.
% LoadClut(windowOrScreen,clut,[startEntry,bits]); % Recommended.
% 
% ¥ Try ShowtimeDemo.m and ShowtimeTest.m.
% 
% HOW TO CONTROL TIMING:
% StŽphane Rainville <fanou101@hotmail.com> writes (7/02), "I was
% concerned with the fact that QuickTime attempts to respect a movie's
% frame rate irrespective of what the monitor's refresh might be. If movie
% and display frame rates don't match, QuickTime uses frame interpolation
% which could potentially mess up stimulus properties. Rather than
% relinquish control of the movie's timing properties to QuickTime, I
% proposed a simple two-punch work-around that uses 1 - ShowTime's ability
% to display any single frame of a QT movie, and 2 - the PsychToolbox's
% well established ability to sync images with the monitor's vertical
% refresh. The heart of the code looks something like
% 	for frame=1:n
% 	  ShowTime('MovieFrameDisplay',movie,frame);
% 	  framesSinceLastWait=SCREEN(window,'WaitBlanking');
% 	end
% "Visually, this seems to work well and is confirmed by
% framesSinceLastWait which never missed a beat during my tests. If the
% 'WaitBlanking' is commented out of the program, the QT movie misses all
% vertical refresh interrupts and screams by in a fraction of second,
% horizontal tear and all. I also did a SCREEN('GetImage') on each frame
% of the movie and that confirmed that movie presentation is lossless
% (i.e. no key frame interpolation). Bottom line, at least for my
% purposes, Showtime seems to be robust both spatially and temporally. The
% main advantage for me at the moment is that QuickTime movies come in a
% single file and load much more quickly than loading an array of
% individual frames stored in separate image files (e.g. TIF)."
% 
% p.s. We've read that QuickTime has polished code for blitting (copying
% quickly to the screen) that may beat QuickDraw's CopyBits, which is what
% Screen 'CopyWindow' uses. This may constitute another advantage of using
% StŽphane's approach to showing movies. It would be interesting to pit
% QuickTime against QuickDraw in this way, ie ShowTime 'MovieFrameDisplay'
% vs Screen 'CopyWindow', and compare their data transfer rates in MB/s.
% 
% NOTE:
% Showtime.mex is distributed in two ways, as part of the Psychtoolbox, and
% on its own. The Psychtoolbox includes several demos that illustrate the use
% of Showtime.mex. You'll need the Psychtoolbox to run those demos. You can 
% download the Psychtoolbox from the website.
% web http://psychtoolbox.org/download.html#mac
% 
% NOTE:
% The "filename" can be just that, eg 'wave.mov', in the current directory, 
% or a partial path relative to the current directory, 'Documents:wave.mov', 
% or a full path, 'HARD_DISK:Documents:wave.mov'. The "filename" string can
% be up to 255 characters long. See Matlab's CD command.
% 
% BUGS:
% None.
% 
% COMPRESSION:
% At present Showtime.mex doesn't use any compression in saving your movie
% to disk. This provides fast faithful playback from today's hard
% disks, which are so fast and cheap ($4/GB). However, to play your
% movie on the web you'll want to compress it severely so that even
% people connecting to the internet by phone can see it.
% 
% You can use Apple's QuickTime Player to compress your movie:
% 0. Upgrade to QuickTime Pro for $30.
%    web http://apple.com/quicktime/download/
% 1. Open your QuickTime movie in QuickTime Player 
% 2. From the File menu select Export 
% 3. From the bottom of the Export dialog, select "Movie to
%    QuickTime Movie" from the drop down list.
% 4. Click the Options button.
% 5. From the "Movie Settings" dialog click Video Settings. 
% 6. From the "Compression Settings" dialog select "Sorenson
%    Video" (or whatever you prefer) as the Compressor.
% 7. Enter your settings. Sorenson suggests setting keyframes every
%    500 frames (i.e. a large value). Keyframes are sent as complete
%    images, independent of what came before; delta frames are
%    transmitted as differences from the previous frame. The Sorenson
%    Video codec assesses the differences between the frames of your
%    movie and automatically inserts keyframes when the difference is
%    large. Apparently even the experts do a lot of trial and error in
%    finding the best settings. Here are some tips:
%    web http://www.terran.com/info/TipsSorenson.html
% 8. Click Ok to dismiss the dialogs and compress and save your new movie.
% 
% According to many sources, to attain the ultimate in compression,
% one should buy Media Cleaner ($499) and the Developer Version of
% Sorenson Video codec ($499). However, the demonstration provided at
% the Sorenson web site, showing the same video compressed in both
% ways, shows a quite modest difference in quality, not enough to
% justify the cost for me. I'm sticking with QuickTime Pro.
% web http://www.s-vision.com/products/SorensonVideo/product/whydev.html
% web http://www.terran.com/products/CleanerOverview.html
% 
% CREDITS:
% Showtime.mex is based on the "Showtime" MathLink extension for Mathematica
% created by A. "Beau" Watson, Cesar Ramirez, and James Hu in the
% summer of 1999. All the routines were merged together here as "Showtime"
% by Denis Pelli. Denis's contributions are in polishing the code
% (removing bugs, adding the videotoolbox GDOpenWindow, and rewriting
% the MediaAdd routine to work at all pixelSizes), and generally
% making the whole library reentrant (state information stored solely
% in the ShowtimeMovie struct, not in the routines) so that the user,
% formerly restricted to using only one movie, is now free to work
% with an unlimited number of movies at once.
% web http://vision.arc.nasa.gov/showtime/
% 
% Denis Pelli						1/00
% 
% 
% DESCRIPTION OF THE FUNCTIONS:
% 
% Showtime('Add',movie,movie2)
% 	Add one movie to another, as a new track. This is mainly for adding
% 	sound.
% 
% Showtime('Dispose',movie);
% 	Dispose of the movie in memory. (ShowtimeMovieSave calls this after
% 	saving to disk.)
% 
% Showtime('Fill',movie,[color],[rect])
% 	Clear the movie's rect in its associated window. If pixelSize>8 then
% 	color is an rgb triplet, or a scalar that we replicate to make a
% 	triplet. If pixelSize<=8 then color is a scalar.
% 
% description=Showtime('GetCodecNameList')
% 	Get list of available compressors
% 
% description=Showtime('GetImageDescription',movie)
% 	Get image description struct: compressor codec, image size, pixel size, etc.
% 
% movie=Showtime('GetFromFile',filename);
% 	Get movie from file.
% 
% error=Showtime('LoadIntoRam',movie)
% 	Ask QuickTime to load the movie into memory, for seamless play.
% 	dgp. Is this request permanently recorded in the movie, if the movie is
% 	subsequently saved?
% 
% movie=Showtime('MovieCreate',filename,window);
% 	Create QuickTime movie.
% 	Overwrite any preexisting file with the same name.
% 
% int ShowtimeMovieFrameCount(ShowtimeMovie qtMovie){
% 	Counts the number of Visual frames and returns that number.
% 
% int ShowtimeMovieFrameDisplay(ShowtimeMovie qtMovie, int iFrame, int isRelative)
% 	Displays a single movie frame.  Specify frame to display by either
% 	absolute or relative reference. Absolute reference is relative to
% 	begining of movie, and so 1 is the first frame, 2 is the second, and so
% 	on.  Also for absolute, -1 is the last frame, -2 second to last, and so
% 	on. For relative references, positive frame values move that many frames
% 	in the forward direction, negative values move backwards, and 0 simply
% 	refreshes the current frame. Returns the frame number displayed from 1
% 	to number of frames in movie. "isRelative" is boolean. Nonzero for true;
% 	zero for false.
% 	Note: attempting to go beyond the last frame or before the first frame,
% 	using either referencing type, the last or first frame will be displayed
% 	respectively.
% 
% Showtime('MovieSave',movie);
% 	Save movie--when finished editing
% 
% Showtime('MovieUserDataAdd',movie,annotation,OSType)
% 	Add user data annotations
% 
% window=Showtime('OpenWindow',screenNumber,[color],[rect])
% 	Open a window. Usually occupies an entire screen.
% 	Open an onscreen window. Specify a screen by a screenNumber (0 is the
% 	main screen, with menu bar). "color" is the clut index (scalar or [r g
% 	b] triplet) that you want to poke into each pixel; default is white. If
% 	supplied, "rect" must contain at least one pixel. "rect" is in screen
% 	coordinates (origin at upper left), and defaults to the whole screen.
% 	(Subsequent references to this new window will use its local
% 	coordinates: origin at its upper left.) Opening or closing a window
% 	takes about a second.
% 	¥ Showtime's windows are known only to Showtime and must be closed by
% 	it, eg Showtime('Close',w). Matlab knows nothing about Showtime's
% 	windows, so the Matlab CLOSE command won't work on Showtime's windows.
% 	¥ While Showtime has onscreen windows open, it disables any
% 	AfterDark-compatible screen saver (e.g. Sleeper) to prevent interference
% 	with your experiment, and pretends to be a sleeping screen saver (by
% 	setting the Gestalt SAVR Selector "enabled" and "asleep" bits) to cause
% 	hiding of system-wide floating windows (e.g. Drop Drawers).
% 	web http://www.stclairsoft.com/Sleeper/ ;
% 	web http://www.sigsoftware.com/dropdrawers/ ;
% 	¥ The handling of the "color" argument may seem arcane. It might seem
% 	simpler to allow the user to specify the background color as an RGB,
% 	which would then be independent of pixelSize. However, it's vital to
% 	recall that here we're specifying only the background, and that the rest
% 	of the image will be specified as pixel values. The overriding concern
% 	was that the color argument be specified and treated in the same way as
% 	the rest of the pixels. dgp 11/99
% 
% Showtime('CloseWindow',window)
% 	Clean up after ShowtimeOpenWindow (or ShowtimeOpenOffscreenWindow, if we
% 	later add that function).
% 
% oldHz=Showtime('Rate',movie,[hz]);
% 	Set rate for movie play. "hz" can be a number or one of the strings
% 	'screenRate' or 'normalRate'.
% 
% rect=Showtime('Rect',movie,[track])
% 	Get rect of movie. If iTrack is 0, uses first video track.
% 
% oldMagnification=Showtime('Scale',movie,[magnification])
% 	Set magnification.
% 
% error=Showtime('SetClut',windowOrScreen,clut,[startEntry],[bits]);
% 	Set clut in specified window or screen. (Completely independent of
% 	movies and QuickTime.) OBSOLETE. This is equivalent to Screen 'SetClut'.
% 	Both Showtime and Screen 'SetClut' have been superceded by the new
% 	Psychtoolbox function LoadClut.m. Use that instead.
% 	
% clut=Showtime('GetClut',windowOrScreen,[bits]);
% 	Get clut in specified window or screen. (Completely independent of
% 	movies and QuickTime.) Get the color lookup table (CLUT) of a video
% 	screen. The returned "clut" is a 3-column matrix with one row per RGB
% 	entry in the hardware CLUT. The "clut" values will be in the range 0 to
% 	255 for an 8-bit CLUT. The "bits" argument specifies how many bits you
% 	want to read from the CLUT. Typically it will be 8, which is the default
% 	value.
% 	¥ Note that if you call SetClut and then GetClut, what you get back from
% 	GetClut may differ from what you supplied to SetClut:
% 	1. For user convenience, 'SetClut' only sets the top n-bits of the
% 	16-bit word of each entry in the colorSpec table that it passes to the
% 	video driver. ('SetClut' left-justifies the user's n-bit values in the
% 	16-bit word.) Typically n is 8, but you could specify 16 (i.e. no
% 	shift).
% 	2. The video driver transforms the colorSpec entries by the gamma table
% 	before loading them into the video card's hardware CLUT. (OpenWindow
% 	loads an identity-transform gamma table, but with some
% 	more-than-8-bit-dac video cards you may want to use 'Gamma' to set your
% 	own custom gamma table.)
% 	3. GetClut reads the raw 16-bit values directly from the hardware clut,
% 	as returned by the video driver call cscGetEntries. No attempt is made
% 	to undo the effect of the gamma table. For user convenience, the data
% 	are shifted right, to right-justify the n-bit values. Again, n is
% 	typically 8, but you could specify 16 (i.e. no shift).
% 	4. The hardware clut retains less than 16 bits per entry, and the video
% 	driver may fail to return all the bits stored by the hardware, returning
% 	only 8 bits per entry.
% 
% ShowtimeScreenRect(int iScreenNumber, Rect *rect)
% 	Gets screen dimensions & position:
% 
% Showtime('Show',movie)
% 	Show the movie!
% 
% movie=Showtime('Sound',array,[hz])
% 	Create a movie containing a sound specified by an array of samples.
% 
% Showtime('VideoMediaCreate',movie)
% 	Create a new media for current track.
% 
% Showtime('VideoMediaGraphicsModeSet',movie,graphicsMode,r,g,b)
% 	Set graphics mode, e.g. XOR or dither. (Probably only very rarely of
% 	interest.) This may be optionally called right after adding any media
% 	with ShowtimeVideoMediaSamplesAdd to set graphics mode for a particular
% 	media sample (frame(s) data).
% 
% Showtime('VideoMediaSamplesAdd',movie,imageArray,pixelSize,frameDuration,isRGB)
% 	Add video media samples (i.e. frames) to movie.
% 	ShowtimeVideoMediaSamplesAdd adds one or more frames ("samples") to
% 	a movie.  The data received is expected to be a pixmap with the
% 	specified pixel size. (The glue routines in Showtime_ML.c and
% 	Showtime_MEX.c pack your Mathematica or Matlab data into the
% 	pixmap.) ShowtimeVideoMediaSamplesAdd will read in qtSample->frames
% 	frames that are qtSample->rows high by qtSample->cols wide.  (To
% 	minimize their own need for buffer space, the glue routines may
% 	break up a multiframe request into multiple one-frame requests.)
% 
% Showtime('VideoMediaSave',movie)
% 	Save the media.  When finished adding samples.
% 
% Showtime('VideoTrackCreate',movie,rows,columns,timescale,preload)
% 	Create new video track.
% 
% Showtime('VideoTrackSamplesSet',movie,iStartInTrack,iStartInMedia,iDurationInMedia,iMediaRate)
% 	Specify how video media samples (frame(s) data) should be arranged
% 	in video track.
% 
% Showtime('VideoTrackSave',movie)
% 	Save track. When done editing track. (Does nothing.)
% 
% oldWindow=Showtime('Window',movie,[window])
% 	Designate the window in which the movie will play.


% 7/28/00 dgp Added NOTE above suggesting that users may prefer to use Screen,
%             not Showtime, to open and close their windows. (Thanks to Michael S. Beauchamp
%             for alerting us to the problem.)
% 4/4/02  dgp Renamed from "QT.mex" to "Showtime.mex" at the request of A.B.Watson.
% 7/9/02  dgp Added synopses at end, above, copied from Showtime.c.
