1 // Wrapper Library for OpenAL
2 // Author: M.D.Snellgrove
3 // Date: 17/3/2002
4 // History:
5
6 // Changes by M Snellgrove 26/7/2003
7 // Conditional Compilation using OpenAL
8
9 // Changes by Judebert 1/8/2003
10 // Portability fix for WIN32 systems
11
12 // Changes by M Snellgrove 5/8/2003
13 // Code cleanup
14
15 #include "sampleio.h"
16
17 // Empty Noaudio sound routines
18 #if AP_AUDIO==AUDIO_NOAUDIO
19
sampleio()20 sampleio :: sampleio(){}
init(int,char[][255],int,int)21 void sampleio :: init(int, char [][255], int, int){}
close()22 void sampleio :: close(){}
update()23 void sampleio :: update(){}
channel(int,int)24 void sampleio :: channel(int, int){}
loop(int,int)25 void sampleio :: loop(int, int){}
play(int)26 void sampleio :: play(int){}
stop(int)27 void sampleio :: stop(int){}
psource(int,int,bool)28 void sampleio :: psource(int, int, bool){}
volume(int,double)29 void sampleio :: volume(int, double){}
sourceisplaying(ALuint)30 ALboolean sampleio :: sourceisplaying(ALuint){return false;}
31
32 #endif
33
34 // OpenAL sound routines
35 #if AP_AUDIO==AUDIO_OPENAL
36
37 // Constructor
38
sampleio()39 sampleio :: sampleio(){
40
41 initdone = false;
42
43 }
44
45 // Initialize OpenAL
46
init(int nsamples,char filenames[][255],int nsources,int npool)47 void sampleio :: init(int nsamples, char filenames[][255], int nsources,
48 int npool){
49 if (initdone){
50 cerr << "sampleio: call to init when already in use" << endl;
51 exit(1);
52 }
53
54 initdone = true;
55 numsamples = nsamples;
56 numsources = nsources;
57 numpool = npool;
58 samples = new ALuint[numsamples];
59 sources = new ALuint[numsources+numpool];
60 poolcount = numsources;
61
62 // Initialize audio device
63 alutInit(0, NULL);
64
65 ALfloat zeroes[] = { 0.0f, 0.0f, 0.0f };
66 ALfloat back[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
67 ALfloat front[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f };
68 ALfloat position[] = { 0.0f, 0.0f, -4.0f };
69 ALsizei filelen;
70
71 // Setup Listener
72 alListenerfv(AL_POSITION, zeroes );
73 alListenerfv(AL_VELOCITY, zeroes );
74 alListenerfv(AL_ORIENTATION, front );
75
76 // Load in samples
77 ALvoid* data;
78 alGenBuffers(numsamples, samples);
79
80 for (int i = 0; i < numsamples; i++){
81 ALfloat freq;
82 ALboolean fileok;
83 // Evil OpenAL portability fix done here
84 ALenum format;
85 data = alutLoadMemoryFromFile(filenames[i], &format, &filelen, &freq);
86 if (!data){
87 cerr << "sampleio: could not open " << filenames[i] << endl;
88 exit(1);
89 }
90 alBufferData(samples[i], format, data, filelen, freq);
91 free(data);
92 }
93
94 // Generate Sources
95 alGenSources(numsources+numpool, sources);
96
97 for(int j=0;j<numsources+numpool;j++){
98 alSourcefv(sources[j], AL_POSITION, position );
99 alSourcefv(sources[j], AL_VELOCITY, zeroes );
100 alSourcefv(sources[j], AL_ORIENTATION, back );
101 }
102
103 }
104
105 // Clearup routine
106
close()107 void sampleio :: close(){
108
109 if (initdone){
110 delete [] samples;
111 delete [] sources;
112 initdone = false;
113 alutExit();
114 }
115
116 }
117
118 // Update method (blank)
119
update()120 void sampleio :: update(){
121
122 }
123
124 // Play a channel
125
channel(int chan,int sample)126 void sampleio :: channel(int chan, int sample){
127 if (!initdone){
128 cerr << "sampleio: initialize before use" << endl;
129 return;
130 }
131 if ((chan < 0) || (chan >= numsources)){
132 cerr << "sampleio: attempt to play nonexistant source " << chan
133 << endl;
134 return;
135 }
136 if ((sample < 0) || (sample >= numsamples)){
137 cerr << "sampleio: attempt to play nonexistant sample " << sample
138 << endl;
139 return;
140 }
141
142 psource(chan, sample, false);
143 }
144
145 // Loop a sample
146
loop(int chan,int sample)147 void sampleio :: loop(int chan, int sample){
148
149 if (!initdone){
150 cerr << "sampleio: initialize before use" << endl;
151 return;
152 }
153 if ((chan < 0) || (chan >= numsources)){
154 cerr << "sampleio: attempt to play nonexistant source " << chan
155 << endl;
156 return;
157 }
158 if ((sample < 0) || (sample >= numsamples)){
159 cerr << "sampleio: attempt to play nonexistant sample " << sample
160 << endl;
161 return;
162 }
163 psource(chan, sample, true);
164
165 }
166
167 // Play a sample
168
play(int sample)169 void sampleio :: play(int sample){
170
171 if (!initdone){
172 cerr << "sampleio: initialize before use" << endl;
173 return;
174 }
175 if (numpool == 0){
176 cerr << "sampleio: attempt to play nonexistant pool " << endl;
177 return;
178 }
179 if ((sample < 0) || (sample >= numsamples)){
180 cerr << "sampleio: attempt to play nonexistant sample " << sample
181 << endl;
182 return;
183 }
184 poolcount++;
185 if (poolcount == numsources + numpool) poolcount = numsources;
186 psource(poolcount, sample, false);
187
188 }
189
190 // Stop current sample
191
stop(int i)192 void sampleio :: stop(int i){
193
194 if (!initdone){
195 cerr << "sampleio: initialize before use" << endl;
196 return;
197 }
198 if ((i < 0) || (i >= numsources)){
199 cerr << "sampleio: attempt to stop nonexistant source " << i
200 << endl;
201 return;
202 }
203 if (sourceisplaying(sources[i])){
204 alSourceStop(sources[i]);
205 }
206
207 }
208
209 // Actaully start a sample
210
psource(int i,int sample,bool loop)211 void sampleio :: psource(int i, int sample, bool loop){
212
213 // Stop current sample
214 if (sourceisplaying(sources[i])){
215 alSourceStop(sources[i]);
216 }
217
218 // Change to new sample
219 alSourcei(sources[i], AL_BUFFER, samples[sample]);
220 if (loop){
221 alSourcei(sources[i], AL_LOOPING, AL_TRUE);
222 }else{
223 alSourcei(sources[i], AL_LOOPING, AL_FALSE);
224 }
225
226 // Play new sample
227 alSourcePlay(sources[i]);
228
229 }
230
231 // Volume control function
232
volume(int i,double vol)233 void sampleio :: volume(int i, double vol){
234
235 if (!initdone){
236 cerr << "sampleio: initialize before use" << endl;
237 return;
238 }
239 if ((i < 0) || (i >= numsources)){
240 cerr << "sampleio: attempt to volume nonexistant source " << i
241 << endl;
242 return;
243 }
244 ALfloat volf = ALfloat(vol);
245 alSourcef(sources[i], AL_GAIN, volf);
246
247 }
248
249 // Check on playing sources function
250
sourceisplaying(ALuint sid)251 ALboolean sampleio :: sourceisplaying(ALuint sid) {
252
253 ALint state;
254 if(alIsSource(sid) == AL_FALSE){
255 return AL_FALSE;
256 }
257 state = AL_INITIAL;
258
259 // Evil OpenAL portability fix done here
260 #ifdef _WIN32
261 alGetSourcei(sid, AL_SOURCE_STATE, &state);
262 #else
263 alGetSourceiv(sid, AL_SOURCE_STATE, &state);
264 #endif
265
266 switch(state) {
267 case AL_PLAYING: case AL_PAUSED:
268 return AL_TRUE;
269 default:
270 break;
271 }
272 return AL_FALSE;
273
274 }
275
276 #endif
277