This file is indexed.

/usr/share/psychtoolbox-3/PsychDemos/ContrastModulatedNoiseTheElegantStyleDemo.m is in psychtoolbox-3-common 3.0.14.20170103+git6-g605ff5c.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
function ContrastModulatedNoiseTheElegantStyleDemo(noisesize, staticnoise)
% ContrastModulatedNoiseTheElegantStyleDemo([noisesize=512] [, staticnoise=0])
%
% This demo shows how to render contrast modulated noise efficiently on
% current state of the art graphics hardware by use of the Psychtoolbox
% imaging pipeline and high precision framebuffers.
%
% A rectangular image with random noise of size
% 'noisesize' by 'noisesize' pixels is created, then drawn to the display.
%
% We use alpha-blending tricks to modulate the contrast of the noise in
% realtime. In this demo you can move the mouse pointer to drag around a
% "modulation disk" of 50 pixels diameter. Noise inside the disk has a
% different contrast 'fgcontrast' from the rest of the image, which has a
% contrast of 'bgcontrast' (see top of code for fgcontrast and bgcontrast).
%
% You can press the cursor left and cursor right keys to decrement or
% increment the contrast inside the disk in steps of 0.01 units. Press
% cursor up key to set the inside disk contrast equal to outside disk
% contrast. Press ESCAPE key to finish the demo.
%
% The optional 'staticnoise' flag - if set to 1 - will render a static
% noise image instead of one that changes at each frame. That's faster
% because one doesn't need to recreate the noise texture each frame.
%
% How this works? Basically we use standard Screen 2D drawing commands to
% draw a "contrast values weight map" into the alpha-channel, so the
% alpha-channel encodes contrast values between 0.0 and 1.0.
% Then we draw a noise texture of fixed contrast into the framebuffer
% and the alpha-blending hardware takes care of modulating the
% contrast of the drawn noise texture with the values from the
% alpha-channel.
%
% Hardware requirements: ATI Radeon X-1000 or later, NVidia Geforce 6000 or
% later. Recommended is Radeon HD2000/3000/... or Geforce-8000/9000/...
% hardware for maximum fun!
%
% The allowable contrast values for standard 2D drawing commands are
% limited to the range 0.0 to 1.0 on MacOS/X, they are not limited on
% MS-Windows or GNU/Linux. Precision is set to 16bpc float, ie. about 3
% digits behind the decimal point or 1024 discriminable levels. On the most
% recent ATI HD-2000 and NVidia Geforce 8000 hardware one can lift this limit
% to 32bpc float -- 6.5 digits or about 8 million discriminable levels by a
% one-line code change in this script ;-)

% History:
% 5.9.2007 Written (MK).

% Running on PTB-3?
AssertOpenGL;

if nargin < 1
    noisesize = [];
end

if isempty(noisesize)
    noisesize = 512;
end

if nargin < 2
    staticnoise = [];
end

if isempty(staticnoise)
    staticnoise = 0;
end

bgcontrast = 0.2;
fgcontrast = 0.4;

% Assign control keys: Cursor Left and Right for increasing/decreasing
% contrast of the noise:
KbName('UnifyKeyNames');
leftArrow = KbName('LeftArrow');
rightArrow = KbName('RightArrow');
upArrow = KbName('UpArrow');
escape = KbName('ESCAPE');

% Open onscreen window on screen with maximum id:
screenid=max(Screen('Screens'));

try
    % Open onscreen window: We request a 32 bit per color component
    % floating point framebuffer if it supports alpha-blendig. Otherwise
    % the system shall fall back to a 16 bit per color component
    % framebuffer:
    PsychImaging('PrepareConfiguration');
    PsychImaging('AddTask', 'General', 'FloatingPoint32BitIfPossible');
    [win, winRect] = PsychImaging('OpenWindow', screenid);

    % We use a normalized color range from now on. All color values are
    % specified as numbers between 0.0 and 1.0, instead of the usual 0 to
    % 255 range. This is more intuitive:
    Screen('ColorRange', win, 1, 0);
    
    % Fill the whole onscreen window with a neutral 50% intensity
    % background color and an alpha channel value of 'bgcontrast'.
    % This becomes the clear color. After each Screen('Flip'), the
    % backbuffer will be cleared to this neutral 50% intensity gray
    % and a default 'bgcontrast' background noise contrast level:
    Screen('FillRect', win, [0.5 0.5 0.5 bgcontrast]);
    
    i=0;
    tonset = [];

    % Create first noisematrix outside loop:
    noisematrix = randn(noisesize);
    
    % Initially place the mouse cursor at the center of the window:
    [x, y] = RectCenter(winRect);
    SetMouse(x, y, win);
    HideCursor;
    
    % Initially sync us to retrace:
    Screen('Flip', win);
    
    % Main stimulus drawing loop:
    while 1
        % Increment framecounter:
        i=i+1;
        
        % If staticnoise is set to 1 then we only generate the noise
        % texture once -- This way we can disentangle "noise creation
        % overhead" from actual drawing overhead:
        if i==1 || staticnoise == 0
            % Convert Matlab 'noisematrix' to 16 bpc floating point noise texture:
            noisetex = Screen('MakeTexture', win, noisematrix, [], [], 1);
        end
        
        % Disable alpha-blending, so we can just overwrite the framebuffer
        % with our new pixels:
        Screen('Blendfunction', win, GL_ONE, GL_ZERO);
        
        % Now we overdraw some regions of the onscreen windows alpha-channel
        % with our "modulation" image - a image that contains alpha values
        % which encode a different contrast 'fgcontrast'. After this drawing op,
        % the alpha-channel will contain the final "contrast modulation landscape":
        Screen('DrawDots', win, [x y], 50, [0.5 0.5 0.5 fgcontrast], [], 1);

        % On some graphics hardware + operating system combos, 'DrawDots'
        % is not able to draw round dots when Screen('ColorRange', win, 1,
        % 1); is used. In such cases, just use 'FillOval' to draw round
        % dots:
        % Screen('FillOval', win, [0.5 0.5 0.5 fgcontrast], OffsetRect([0 0 50 50], x-25, y-25));

        % Now we draw the noise texture and use alpha-blending of
        % the drawn noise color pixels with the destination alpha-channel,
        % thereby multiplying the incoming color values with the stored
        % alpha values -- effectively a contrast modulation. The GL_ONE
        % means that we add the final contrast modulated noise pixels to
        % the current content of the window == the neutral gray background.
        Screen('Blendfunction', win, GL_DST_ALPHA, GL_ONE);
        
        % The extra zero at the end forcefully disables bilinear filtering. This is
        % not strictly neccessary on correctly working hardware, but an extra
        % precaution to make sure that the noise values are blitted
        % one-to-one into the offscreen window:
        Screen('DrawTexture', win, noisetex, [], [], [], 0);
            
        % At this point, the final image should be ready in the backbuffer
        % of our onscreen window. Ready to flip it onscreen...
        
        % Cleanup: Release our noise texture in the dynamic-noise case were
        % we recreate one for each drawn frame:
        if ~staticnoise
            Screen('Close', noisetex);
        end

        % Tell PTB that all drawing commands are done now. This allows
        % the graphics hardware to perform all drawing and image processing
        % in parallel while we execute Matlab code for non-graphics related
        % stuff, in our case random noise creation, keyboard and mouse
        % queries:
        Screen('DrawingFinished', win);
                
        % Now all the non-Screen() stuff:
        if ~staticnoise
            % Generate a noisesize x noisesize matrix of random noise with mean zero,
            % stddev 1.0 for use in the next loop iteration:
            noisematrix = randn(noisesize);
        end
        
        % Keyboard queries:
        [isdown secs keycode] = KbCheck;
        if isdown
            if keycode(escape)
                break;
            end
            
            if keycode(leftArrow)
                fgcontrast = max(0, fgcontrast - 0.01);
            end
            
            if keycode(rightArrow)
                fgcontrast = min(1, fgcontrast + 0.01);
            end
            
            if keycode(upArrow)
                fgcontrast = bgcontrast;
            end
        end

        % Query mouse position: This will be the center of our "modulation disk":
        [x, y] = GetMouse(win);

        % Ready. Request stimulus onset:
        tonset(i) = Screen('Flip', win);

        % Ready. Next loop iteration:
    end

    % One final flip:
    Screen('Flip', win);

    % Done. Close screen and finish:
    ShowCursor;
    sca;
    
    % Compute avg. computation time for redraw:
    avgredrawtime = mean(diff(tonset)) * 1000
    %plot(diff(tonset));
    
    % Done.
    return;
catch
    % Error. Close screen, show cursor, rethrow error:
    ShowCursor;
    sca;
    psychrethrow(psychlasterror);
end