/usr/share/psychtoolbox-3/PsychHardware/BitsPlusToolbox/BitsPlusMovieDemo.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 119 120 121 122 123 124 125 126 127 128 129 | % BitsPlusMovieDemo
%
% BitsPlusMovieDemo displays a counterphase flickering grating, by lookup
% table animation, using the Bits++ box.
%
% Note that you need to precompute the cluts and write them into
% offscreen memory in advance, so that the blits happen fast. In
% this example, each clut goes into its own offscreen window. In
% real applications, we have found that the precomputation is considerably
% faster if we allocate one large offscreen window and put each clut
% into a different rect inside of it.
% 9/20/02 dhb Version created from ClutMovieDemo.
% 10/xx/02 jmh Fixed it up.
% 11/4/02 dhb, jmh Comments, etc.
% 9/20/03 dhb No more calls to BitsPlus mex file.
clear all; close all
% Define screen
whichScreen=max(Screen('Screens'));
% Create a sinusoidal image in a Matlab matrix. The grating is
% scaled between 1 and 255. The creation happens in two steps. First
% create a sinusoidal vector, then replicate this vector to produce a
% sinusoidal image. The replication is done by an outer product. This is
% not the fastest way to do it in Matlab, but it is a little clearer.
nPixels = 256;
cyclesPerImage = 4;
sinVector = 1+(1+sin(2*pi*cyclesPerImage*(1:nPixels)/nPixels))/2*254;
sinImage = ones(nPixels,1)*sinVector;
% Create a set of color lookup tables (cluts) for animating the
% grating. Each clut starts life as a 256 by three matrix. But
% since we write them into the frame buffer to talk to the Bits++
% box, we then create an offscreen window for each clut and write
% it in. This needs to be done in advance so that the blit of
% the lookup table is fast.
%
% The computed set of cluts produces one cycle of counterphase flicker.
% We also create a uniform clut (offClut) to initialize the display.
%
% The variable nCluts determines the number of temporal quantization intervals.
%
% This routine does not do gamma correction -- it's purpose is just
% to show how to interface to the Bits++.
nCluts = 80;
theCluts = zeros(256,3,nCluts);
theContrasts = sin(2*pi*(0:nCluts-1)/nCluts);
fprintf('Computing %g cluts: ',nCluts);
% Open up the a window on the screen & initialize the clut.
% This is done by calling the Screen function of the Psychophysics
% Toolbox. We need to open the onscreen window first, so that
% the offscreen storage allocated subsequently is properly
% matched to the onscreen frame buffer.
[window,screenRect] = Screen(whichScreen,'OpenWindow',128,[],32);
Screen('LoadClut', window, (0:255)'*ones(1,3));
% Generate a clut for the background and use USB interface
% to write it into Bits++.
offClut = ones(256,3)*(2^14-1)/2;
BitsPlusSetClut(window,offClut);
% Magic rect for writing the clut into the frame buffer.
bitsPlusRect = [0 0 524 1];
% Draw grating onto the screen using PsychToolbox.
% We don't see it at this stage becuase we've got
% a uniform clut in the Bits++.
Screen(window,'PutImage',sinImage);
% Loop through, compute clut, push into created offscreen memory.
for i = 1:nCluts
if (rem(i,10) == 0)
fprintf('%g ',i);
end
contrast = theContrasts(i);
lowValDev = (1-contrast)/2;
highValDev = (1+contrast)/2;
clutEntries = round(linspace(lowValDev*(2^14-1),highValDev*(2^14-1),256)');
theCluts(:,:,i) = [clutEntries clutEntries clutEntries];
bitsPlusClutRow(i,:,:) = BitsPlusEncodeClutRow(theCluts(:,:,i)); % converts to 1X524X3
[w(i),temp]=Screen(window,'OpenOffscreenWindow',[],bitsPlusRect);
Screen(w(i),'PutImage',bitsPlusClutRow(i,:,:),temp); % draw value of CLUT into offscreen windows
end
fprintf('. Done.\n');
% Animate the clut. The timing works a little different from
% the way we think about a conventional clut. We want to write
% the clut into the first line of the frame buffer after the raster
% has gone by, so that we don't get half of one clut and half of
% another. The new clut won't latch into the Bits++ until the
% raster goes by the first line of the frame buffer, i.e. at the
% start of the next frame. So the timing sequence is a) wait
% for blanking, b) delay a suitable amount so that the raster
% has gone by the first line, c) write in the new clut. This clut
% then takes effect on the next frame, not the one where we wrote it.
% The parameter rasterDelay below determines what we mean by "suitable
% amount." Also, we need a last call to WaitBlanking at the end of the
% loop so that we don't truncate the last frame.
nCycles=8;
clutCounter = 1;
rasterDelay = 0.003;
s0=0;f0=0;f=0;s=0;rem(1,1);
Screen(window,'WaitBlanking'); WaitSecs(rasterDelay);
[f0,s0]=Screen(window,'PeekBlanking');
for i=1:nCluts*nCycles
Screen('CopyWindow',w(clutCounter),window,bitsPlusRect,bitsPlusRect);
Screen(window,'WaitBlanking'); WaitSecs(rasterDelay);
s(i)=GetSecs;
if (clutCounter == nCluts); clutCounter = 1; else; clutCounter = clutCounter +1; end
end
s=diff(s);
frames1=sum(s)*FrameRate(whichScreen)-length(s);
Screen(window,'WaitBlanking'); WaitSecs(rasterDelay);
[f,s]=Screen(window,'PeekBlanking');
% Write the off clut back in so we end with a uniform field
WaitSecs(1);
f=f-f0;
s=s-s0;
clutsShown=nCluts*nCycles;
% Close the window.
Screen(window,'Close');
% Set the Bits++ clut to linear ramp
BitsPlusBlank(whichScreen);
|