Skip to content

Latest commit

 

History

History
431 lines (371 loc) · 12.6 KB

music_mpg123.c

File metadata and controls

431 lines (371 loc) · 12.6 KB
 
Jul 20, 2017
Jul 20, 2017
1
2
/*
SDL_mixer: An audio mixer library based on the SDL library
Mar 1, 2018
Mar 1, 2018
3
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Jul 20, 2017
Jul 20, 2017
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
Oct 17, 2017
Oct 17, 2017
22
/* This file supports playing MP3 files with mpg123 */
Jul 20, 2017
Jul 20, 2017
23
Oct 17, 2017
Oct 17, 2017
24
25
#ifdef MUSIC_MP3_MPG123
Oct 18, 2017
Oct 18, 2017
26
27
#include <stdio.h> // For SEEK_SET
Oct 21, 2017
Oct 21, 2017
28
#include "SDL_assert.h"
Oct 18, 2017
Oct 18, 2017
29
30
#include "SDL_loadso.h"
Oct 17, 2017
Oct 17, 2017
31
32
33
34
#include "music_mpg123.h"
#include <mpg123.h>
Oct 18, 2017
Oct 18, 2017
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
typedef struct {
int loaded;
void *handle;
int (*mpg123_close)(mpg123_handle *mh);
void (*mpg123_delete)(mpg123_handle *mh);
void (*mpg123_exit)(void);
int (*mpg123_format)( mpg123_handle *mh, long rate, int channels, int encodings );
int (*mpg123_format_none)(mpg123_handle *mh);
int (*mpg123_getformat)( mpg123_handle *mh, long *rate, int *channels, int *encoding );
int (*mpg123_init)(void);
mpg123_handle *(*mpg123_new)(const char* decoder, int *error);
int (*mpg123_open_handle)(mpg123_handle *mh, void *iohandle);
const char* (*mpg123_plain_strerror)(int errcode);
Oct 21, 2017
Oct 21, 2017
50
void (*mpg123_rates)(const long **list, size_t *number);
Oct 18, 2017
Oct 18, 2017
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
int (*mpg123_read)(mpg123_handle *mh, unsigned char *outmemory, size_t outmemsize, size_t *done );
int (*mpg123_replace_reader_handle)( mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), off_t (*r_lseek)(void *, off_t, int), void (*cleanup)(void*) );
off_t (*mpg123_seek)( mpg123_handle *mh, off_t sampleoff, int whence );
const char* (*mpg123_strerror)(mpg123_handle *mh);
} mpg123_loader;
static mpg123_loader mpg123 = {
0, NULL
};
#ifdef MPG123_DYNAMIC
#define FUNCTION_LOADER(FUNC, SIG) \
mpg123.FUNC = (SIG) SDL_LoadFunction(mpg123.handle, #FUNC); \
if (mpg123.FUNC == NULL) { SDL_UnloadObject(mpg123.handle); return -1; }
#else
#define FUNCTION_LOADER(FUNC, SIG) \
mpg123.FUNC = FUNC;
#endif
Oct 18, 2017
Oct 18, 2017
70
static int MPG123_Load(void)
Oct 18, 2017
Oct 18, 2017
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
{
if (mpg123.loaded == 0) {
#ifdef MPG123_DYNAMIC
mpg123.handle = SDL_LoadObject(MPG123_DYNAMIC);
if (mpg123.handle == NULL) {
return -1;
}
#elif defined(__MACOSX__)
extern int mpg123_init(void) __attribute__((weak_import));
if (mpg123_init == NULL)
{
/* Missing weakly linked framework */
Mix_SetError("Missing mpg123.framework");
return -1;
}
#endif
FUNCTION_LOADER(mpg123_close, int (*)(mpg123_handle *mh))
FUNCTION_LOADER(mpg123_delete, void (*)(mpg123_handle *mh))
FUNCTION_LOADER(mpg123_exit, void (*)(void))
FUNCTION_LOADER(mpg123_format, int (*)( mpg123_handle *mh, long rate, int channels, int encodings ))
FUNCTION_LOADER(mpg123_format_none, int (*)(mpg123_handle *mh))
FUNCTION_LOADER(mpg123_getformat, int (*)( mpg123_handle *mh, long *rate, int *channels, int *encoding ))
FUNCTION_LOADER(mpg123_init, int (*)(void))
FUNCTION_LOADER(mpg123_new, mpg123_handle *(*)(const char* decoder, int *error))
FUNCTION_LOADER(mpg123_open_handle, int (*)(mpg123_handle *mh, void *iohandle))
FUNCTION_LOADER(mpg123_plain_strerror, const char* (*)(int errcode))
Oct 21, 2017
Oct 21, 2017
97
FUNCTION_LOADER(mpg123_rates, void (*)(const long **list, size_t *number));
Oct 18, 2017
Oct 18, 2017
98
99
100
101
102
103
104
105
106
107
FUNCTION_LOADER(mpg123_read, int (*)(mpg123_handle *mh, unsigned char *outmemory, size_t outmemsize, size_t *done ))
FUNCTION_LOADER(mpg123_replace_reader_handle, int (*)( mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), off_t (*r_lseek)(void *, off_t, int), void (*cleanup)(void*) ))
FUNCTION_LOADER(mpg123_seek, off_t (*)( mpg123_handle *mh, off_t sampleoff, int whence ))
FUNCTION_LOADER(mpg123_strerror, const char* (*)(mpg123_handle *mh))
}
++mpg123.loaded;
return 0;
}
Oct 18, 2017
Oct 18, 2017
108
static void MPG123_Unload(void)
Oct 18, 2017
Oct 18, 2017
109
110
111
112
113
114
115
116
117
118
119
120
121
{
if (mpg123.loaded == 0) {
return;
}
if (mpg123.loaded == 1) {
#ifdef MPG123_DYNAMIC
SDL_UnloadObject(mpg123.handle);
#endif
}
--mpg123.loaded;
}
Oct 17, 2017
Oct 17, 2017
122
123
typedef struct
{
Oct 21, 2017
Oct 21, 2017
124
int play_count;
Oct 17, 2017
Oct 17, 2017
125
126
127
128
129
SDL_RWops* src;
int freesrc;
int volume;
mpg123_handle* handle;
Oct 21, 2017
Oct 21, 2017
130
131
132
133
SDL_AudioStream *stream;
unsigned char *buffer;
size_t buffer_size;
} MPG123_Music;
Oct 17, 2017
Oct 17, 2017
134
Jul 20, 2017
Jul 20, 2017
135
Oct 21, 2017
Oct 21, 2017
136
137
static int MPG123_Seek(void *context, double secs);
static void MPG123_Delete(void *context);
Jul 20, 2017
Jul 20, 2017
138
Oct 21, 2017
Oct 21, 2017
139
static int mpg123_format_to_sdl(int fmt)
Jul 20, 2017
Jul 20, 2017
140
141
142
{
switch (fmt)
{
Oct 21, 2017
Oct 21, 2017
143
144
145
146
147
148
149
case MPG123_ENC_SIGNED_8: return AUDIO_S8;
case MPG123_ENC_UNSIGNED_8: return AUDIO_U8;
case MPG123_ENC_SIGNED_16: return AUDIO_S16SYS;
case MPG123_ENC_UNSIGNED_16: return AUDIO_U16SYS;
case MPG123_ENC_SIGNED_32: return AUDIO_S32SYS;
case MPG123_ENC_FLOAT_32: return AUDIO_F32SYS;
default: return -1;
Jul 20, 2017
Jul 20, 2017
150
151
152
}
}
Oct 21, 2017
Oct 21, 2017
153
154
/*
static const char *mpg123_format_str(int fmt)
Jul 20, 2017
Jul 20, 2017
155
156
157
158
159
160
161
162
163
{
switch (fmt)
{
#define f(x) case x: return #x;
f(MPG123_ENC_UNSIGNED_8)
f(MPG123_ENC_UNSIGNED_16)
f(MPG123_ENC_SIGNED_8)
f(MPG123_ENC_SIGNED_16)
f(MPG123_ENC_SIGNED_32)
Oct 21, 2017
Oct 21, 2017
164
f(MPG123_ENC_FLOAT_32)
Jul 20, 2017
Jul 20, 2017
165
166
167
168
#undef f
}
return "unknown";
}
Oct 21, 2017
Oct 21, 2017
169
*/
Jul 20, 2017
Jul 20, 2017
170
Oct 21, 2017
Oct 21, 2017
171
static char const* mpg_err(mpg123_handle* mpg, int result)
Jul 20, 2017
Jul 20, 2017
172
173
174
{
char const* err = "unknown error";
Oct 21, 2017
Oct 21, 2017
175
if (mpg && result == MPG123_ERR) {
Oct 18, 2017
Oct 18, 2017
176
err = mpg123.mpg123_strerror(mpg);
Jul 20, 2017
Jul 20, 2017
177
} else {
Oct 21, 2017
Oct 21, 2017
178
err = mpg123.mpg123_plain_strerror(result);
Jul 20, 2017
Jul 20, 2017
179
180
181
182
183
}
return err;
}
/* we're gonna override mpg123's I/O with these wrappers for RWops */
Oct 21, 2017
Oct 21, 2017
184
185
static ssize_t rwops_read(void* p, void* dst, size_t n)
{
Jul 20, 2017
Jul 20, 2017
186
187
188
return (ssize_t)SDL_RWread((SDL_RWops*)p, dst, 1, n);
}
Oct 21, 2017
Oct 21, 2017
189
190
static off_t rwops_seek(void* p, off_t offset, int whence)
{
Jul 20, 2017
Jul 20, 2017
191
192
193
return (off_t)SDL_RWseek((SDL_RWops*)p, (Sint64)offset, whence);
}
Oct 21, 2017
Oct 21, 2017
194
195
static void rwops_cleanup(void* p)
{
Jul 20, 2017
Jul 20, 2017
196
197
198
199
(void)p;
/* do nothing, we will free the file later */
}
Oct 17, 2017
Oct 17, 2017
200
201
202
static int MPG123_Open(const SDL_AudioSpec *spec)
{
Oct 18, 2017
Oct 18, 2017
203
if (mpg123.mpg123_init() != MPG123_OK) {
Oct 17, 2017
Oct 17, 2017
204
205
206
207
208
209
210
Mix_SetError("mpg123_init() failed");
return -1;
}
return 0;
}
static void *MPG123_CreateFromRW(SDL_RWops *src, int freesrc)
Jul 20, 2017
Jul 20, 2017
211
{
Oct 21, 2017
Oct 21, 2017
212
MPG123_Music *music;
Jul 20, 2017
Jul 20, 2017
213
int result;
Oct 21, 2017
Oct 21, 2017
214
215
const long *rates;
size_t i, num_rates;
Jul 20, 2017
Jul 20, 2017
216
Oct 21, 2017
Oct 21, 2017
217
218
219
220
221
222
223
224
225
226
227
228
229
230
music = (MPG123_Music*)SDL_calloc(1, sizeof(*music));
if (!music) {
return NULL;
}
music->src = src;
music->volume = MIX_MAX_VOLUME;
/* Just assume 16-bit 2 channel audio for now */
music->buffer_size = music_spec.samples * sizeof(Sint16) * 2;
music->buffer = (unsigned char *)SDL_malloc(music->buffer_size);
if (!music->buffer) {
MPG123_Delete(music);
SDL_OutOfMemory();
return NULL;
Jul 20, 2017
Jul 20, 2017
231
232
}
Oct 21, 2017
Oct 21, 2017
233
music->handle = mpg123.mpg123_new(0, &result);
Jul 20, 2017
Jul 20, 2017
234
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
235
236
237
MPG123_Delete(music);
Mix_SetError("mpg123_new failed");
return NULL;
Jul 20, 2017
Jul 20, 2017
238
239
}
Oct 18, 2017
Oct 18, 2017
240
result = mpg123.mpg123_replace_reader_handle(
Oct 21, 2017
Oct 21, 2017
241
music->handle,
Jul 20, 2017
Jul 20, 2017
242
rwops_read, rwops_seek, rwops_cleanup
Oct 21, 2017
Oct 21, 2017
243
);
Jul 20, 2017
Jul 20, 2017
244
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
245
246
247
MPG123_Delete(music);
Mix_SetError("mpg123_replace_reader_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
248
249
}
Oct 21, 2017
Oct 21, 2017
250
result = mpg123.mpg123_format_none(music->handle);
Jul 20, 2017
Jul 20, 2017
251
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
252
253
254
MPG123_Delete(music);
Mix_SetError("mpg123_format_none: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
255
256
}
Oct 21, 2017
Oct 21, 2017
257
258
259
260
261
262
263
264
265
266
267
mpg123.mpg123_rates(&rates, &num_rates);
for (i = 0; i < num_rates; ++i) {
const int channels = (MPG123_MONO|MPG123_STEREO);
const int formats = (MPG123_ENC_SIGNED_8 |
MPG123_ENC_UNSIGNED_8 |
MPG123_ENC_SIGNED_16 |
MPG123_ENC_UNSIGNED_16 |
MPG123_ENC_SIGNED_32 |
MPG123_ENC_FLOAT_32);
mpg123.mpg123_format(music->handle, rates[i], channels, formats);
Jul 20, 2017
Jul 20, 2017
268
269
}
Oct 21, 2017
Oct 21, 2017
270
result = mpg123.mpg123_open_handle(music->handle, music->src);
Jul 20, 2017
Jul 20, 2017
271
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
272
273
274
MPG123_Delete(music);
Mix_SetError("mpg123_open_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
275
276
}
Oct 21, 2017
Oct 21, 2017
277
278
music->freesrc = freesrc;
return music;
Jul 20, 2017
Jul 20, 2017
279
280
}
Oct 21, 2017
Oct 21, 2017
281
static void MPG123_SetVolume(void *context, int volume)
Oct 17, 2017
Oct 17, 2017
282
{
Oct 21, 2017
Oct 21, 2017
283
284
MPG123_Music *music = (MPG123_Music *)context;
music->volume = volume;
Jul 20, 2017
Jul 20, 2017
285
286
}
Oct 21, 2017
Oct 21, 2017
287
static int MPG123_Play(void *context, int play_count)
Oct 17, 2017
Oct 17, 2017
288
{
Oct 21, 2017
Oct 21, 2017
289
290
291
MPG123_Music *music = (MPG123_Music *)context;
music->play_count = play_count;
return MPG123_Seek(music, 0.0);
Jul 20, 2017
Jul 20, 2017
292
293
}
Oct 21, 2017
Oct 21, 2017
294
295
/* read some mp3 stream data and convert it for output */
static int MPG123_GetSome(void *context, void *data, int bytes, SDL_bool *done)
Jul 20, 2017
Jul 20, 2017
296
{
Oct 21, 2017
Oct 21, 2017
297
298
299
MPG123_Music *music = (MPG123_Music *)context;
int filled, result;
size_t amount;
Jul 20, 2017
Jul 20, 2017
300
long rate;
Oct 21, 2017
Oct 21, 2017
301
int channels, encoding, format;
Jul 20, 2017
Jul 20, 2017
302
Oct 21, 2017
Oct 21, 2017
303
304
305
306
307
if (music->stream) {
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
}
Jul 20, 2017
Jul 20, 2017
308
309
}
Oct 21, 2017
Oct 21, 2017
310
311
312
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
Jul 20, 2017
Jul 20, 2017
313
314
315
return 0;
}
Oct 21, 2017
Oct 21, 2017
316
317
318
319
320
result = mpg123.mpg123_read(music->handle, music->buffer, music->buffer_size, &amount);
switch (result) {
case MPG123_OK:
if (SDL_AudioStreamPut(music->stream, music->buffer, (int)amount) < 0) {
return -1;
Jul 20, 2017
Jul 20, 2017
321
}
Oct 21, 2017
Oct 21, 2017
322
break;
Jul 20, 2017
Jul 20, 2017
323
Oct 21, 2017
Oct 21, 2017
324
325
326
327
328
case MPG123_NEW_FORMAT:
result = mpg123.mpg123_getformat(music->handle, &rate, &channels, &encoding);
if (result != MPG123_OK) {
Mix_SetError("mpg123_getformat: %s", mpg_err(music->handle, result));
return -1;
Jul 20, 2017
Jul 20, 2017
329
}
Oct 21, 2017
Oct 21, 2017
330
/*printf("MPG123 format: %s, channels = %d, rate = %ld\n", mpg123_format_str(encoding), channels, rate);*/
Jul 20, 2017
Jul 20, 2017
331
Oct 21, 2017
Oct 21, 2017
332
333
format = mpg123_format_to_sdl(encoding);
SDL_assert(format != -1);
Jul 20, 2017
Jul 20, 2017
334
Oct 21, 2017
Oct 21, 2017
335
336
337
338
music->stream = SDL_NewAudioStream(format, channels, (int)rate,
music_spec.format, music_spec.channels, music_spec.freq);
if (!music->stream) {
return -1;
Jul 20, 2017
Jul 20, 2017
339
}
Oct 21, 2017
Oct 21, 2017
340
341
342
343
344
345
346
347
348
349
350
351
352
353
break;
case MPG123_DONE:
if (music->play_count == 1) {
music->play_count = 0;
SDL_AudioStreamFlush(music->stream);
} else {
int play_count = -1;
if (music->play_count > 0) {
play_count = (music->play_count - 1);
}
if (MPG123_Play(music, play_count) < 0) {
return -1;
}
Jul 20, 2017
Jul 20, 2017
354
}
Oct 21, 2017
Oct 21, 2017
355
356
357
358
break;
default:
Mix_SetError("mpg123_read: %s", mpg_err(music->handle, result));
return -1;
Jul 20, 2017
Jul 20, 2017
359
}
Oct 21, 2017
Oct 21, 2017
360
361
362
363
364
365
return 0;
}
static int MPG123_GetAudio(void *context, void *data, int bytes)
{
MPG123_Music *music = (MPG123_Music *)context;
return music_pcm_getaudio(context, data, bytes, music->volume, MPG123_GetSome);
Jul 20, 2017
Jul 20, 2017
366
367
}
Oct 17, 2017
Oct 17, 2017
368
static int MPG123_Seek(void *context, double secs)
Jul 20, 2017
Jul 20, 2017
369
{
Oct 21, 2017
Oct 21, 2017
370
371
MPG123_Music *music = (MPG123_Music *)context;
off_t offset = (off_t)(music_spec.freq * secs);
Jul 20, 2017
Jul 20, 2017
372
Oct 21, 2017
Oct 21, 2017
373
374
if ((offset = mpg123.mpg123_seek(music->handle, offset, SEEK_SET)) < 0) {
return Mix_SetError("mpg123_seek: %s", mpg_err(music->handle, (int)-offset));
Jul 20, 2017
Jul 20, 2017
375
}
Oct 17, 2017
Oct 17, 2017
376
return 0;
Jul 20, 2017
Jul 20, 2017
377
378
}
Oct 17, 2017
Oct 17, 2017
379
380
static void MPG123_Delete(void *context)
{
Oct 21, 2017
Oct 21, 2017
381
MPG123_Music *music = (MPG123_Music *)context;
Jul 20, 2017
Jul 20, 2017
382
Oct 21, 2017
Oct 21, 2017
383
384
385
if (music->handle) {
mpg123.mpg123_close(music->handle);
mpg123.mpg123_delete(music->handle);
Oct 17, 2017
Oct 17, 2017
386
}
Oct 21, 2017
Oct 21, 2017
387
388
if (music->stream) {
SDL_FreeAudioStream(music->stream);
Oct 17, 2017
Oct 17, 2017
389
}
Oct 21, 2017
Oct 21, 2017
390
391
392
393
394
395
396
if (music->buffer) {
SDL_free(music->buffer);
}
if (music->freesrc) {
SDL_RWclose(music->src);
}
SDL_free(music);
Oct 17, 2017
Oct 17, 2017
397
398
399
400
}
static void MPG123_Close(void)
{
Oct 18, 2017
Oct 18, 2017
401
mpg123.mpg123_exit();
Oct 17, 2017
Oct 17, 2017
402
403
404
405
406
407
408
409
410
411
}
Mix_MusicInterface Mix_MusicInterface_MPG123 =
{
"MPG123",
MIX_MUSIC_MPG123,
MUS_MP3,
SDL_FALSE,
SDL_FALSE,
Oct 18, 2017
Oct 18, 2017
412
MPG123_Load,
Oct 17, 2017
Oct 17, 2017
413
414
415
416
417
MPG123_Open,
MPG123_CreateFromRW,
NULL, /* CreateFromFile */
MPG123_SetVolume,
MPG123_Play,
Oct 21, 2017
Oct 21, 2017
418
NULL, /* IsPlaying */
Oct 17, 2017
Oct 17, 2017
419
420
421
422
MPG123_GetAudio,
MPG123_Seek,
NULL, /* Pause */
NULL, /* Resume */
Oct 21, 2017
Oct 21, 2017
423
NULL, /* Stop */
Oct 17, 2017
Oct 17, 2017
424
425
MPG123_Delete,
MPG123_Close,
Oct 18, 2017
Oct 18, 2017
426
MPG123_Unload
Oct 17, 2017
Oct 17, 2017
427
428
429
430
431
};
#endif /* MUSIC_MP3_MPG123 */
/* vi: set ts=4 sw=4 expandtab: */