/usr/share/psychtoolbox-3/PsychDemos/AudioTunnel3DDemo.m is in psychtoolbox-3-common 3.0.9+svn2579.dfsg1-1.
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 | function AudioTunnel3DDemo
% AudioTunnel3DDemo -- A very sketchy and raw demo of how to use OpenAL to
% create the illusion of walking through a tunnel which has different sound
% sources attached to it.
%
% You'll need a properly configured multi-speaker system or very good
% head-phones attached to a very good soundcard and a lot of luck and
% goodwill for this to sound good.
%
% OpenAL for Matlab is currently only supported on a subset of platforms,
% so this demo may abort quickly with an error.
%
walkthroughduration = 15;
walkspeed = -6;
zcorridorlength = abs( walkspeed * walkthroughduration );
nsources = 5;
% Establish key mapping: ESCape aborts, Space toggles between auto-
% movement of sound source or user mouse controlled movement:
KbName('UnifyKeynames');
space = KbName('space');
esc = KbName('ESCAPE');
% Initialize OpenAL subsystem at debuglevel 2 with the default output device:
InitializeMatlabOpenAL(2);
% Generate one sound buffer:
buffers = alGenBuffers(nsources);
% Query for errors:
alGetString(alGetError)
% Try to load some impressive sound...
sounddir = [PsychtoolboxRoot 'PsychDemos/SoundFiles/'];
%sounddir = '/Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files/String Ensemble/';
%sounddir = '/Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files/Grand Piano/';
soundfiles = dir([sounddir '*.wav']);
% Velocity of listener: Walks straight down the z-axis:
alListenerfv(AL.VELOCITY, [0, 0, walkspeed]);
% Start position of listener is at the beginning of the corridor:
startpos = - 1.5 * zcorridorlength;
if walkspeed < 0
startpos = -startpos;
end
alListenerfv(AL.POSITION, [0, 0, startpos]);
if IsOSX
alcASASetListener(ALC.ASA_REVERB_ON, 1);
alcASASetListener(ALC.ASA_REVERB_QUALITY, ALC.ASA_REVERB_QUALITY_Max);
alcASASetListener(ALC.ASA_REVERB_ROOM_TYPE, ALC.ASA_REVERB_ROOM_TYPE_Cathedral);
end
% Create a sound source:
sources = alGenSources(nsources);
perm = randperm(nsources);
for i=1:nsources
% Assign next soundfilename round-robin:
soundname = [sounddir soundfiles(mod(perm(i), length(soundfiles))+1).name];
% Load it...
[mynoise freq]= wavread(soundname);
% Convert it...
mynoise = int16(mynoise * 32767);
% Fill our sound buffer with the data from the sound vector. Tell AL that its
% a 16 bpc, mono format, with length(mynoise)*2 bytes total, to be played at
% a sampling rate of freq Hz. The AL will resample this to the native device
% sampling rate and format at buffer load time.
alBufferData( buffers(i), AL.FORMAT_MONO16, mynoise, length(mynoise)*2, freq);
% Attach our buffer to it: The source will play the buffers sound data.
alSourceQueueBuffers(sources(i), 1, buffers(i));
% Switch source to looping playback: It will repeat playing the buffer until
% its stopped.
alSourcei(sources(i), AL.LOOPING, AL.TRUE);
% Set emission volume to 100%, aka a gain of 1.0:
alSourcef(sources(i), AL.GAIN, 1);
alSourcef(sources(i), AL.CONE_INNER_ANGLE, 30);
alSourcef(sources(i), AL.CONE_OUTER_ANGLE, 270);
alSource3f(sources(i), AL.DIRECTION, 0, 0, 1);
% Set position: Nicely lined up in z direction, but randomly placed in
% x,y direction within a range of +/- 5 meters:
% theta = rand * 2 * pi;
% x = cos(theta) * 2;
% y = sin(theta) * 2;
y = 0;
x = mod(i,2) * 8 - 4;
% nsources, equally spaced along a sound corridor of zcorridorlength
% meters, the first one at z == 0.
z = (i-1) * (zcorridorlength / nsources);
alSource3f(sources(i), AL.POSITION, x, y, z);
% Sources themselves remain static in space:
alSource3f(sources(i), AL.VELOCITY, 0, 0, 0);
if IsOSX
% Source emits some sound that gets reverbrated in room:
alcASASetSource(ALC.ASA_REVERB_SEND_LEVEL, sources(i), 0.5);
end
end
% Start playback for these sources:
alSourcePlayv(nsources, sources);
% 3D sound animation loop. Runs until ESCape key press:
manual = 0;
tstart = GetSecs;
zposition = startpos;
while 1
% Check keyboard:
[isdown dummy, keycode]=KbCheck;
if isdown
if keycode(esc)
break;
end
if keycode(space)
% Toggle between mouse control and automatic:
manual=1-manual;
KbReleaseWait;
end
end
if manual
% Query mouse:
[xm ym]=GetMouse;
walkspeed=(ym-500)/100;
end
t = GetSecs;
telapsed = t - tstart;
tstart = t;
tdistance = telapsed * walkspeed;
zposition = zposition + tdistance;
alListenerfv(AL.POSITION, [0, 0, zposition]);
fprintf('Z=%f\n', zposition);
% Pause for 10 milliseconds in order to yield the cpu to other processes:
WaitSecs(0.01);
end
% Stop playback of all sources:
alSourceStopv(length(sources), sources);
for i=1:nsources
% Unqueue sound buffer:
alSourceUnqueueBuffers(sources(i), 1, buffers(i));
end
% Wait a bit:
WaitSecs(0.1);
% Delete buffer:
alDeleteBuffers(nsources, buffers);
% Wait a bit:
WaitSecs(0.1);
% Delete sources:
alDeleteSources(nsources, sources);
% Wait a bit:
WaitSecs(0.1);
% Shutdown OpenAL:
CloseOpenAL;
% Done. Bye.
return;
|