had a stab at my incorrect pointer code
[bcl.git] / audio.c
blobc1f9bf8e33417a9e04f75cac1ec71d7eae7f9aa2
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;
31 int addClip(clip c) {
32 if (numClips>=clipsSize) {
33 clips = realloc(clips,clipsSize*2*sizeof(clip));
34 clipsSize*=2;
36 clips[numClips] = c;
37 numClips++;
38 return numClips-1;
41 void removeClip(int pos) {
42 for (;pos<numClips;pos++)
43 clips[pos]=clips[pos+1];
44 numClips--;
45 if (numClips>0&&numClips <clipsSize/4) {
46 clips = realloc(clips,clipsSize/4*sizeof(clip));
47 clipsSize/=4;
51 int findClipstr(char * name) {
52 int i = 0;
53 for (;i<numClips;i++)
54 if (strcmp(name,clips[i].fileName)==0)
55 return i;
56 return -1;
59 int findClipi(int id) {
60 int i = 0;
61 for (;i<numClips;i++)
62 if (clips[i].bufId==id)
63 return i;
64 return -1;
67 int addSource(ALuint id) {
68 if (numSources>=sourcesSize) {
69 sources = realloc(sources,sizeof(ALuint)*sourcesSize*2);
70 sourcesSize*=2;
72 sources[numSources]=id;
73 numSources++;
74 return numSources -1;
77 void removeSource(int pos) {
78 for (;pos<numSources;pos++)
79 sources[pos]=sources[pos+1];
80 if (numSources>0&&numSources<sourcesSize/4) {
81 sources = realloc(sources,sizeof(ALuint)*sourcesSize/4);
82 sourcesSize/=4;
86 int findSource(int id) {
87 int i;
88 for (i = 0; i < numSources;i++)
89 if (sources[i]==id)
90 return i;
91 return -1;
94 void sourcecall(void *data, ALuint source) {
97 int timercall(int ms, void * data) {
98 alureUpdate();
99 return ms;
102 int lowpass;
103 TIMER updater;
105 DECLSPEC void initAudio() {
106 int attrlist[3];
107 attrlist[0] = ALC_FREQUENCY;
108 attrlist[1] = 44100;
109 attrlist[2] = 0;
110 alureInitDevice(NULL,attrlist);
111 numClips = 0;
112 numSources = 0;
113 clips = malloc(sizeof(clip)*clipsSize);
114 sources = malloc(sizeof(ALuint)*sourcesSize);
115 updater = addTimer(10,timercall,NULL);
116 // filters
117 alGenFilters(1,&lowpass);
118 alFilteri(lowpass,AL_FILTER_TYPE,AL_FILTER_LOWPASS);
119 alFilterf(lowpass,AL_LOWPASS_GAINHF,0.5f);
122 DECLSPEC void terminateAudio() {
123 cancelTimer(updater);
124 int i;
125 alDeleteSources(numSources,sources);
126 for (i = 0; i < numClips;i++) {
127 free(clips[i].fileName);
128 if (clips[i].stream==NULL)
129 alDeleteBuffers(1,&clips[i].bufId);
130 else
131 alureDestroyStream(clips[i].stream,4096,&clips[i].bufId);
133 free(clips);
134 free(sources);
135 alDeleteFilters(1,&lowpass);
136 alureShutdownDevice();
139 void playsource(int sound,int loop) {
140 int bufid;
141 alGetSourcei(sound, AL_BUFFER, &bufid);
142 int pos = findClipi(bufid);
143 if (pos==-1)
144 return;
145 if (clips[pos].stream==NULL)
146 alSourcePlay(sound);
147 else {
148 alurePlaySourceStream(sound,clips[pos].stream,4,loop,sourcecall,NULL);
152 DECLSPEC int loadSound(char * file) {
153 int pos = findClipstr(file);
154 ALuint bufid;
155 if (pos==-1) {
156 bufid = alureCreateBufferFromFile(file);
157 clip c= {strdup(file),bufid,0,NULL};
158 pos = addClip(c);
160 else
161 bufid = clips[pos].bufId;
162 ALuint soundid;
163 alGenSources(1, &soundid);
164 alSourcei(soundid, AL_BUFFER, bufid);
165 addSource(soundid);
166 clips[pos].count++;
167 return soundid;
170 DECLSPEC int streamSound(char * file) {
171 int pos = findClipstr(file);
172 ALuint bufid;
173 if (pos==-1) {
174 alureStream * s = alureCreateStreamFromFile(file,4096,1,&bufid);
175 clip c= {strdup(file),bufid,0,s};
176 pos = addClip(c);
178 else
179 bufid = clips[pos].bufId;
180 ALuint soundid;
181 alGenSources(1, &soundid);
182 alSourcei(soundid, AL_BUFFER, bufid);
183 addSource(soundid);
184 clips[pos].count++;
185 return soundid;
188 DECLSPEC void unloadSound(int sound) {
189 int id,pos;
190 alGetSourcei(sound,AL_BUFFER,&id);
191 pos = findClipi(id);
192 removeSource(sound);
193 alDeleteSources(1, &sound);
194 clips[pos].count--;
195 if (clips[pos].count==0) {
196 free(clips[pos].fileName);
197 if (clips[pos].stream==NULL)
198 alDeleteBuffers(1,&clips[pos].bufId);
199 else
200 alureDestroyStream(clips[pos].stream,4096,&clips[pos].bufId);
201 removeClip(pos);
205 DECLSPEC void setSoundPosition(int sound, float x, float y, float z) {
206 alSource3f(sound,AL_POSITION,x,y,z);
209 DECLSPEC void setSoundPitch(int sound, float pitch) {
210 alSourcef(sound,AL_PITCH,pitch);
213 DECLSPEC void playSound(int sound) {
214 alSourcei(sound,AL_LOOPING,AL_FALSE);
215 playsource(sound,1);
218 DECLSPEC void loopSound(int sound) {
219 alSourcei(sound,AL_LOOPING,AL_TRUE);
220 playsource(sound,-1);
223 DECLSPEC void stopSound(int sound) {
224 alureStopSource(sound,0);
228 DECLSPEC void setListenerPosition(float x, float y, float z) {
229 alListener3f(AL_POSITION, x, y, z);
232 DECLSPEC void setSoundLowpass(int sound, int lp) {
233 if (lp)
234 alSourcei(sound,AL_DIRECT_FILTER,lowpass);
235 else
236 alSourcei(sound,AL_DIRECT_FILTER,AL_FILTER_NULL);
239 DECLSPEC int getSoundLowpass(int sound) {
240 int ret;
241 alGetSourcei(sound,AL_DIRECT_FILTER,&ret);
242 return ret==lowpass;
245 DECLSPEC int isPlaying(int sound) {
246 int ret=0;
247 alGetSourcei(sound,AL_SOURCE_STATE,&ret);
248 return ret==AL_PLAYING;
251 DECLSPEC void setSoundGain(int sound, float gain) {
252 alSourcef(sound,AL_GAIN,gain);