Fixed makefile.
[bcl.git] / audio.c
blob4239d71163bee9108b7049dd08d1eaf64417319e
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #ifndef _WIN32
5 #include <AL/al.h>
6 #include <AL/alc.h>
7 #include <AL/alure.h>
8 #include <AL/efx.h>
9 #else
10 #include <al.h>
11 #include <efx.h>
12 #include <alc.h>
13 #include <alure.h>
14 #endif
15 #include "bcl.h"
17 typedef struct {
18 char * fileName;
19 ALuint bufId;
20 int count;
21 alureStream * stream;
22 } clip;
24 clip * clips;
25 ALuint * sources;
26 int clipsSize=20;
27 int sourcesSize=20;
28 int numClips;
29 int numSources;
30 int lock;
32 int addClip(clip c) {
33 if (numClips>=clipsSize) {
34 clips = realloc(clips,clipsSize*2*sizeof(clip));
35 clipsSize*=2;
37 clips[numClips] = c;
38 numClips++;
39 return numClips-1;
42 void removeClip(int pos) {
43 for (;pos<numClips-1;pos++)
44 clips[pos]=clips[pos+1];
45 numClips--;
46 if (numClips>20&&numClips <clipsSize/4) {
47 clips = realloc(clips,clipsSize/2*sizeof(clip));
48 clipsSize/=2;
52 int findClipstr(char * name) {
53 int i = 0;
54 for (;i<numClips;i++)
55 if (strcmp(name,clips[i].fileName)==0)
56 return i;
57 return -1;
60 int findClipi(int id) {
61 int i = 0;
62 for (;i<numClips;i++)
63 if (clips[i].bufId==id)
64 return i;
65 return -1;
68 int addSource(ALuint id) {
69 if (numSources>=sourcesSize) {
70 sources = realloc(sources,sizeof(ALuint)*sourcesSize*2);
71 sourcesSize*=2;
73 sources[numSources]=id;
74 numSources++;
75 return numSources -1;
78 void removeSource(int pos) {
79 for (;pos<numSources-1;pos++)
80 sources[pos]=sources[pos+1];
81 numSources--;
82 if (numSources>20&&numSources<sourcesSize/4) {
83 sources = realloc(sources,sizeof(ALuint)*sourcesSize/2);
84 sourcesSize/=2;
88 int findSource(int id) {
89 int i;
90 for (i = 0; i < numSources;i++)
91 if (sources[i]==id)
92 return i;
93 return -1;
96 void sourcecall(void *data, ALuint source) {
99 int timercall(int ms, void * data) {
100 alureUpdate();
101 return ms;
104 int lowpass;
105 TIMER updater;
107 void waitLock() {
108 while (lock==1) {
109 delay(10);
111 lock=1;
114 DECLSPEC void initAudio() {
115 lock=0;
116 waitLock();
117 int attrlist[3];
118 attrlist[0] = ALC_FREQUENCY;
119 attrlist[1] = 44100;
120 attrlist[2] = 0;
121 alureInitDevice(NULL,attrlist);
122 numClips = 0;
123 numSources = 0;
124 clips = malloc(sizeof(clip)*clipsSize);
125 sources = malloc(sizeof(ALuint)*sourcesSize);
126 updater = addTimer(10,timercall,NULL);
127 // filters
128 alGenFilters(1,&lowpass);
129 alFilteri(lowpass,AL_FILTER_TYPE,AL_FILTER_LOWPASS);
130 alFilterf(lowpass,AL_LOWPASS_GAINHF,0.5f);
131 lock = 0;
134 DECLSPEC void terminateAudio() {
135 waitLock();
136 cancelTimer(updater);
137 int i;
138 alDeleteSources(numSources,sources);
139 for (i = 0; i < numClips;i++) {
140 free(clips[i].fileName);
141 if (clips[i].stream==NULL)
142 alDeleteBuffers(1,&clips[i].bufId);
143 else
144 alureDestroyStream(clips[i].stream,4096,&clips[i].bufId);
146 free(clips);
147 free(sources);
148 alDeleteFilters(1,&lowpass);
149 alureShutdownDevice();
150 lock=0;
153 void playsource(int sound,int loop) {
154 int bufid;
155 alGetSourcei(sound, AL_BUFFER, &bufid);
156 int pos = findClipi(bufid);
157 if (pos==-1)
158 return;
159 if (clips[pos].stream==NULL)
160 alSourcePlay(sound);
161 else {
162 alurePlaySourceStream(sound,clips[pos].stream,4,loop,sourcecall,NULL);
166 DECLSPEC int loadSound(char * file) {
167 waitLock();
168 int pos = findClipstr(file);
169 ALuint bufid;
170 if (pos==-1) {
171 bufid = alureCreateBufferFromFile(file);
172 clip c= {strdup(file),bufid,0,NULL};
173 pos = addClip(c);
175 else
176 bufid = clips[pos].bufId;
177 ALuint soundid;
178 alGenSources(1, &soundid);
179 alSourcei(soundid, AL_BUFFER, bufid);
180 addSource(soundid);
181 clips[pos].count++;
182 lock=0;
183 return soundid;
186 DECLSPEC int streamSound(char * file) {
187 waitLock();
188 int pos = findClipstr(file);
189 ALuint bufid;
190 if (pos==-1) {
191 alureStream * s = alureCreateStreamFromFile(file,4096,1,&bufid);
192 clip c= {strdup(file),bufid,0,s};
193 pos = addClip(c);
195 else
196 bufid = clips[pos].bufId;
197 ALuint soundid;
198 alGenSources(1, &soundid);
199 alSourcei(soundid, AL_BUFFER, bufid);
200 addSource(soundid);
201 clips[pos].count++;
202 lock=0;
203 return soundid;
206 DECLSPEC void unloadSound(int sound) {
207 waitLock();
208 if (!alIsSource(sound)) {
209 printf("bcl: Invalid source\n");
210 return;
212 int id,pos;
213 alGetSourcei(sound,AL_BUFFER,&id);
214 pos = findClipi(id);
215 removeSource(findSource(sound));
216 alDeleteSources(1, &sound);
217 clips[pos].count--;
218 if (clips[pos].count==0) {
219 free(clips[pos].fileName);
220 if (clips[pos].stream==NULL)
221 alDeleteBuffers(1,&clips[pos].bufId);
222 else
223 alureDestroyStream(clips[pos].stream,4096,&clips[pos].bufId);
224 removeClip(pos);
226 lock=0;
229 DECLSPEC void setSoundPosition(int sound, float x, float y, float z) {
230 alSource3f(sound,AL_POSITION,x,y,z);
233 DECLSPEC void setSoundPitch(int sound, float pitch) {
234 alSourcef(sound,AL_PITCH,pitch);
237 DECLSPEC void playSound(int sound) {
238 alSourcei(sound,AL_LOOPING,AL_FALSE);
239 playsource(sound,1);
242 DECLSPEC void loopSound(int sound) {
243 alSourcei(sound,AL_LOOPING,AL_TRUE);
244 playsource(sound,-1);
247 DECLSPEC void stopSound(int sound) {
248 alureStopSource(sound,0);
252 DECLSPEC void setListenerPosition(float x, float y, float z) {
253 alListener3f(AL_POSITION, x, y, z);
256 DECLSPEC void setSoundLowpass(int sound, int lp) {
257 if (lp)
258 alSourcei(sound,AL_DIRECT_FILTER,lowpass);
259 else
260 alSourcei(sound,AL_DIRECT_FILTER,AL_FILTER_NULL);
263 DECLSPEC int getSoundLowpass(int sound) {
264 int ret;
265 alGetSourcei(sound,AL_DIRECT_FILTER,&ret);
266 return ret==lowpass;
269 DECLSPEC int isSoundPlaying(int sound) {
270 if (!alIsSource(sound)) {
271 printf("bcl: Invalid source %d\n",sound);
272 return 0;
274 int ret=0;
275 alGetSourcei(sound,AL_SOURCE_STATE,&ret);
276 return ret==AL_PLAYING;
279 DECLSPEC void setSoundGain(int sound, float gain) {
280 alSourcef(sound,AL_GAIN,gain);
284 void setListenerOrientation(float x1, float y1, float z1, float x2, float y2, float z2) {
285 float attrs[6] = {x1,y1,z1,x2,y2,z2};
286 alListenerfv(AL_ORIENTATION,attrs);