6 // public define AUDIO_BUFFER_SIZE = 21024;
7 public define AUDIO_BUFFER_SIZE = 48000;
12 uint32 f_len __attribute__((packed));
14 uint32 fmt_len __attribute__((packed));
15 uint16 fmt_tag __attribute__((packed));
16 uint16 channel __attribute__((packed));
17 uint32 samples_per_sec __attribute__((packed));
18 uint32 avg_bytes_per_sec __attribute__((packed));
19 uint16 blk_align __attribute__((packed));
20 uint16 bits_per_sample __attribute__((packed));
22 uint32 data_len __attribute__((packed));
28 property const String fileName { set { Load(value); } }
30 int frequency, bits, channels, length;
33 ~Sound() { delete data; }
35 bool Load(const char * fileName)
39 File f = FileOpen(fileName, read);
42 if(f.Read(header,sizeof(WAVEHDR),1) && !memcmp(header.format,"RIFF",4) && !memcmp(header.wave_fmt,"WAVEfmt ",8))
44 data = new byte[header.data_len];
47 int c = f.Read(data, 1, header.data_len);
50 frequency = header.samples_per_sec;
51 bits = header.bits_per_sample;
52 channels = header.channel;
53 length = Min(header.data_len, c);
54 if(c < header.data_len)
73 double volume, balance, pitch;
76 int loopStart, loopEnd;
88 voices.Delete((void *)voices.array);
91 void AudioCallback(byte *stream, int lenToFill)
93 static byte buffer[AUDIO_BUFFER_SIZE];
94 static float fBuffer[AUDIO_BUFFER_SIZE/2];
96 int numSamples = (bits == 16) ? (lenToFill / 2) : lenToFill;
97 memset(fBuffer, 0, sizeof(float) * numSamples);
101 Sound sound = v.sound;
102 float volume = (float)v.volume;
103 float balance = (float)v.balance;
104 int freq = (int)(sound.frequency * v.pitch);
105 int chn = sound.channels;
108 short * sBuffer = (short *)sound.data;
111 short sampleL = sBuffer[s];
112 short sampleR = (chn == 2) ? sBuffer[s+1] : sampleL;
114 for(c = 0; c < numSamples; c++)
116 float left = sampleL * volume / 32767.0f;
117 float right = sampleR * volume / 32767.0f;
120 float v = balance * ((balance < 0) ? right : left);
126 fBuffer[c++] += left;
130 fBuffer[c] += (left + right)/2;
139 } while(se >= frequency);
142 sampleL = sBuffer[s];
143 sampleR = (chn == 2) ? sBuffer[s+1] : sampleL;
151 else if(sound.bits == 8)
153 byte * sBuffer = sound.data;
156 byte sampleL = sBuffer[s];
157 byte sampleR = (chn == 2) ? sBuffer[s+1] : sampleL;
158 bool looped = v.looped;
159 int loopStart = v.loopStart, loopEnd = v.loopEnd;
161 for(c = 0; c < numSamples; c++)
163 float left = (sampleL - 127) * volume / 127.0f;
164 float right = (sampleR - 127) * volume / 127.0f;;
167 float v = balance * ((balance < 0) ? right : left);
173 fBuffer[c++] += left;
177 fBuffer[c] += (left + right)/2;
185 if(looped && s >= loopEnd)
188 } while(se >= frequency);
191 sampleL = sBuffer[s];
192 sampleR = (chn == 2) ? sBuffer[s+1] : sampleL;
203 for(c = 0; c < numSamples; c++)
205 int i = (int)(fBuffer[c] * 32767);
206 if(i > 32767) i = 32767; else if(i < -32768) i = -32768;
207 ((short *)buffer)[c] = (short)i;
212 for(c = 0; c < numSamples; c++)
214 int i = (int)(fBuffer[c] * 127) + 127;
215 if(i > 255) i = 255; else if(i < 0) i = 0;
219 memcpy(stream, buffer, lenToFill);
228 if(v.pos >= v.sound.length)
231 voices.Delete((void *)(voices.array + c));
246 Array<Voice> voices { };
252 property void * systemHandle { set { systemHandle = value; Init(); } }
261 samples = AUDIO_BUFFER_SIZE;
262 callback = AudioCallback;
264 windowHandle = systemHandle;
268 if(!OpenAudio(wantedSpec, spec))
270 MessageBox { contents = "OpenAudio failed" }.Modal();
277 Voice Play(Sound sound, double volume, double balance, double pitch)
279 if(sound && sound.data)
281 Voice voice { sound, volume, balance, pitch };
301 void PlayInVoice(Voice voice, Sound sound, double volume, double balance, double pitch)
319 voice.volume = volume;
320 voice.balance = balance;