Skip to content

Commit ae27c6d

Browse files
committed
MiniAL improvements and fixes backported from sdl2 branch.
1 parent b7a6717 commit ae27c6d

1 file changed

Lines changed: 85 additions & 53 deletions

File tree

src/minial.cpp

Lines changed: 85 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515
#include <cmath>
1616
#include <SDL/SDL.h>
1717

18+
#define MA_FILTER_NONE 0
19+
#define MA_FILTER_LINEAR 1 // recommended
20+
#define MA_FILTER_HIGH_QUALITY 2
21+
22+
#define MA_FILTER MA_FILTER_LINEAR
1823
#define MA_FREQ 22050
19-
#define MA_SAMPLES 1024
20-
#define MA_LINEAR 1 // sample filtering: 0 - none, 1 - linear
24+
#define MA_SAMPLES 256
2125

2226
struct ALCdevice
2327
{
@@ -51,6 +55,7 @@ struct MA_Source
5155
struct MA_Buffer
5256
{
5357
std::vector<Sint16> samples;
58+
float pitch = 1.f;
5459
};
5560

5661
static ALCdevice alcDevice;
@@ -65,54 +70,63 @@ static void ma_callback(void *userdata, Uint8 *stream, int len)
6570
(void)userdata;
6671
Sint16* stream16 = (Sint16*)stream;
6772
int len16 = len >> 1;
73+
if (floatBuff == 0) return;
6874
floatBuff->resize(len16);
6975
std::fill(floatBuff->begin(), floatBuff->end(), 0.f);
70-
for (auto& p : *sourceMap)
76+
if (sourceMap != 0)
7177
{
72-
MA_Source& src = p.second;
73-
if (src.playing)
78+
for (auto& p : *sourceMap)
7479
{
75-
if (src.buffer != 0)
80+
MA_Source& src = p.second;
81+
if (src.playing)
7682
{
77-
MA_Buffer& buff = (*bufferMap)[src.buffer];
78-
if (!buff.samples.empty())
83+
if (src.buffer != 0)
7984
{
80-
for (int i = 0; i != len16; ++i)
85+
MA_Buffer& buff = (*bufferMap)[src.buffer];
86+
if (!buff.samples.empty())
8187
{
82-
while (src.pos >= buff.samples.size())
88+
const float pitch = src.pitch * buff.pitch;
89+
for (int i = 0; i != len16; ++i)
8390
{
84-
if (src.looping)
91+
while (src.pos >= buff.samples.size())
8592
{
86-
src.pos -= buff.samples.size();
93+
if (src.looping)
94+
{
95+
src.pos -= buff.samples.size();
96+
}
97+
else
98+
{
99+
src.pos = 0;
100+
src.playing = false;
101+
}
87102
}
88-
else
103+
if (!src.playing) break;
104+
#if MA_FILTER == MA_FILTER_NONE
105+
(*floatBuff)[i] += buff.samples[src.pos] * src.gain;
106+
#endif
107+
#if MA_FILTER == MA_FILTER_LINEAR
108+
uint32_t ipos0 = src.pos;
109+
uint32_t ipos1 = ipos0 + 1;
110+
Sint16 smp0 = buff.samples[ipos0];
111+
Sint16 smp1 = 0;
112+
if (ipos1 >= buff.samples.size())
89113
{
90-
src.pos = 0;
91-
src.playing = false;
114+
if (src.looping)
115+
{
116+
smp1 = buff.samples[0];
117+
}
92118
}
93-
}
94-
if (!src.playing) break;
95-
#if MA_LINEAR
96-
uint32_t ipos0 = src.pos;
97-
uint32_t ipos1 = ipos0 + 1;
98-
Sint16 smp0 = buff.samples[ipos0];
99-
Sint16 smp1 = 0;
100-
if (ipos1 >= buff.samples.size())
101-
{
102-
if (src.looping)
119+
else
103120
{
104-
smp1 = buff.samples[0];
121+
smp1 = buff.samples[ipos1];
105122
}
106-
}
107-
else
108-
{
109-
smp1 = buff.samples[ipos1];
110-
}
111-
(*floatBuff)[i] += (float(smp0) + (float(smp1) - float(smp0)) * (src.pos - ipos0)) * src.gain;
112-
#else
113-
(*floatBuff)[i] += buff.samples[src.pos] * src.gain;
123+
(*floatBuff)[i] += (float(smp0) + (float(smp1) - float(smp0)) * (src.pos - ipos0)) * src.gain;
124+
#endif
125+
#if MA_FILTER == MA_FILTER_HIGH_QUALITY
126+
#error "Hight quality audio filter is currently not implemented"
114127
#endif
115-
src.pos += src.pitch;
128+
src.pos += pitch;
129+
}
116130
}
117131
}
118132
}
@@ -133,17 +147,29 @@ static void ma_callback(void *userdata, Uint8 *stream, int len)
133147

134148
ALCboolean alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname)
135149
{
136-
(void)device;
137-
(void)extname;
138-
return 1;
150+
if (device == 0)
151+
{
152+
if (strcmp(extname, "ALC_ENUMERATE_ALL_EXT") == 0)
153+
{
154+
return 1;
155+
}
156+
if (strcmp(extname, "ALC_ENUMERATION_EXT") == 0)
157+
{
158+
return 1;
159+
}
160+
}
161+
return 0;
139162
}
140163

141164
const ALCchar* alcGetString(ALCdevice *device, ALCenum param)
142165
{
143-
(void)device;
144-
(void)param;
145-
static const ALCchar* ret = "\0\0";
146-
return ret;
166+
SDL_InitSubSystem(SDL_INIT_AUDIO);
167+
if (device == 0 && (param == ALC_ALL_DEVICES_SPECIFIER || param == ALC_DEVICE_SPECIFIER))
168+
{
169+
static const ALCchar* ret = "\0\0";
170+
return ret;
171+
}
172+
return 0;
147173
}
148174

149175
ALCdevice* alcOpenDevice(const ALCchar *devicename)
@@ -153,7 +179,6 @@ ALCdevice* alcOpenDevice(const ALCchar *devicename)
153179
bufferMap = new std::map<ALuint, MA_Buffer>;
154180
floatBuff = new std::vector<float>;
155181
floatBuff->resize(MA_SAMPLES);
156-
SDL_InitSubSystem(SDL_INIT_AUDIO);
157182
SDL_AudioSpec as;
158183
as.freq = MA_FREQ;
159184
as.format = AUDIO_S16;
@@ -190,8 +215,11 @@ ALCboolean alcCloseDevice(ALCdevice *device)
190215
(void)device;
191216
SDL_CloseAudio();
192217
delete sourceMap;
218+
sourceMap = 0;
193219
delete bufferMap;
220+
bufferMap = 0;
194221
delete floatBuff;
222+
floatBuff = 0;
195223
return 1;
196224
}
197225

@@ -223,46 +251,50 @@ void alGenBuffers(ALsizei n, ALuint *buffers)
223251
generateStuff(n, buffers, *bufferMap, bufferCounter);
224252
}
225253

226-
template<class T> void deleteStuff(ALsizei n, const ALuint* stuff, std::map<ALuint, T>& m)
254+
template<class T> void deleteStuff(ALsizei n, const ALuint* stuff, std::map<ALuint, T>* m)
227255
{
256+
if (m == 0)
257+
return;
228258
SDL_LockAudio();
229259
for (ALsizei i = 0; i != n; ++i)
230260
{
231-
m.erase(stuff[i]);
261+
m->erase(stuff[i]);
232262
}
233263
SDL_UnlockAudio();
234264
}
235265

236266
void alDeleteSources(ALsizei n, const ALuint *sources)
237267
{
238-
deleteStuff(n, sources, *sourceMap);
268+
deleteStuff(n, sources, sourceMap);
239269
}
240270

241271
void alDeleteBuffers(ALsizei n, const ALuint *buffers)
242272
{
243-
deleteStuff(n, buffers, *bufferMap);
273+
deleteStuff(n, buffers, bufferMap);
244274
}
245275

246276
void alListenerfv(ALenum param, const ALfloat *values)
247277
{
248278
(void)param;
249279
(void)values;
280+
// listener parameters have no effect
250281
return;
251282
}
252283

253284
void alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
254285
{
255-
if (buffer == 0 || format != AL_FORMAT_MONO16 || freq != MA_FREQ) return; // only 22050 Hz, 16-bit mono audio is currently supported
286+
if (buffer == 0 || bufferMap == 0 || format != AL_FORMAT_MONO16) return; // only 16-bit mono audio is currently supported
256287
SDL_LockAudio();
257288
MA_Buffer& buff = (*bufferMap)[buffer];
289+
buff.pitch = float(freq)/float(MA_FREQ);
258290
buff.samples.resize(size >> 1);
259291
std::copy((Sint16*)data, ((Sint16*)data) + buff.samples.size(), buff.samples.begin());
260292
SDL_UnlockAudio();
261293
}
262294

263295
void alSourcef(ALuint source, ALenum param, ALfloat value)
264296
{
265-
if (source == 0) return;
297+
if (source == 0 || sourceMap == 0) return;
266298
SDL_LockAudio();
267299
MA_Source& src = (*sourceMap)[source];
268300
switch (param)
@@ -294,7 +326,7 @@ void alSourcefv(ALuint source, ALenum param, const ALfloat *values)
294326

295327
void alSourcei(ALuint source, ALenum param, ALint value)
296328
{
297-
if (source == 0) return;
329+
if (source == 0 || sourceMap == 0) return;
298330
SDL_LockAudio();
299331
MA_Source& src = (*sourceMap)[source];
300332
switch (param)
@@ -311,7 +343,7 @@ void alSourcei(ALuint source, ALenum param, ALint value)
311343

312344
void alSourcePlay(ALuint source)
313345
{
314-
if (source == 0) return;
346+
if (source == 0 || sourceMap == 0) return;
315347
SDL_LockAudio();
316348
MA_Source& src = (*sourceMap)[source];
317349
src.playing = true;
@@ -320,7 +352,7 @@ void alSourcePlay(ALuint source)
320352

321353
void alSourceStop(ALuint source)
322354
{
323-
if (source == 0) return;
355+
if (source == 0 || sourceMap == 0) return;
324356
SDL_LockAudio();
325357
MA_Source& src = (*sourceMap)[source];
326358
src.playing = false;
@@ -329,7 +361,7 @@ void alSourceStop(ALuint source)
329361

330362
void alSourceRewind(ALuint source)
331363
{
332-
if (source == 0) return;
364+
if (source == 0 || sourceMap == 0) return;
333365
SDL_LockAudio();
334366
MA_Source& src = (*sourceMap)[source];
335367
src.pos = 0;

0 commit comments

Comments
 (0)