Skip to content

Latest commit

 

History

History
441 lines (380 loc) · 12.9 KB

music_mpg123.c

File metadata and controls

441 lines (380 loc) · 12.9 KB
 
Jul 20, 2017
Jul 20, 2017
1
2
/*
SDL_mixer: An audio mixer library based on the SDL library
Jan 5, 2019
Jan 5, 2019
3
Copyright (C) 1997-2019 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
Nov 17, 2019
Nov 17, 2019
26
#include <stdio.h> /* For SEEK_SET */
Oct 18, 2017
Oct 18, 2017
27
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
#include "music_mpg123.h"
Dec 10, 2019
Dec 10, 2019
32
#include "mp3utils.h"
Oct 17, 2017
Oct 17, 2017
33
34
35
#include <mpg123.h>
Oct 18, 2017
Oct 18, 2017
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
51
void (*mpg123_rates)(const long **list, size_t *number);
Oct 18, 2017
Oct 18, 2017
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
71
static int MPG123_Load(void)
Oct 18, 2017
Oct 18, 2017
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
97
{
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))
Dec 10, 2019
Dec 10, 2019
98
FUNCTION_LOADER(mpg123_rates, void (*)(const long **list, size_t *number))
Oct 18, 2017
Oct 18, 2017
99
100
101
102
103
104
105
106
107
108
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
109
static void MPG123_Unload(void)
Oct 18, 2017
Oct 18, 2017
110
111
112
113
114
115
116
117
118
119
120
121
122
{
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
123
124
typedef struct
{
Dec 10, 2019
Dec 10, 2019
125
struct mp3file_t mp3file;
Oct 21, 2017
Oct 21, 2017
126
int play_count;
Oct 17, 2017
Oct 17, 2017
127
128
129
130
int freesrc;
int volume;
mpg123_handle* handle;
Oct 21, 2017
Oct 21, 2017
131
132
133
134
SDL_AudioStream *stream;
unsigned char *buffer;
size_t buffer_size;
} MPG123_Music;
Oct 17, 2017
Oct 17, 2017
135
Jul 20, 2017
Jul 20, 2017
136
Oct 21, 2017
Oct 21, 2017
137
138
static int MPG123_Seek(void *context, double secs);
static void MPG123_Delete(void *context);
Jul 20, 2017
Jul 20, 2017
139
Oct 21, 2017
Oct 21, 2017
140
static int mpg123_format_to_sdl(int fmt)
Jul 20, 2017
Jul 20, 2017
141
142
143
{
switch (fmt)
{
Oct 21, 2017
Oct 21, 2017
144
145
146
147
148
149
150
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
151
152
153
}
}
Oct 21, 2017
Oct 21, 2017
154
155
/*
static const char *mpg123_format_str(int fmt)
Jul 20, 2017
Jul 20, 2017
156
157
158
159
160
161
162
163
164
{
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
165
f(MPG123_ENC_FLOAT_32)
Jul 20, 2017
Jul 20, 2017
166
167
168
169
#undef f
}
return "unknown";
}
Oct 21, 2017
Oct 21, 2017
170
*/
Jul 20, 2017
Jul 20, 2017
171
Oct 21, 2017
Oct 21, 2017
172
static char const* mpg_err(mpg123_handle* mpg, int result)
Jul 20, 2017
Jul 20, 2017
173
174
175
{
char const* err = "unknown error";
Oct 21, 2017
Oct 21, 2017
176
if (mpg && result == MPG123_ERR) {
Oct 18, 2017
Oct 18, 2017
177
err = mpg123.mpg123_strerror(mpg);
Jul 20, 2017
Jul 20, 2017
178
} else {
Oct 21, 2017
Oct 21, 2017
179
err = mpg123.mpg123_plain_strerror(result);
Jul 20, 2017
Jul 20, 2017
180
181
182
183
184
}
return err;
}
/* we're gonna override mpg123's I/O with these wrappers for RWops */
Oct 21, 2017
Oct 21, 2017
185
186
static ssize_t rwops_read(void* p, void* dst, size_t n)
{
Dec 10, 2019
Dec 10, 2019
187
return (ssize_t)MP3_RWread((struct mp3file_t *)p, dst, 1, n);
Jul 20, 2017
Jul 20, 2017
188
189
}
Oct 21, 2017
Oct 21, 2017
190
191
static off_t rwops_seek(void* p, off_t offset, int whence)
{
Dec 10, 2019
Dec 10, 2019
192
return (off_t)MP3_RWseek((struct mp3file_t *)p, (Sint64)offset, whence);
Jul 20, 2017
Jul 20, 2017
193
194
}
Oct 21, 2017
Oct 21, 2017
195
196
static void rwops_cleanup(void* p)
{
Jul 20, 2017
Jul 20, 2017
197
198
199
200
(void)p;
/* do nothing, we will free the file later */
}
Oct 17, 2017
Oct 17, 2017
201
202
203
static int MPG123_Open(const SDL_AudioSpec *spec)
{
Nov 17, 2019
Nov 17, 2019
204
(void)spec;
Oct 18, 2017
Oct 18, 2017
205
if (mpg123.mpg123_init() != MPG123_OK) {
Oct 17, 2017
Oct 17, 2017
206
207
208
209
210
211
212
Mix_SetError("mpg123_init() failed");
return -1;
}
return 0;
}
static void *MPG123_CreateFromRW(SDL_RWops *src, int freesrc)
Jul 20, 2017
Jul 20, 2017
213
{
Oct 21, 2017
Oct 21, 2017
214
MPG123_Music *music;
Jul 20, 2017
Jul 20, 2017
215
int result;
Oct 21, 2017
Oct 21, 2017
216
217
const long *rates;
size_t i, num_rates;
Jul 20, 2017
Jul 20, 2017
218
Oct 21, 2017
Oct 21, 2017
219
220
221
222
music = (MPG123_Music*)SDL_calloc(1, sizeof(*music));
if (!music) {
return NULL;
}
Dec 10, 2019
Dec 10, 2019
223
music->mp3file.src = src;
Oct 21, 2017
Oct 21, 2017
224
225
music->volume = MIX_MAX_VOLUME;
Dec 10, 2019
Dec 10, 2019
226
227
228
229
230
231
232
233
music->mp3file.length = SDL_RWsize(src);
if (mp3_skiptags(&music->mp3file) < 0) {
SDL_free(music);
Mix_SetError("music_mpg123: corrupt mp3 file (bad tags.)");
return NULL;
}
MP3_RWseek(&music->mp3file, 0, RW_SEEK_SET);
Oct 21, 2017
Oct 21, 2017
234
235
236
237
238
239
240
/* 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
241
242
}
Oct 21, 2017
Oct 21, 2017
243
music->handle = mpg123.mpg123_new(0, &result);
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_new failed");
return NULL;
Jul 20, 2017
Jul 20, 2017
248
249
}
Oct 18, 2017
Oct 18, 2017
250
result = mpg123.mpg123_replace_reader_handle(
Oct 21, 2017
Oct 21, 2017
251
music->handle,
Jul 20, 2017
Jul 20, 2017
252
rwops_read, rwops_seek, rwops_cleanup
Oct 21, 2017
Oct 21, 2017
253
);
Jul 20, 2017
Jul 20, 2017
254
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
255
256
257
MPG123_Delete(music);
Mix_SetError("mpg123_replace_reader_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
258
259
}
Oct 21, 2017
Oct 21, 2017
260
result = mpg123.mpg123_format_none(music->handle);
Jul 20, 2017
Jul 20, 2017
261
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
262
263
264
MPG123_Delete(music);
Mix_SetError("mpg123_format_none: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
265
266
}
Oct 21, 2017
Oct 21, 2017
267
268
269
270
271
272
273
274
275
276
277
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
278
279
}
Dec 10, 2019
Dec 10, 2019
280
result = mpg123.mpg123_open_handle(music->handle, &music->mp3file);
Jul 20, 2017
Jul 20, 2017
281
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
282
283
284
MPG123_Delete(music);
Mix_SetError("mpg123_open_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
285
286
}
Oct 21, 2017
Oct 21, 2017
287
288
music->freesrc = freesrc;
return music;
Jul 20, 2017
Jul 20, 2017
289
290
}
Oct 21, 2017
Oct 21, 2017
291
static void MPG123_SetVolume(void *context, int volume)
Oct 17, 2017
Oct 17, 2017
292
{
Oct 21, 2017
Oct 21, 2017
293
294
MPG123_Music *music = (MPG123_Music *)context;
music->volume = volume;
Jul 20, 2017
Jul 20, 2017
295
296
}
Oct 21, 2017
Oct 21, 2017
297
static int MPG123_Play(void *context, int play_count)
Oct 17, 2017
Oct 17, 2017
298
{
Oct 21, 2017
Oct 21, 2017
299
300
301
MPG123_Music *music = (MPG123_Music *)context;
music->play_count = play_count;
return MPG123_Seek(music, 0.0);
Jul 20, 2017
Jul 20, 2017
302
303
}
Oct 21, 2017
Oct 21, 2017
304
305
/* 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
306
{
Oct 21, 2017
Oct 21, 2017
307
308
309
MPG123_Music *music = (MPG123_Music *)context;
int filled, result;
size_t amount;
Jul 20, 2017
Jul 20, 2017
310
long rate;
Oct 21, 2017
Oct 21, 2017
311
int channels, encoding, format;
Jul 20, 2017
Jul 20, 2017
312
Oct 21, 2017
Oct 21, 2017
313
314
315
316
317
if (music->stream) {
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
}
Jul 20, 2017
Jul 20, 2017
318
319
}
Oct 21, 2017
Oct 21, 2017
320
321
322
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
Jul 20, 2017
Jul 20, 2017
323
324
325
return 0;
}
Oct 21, 2017
Oct 21, 2017
326
327
328
329
330
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
331
}
Oct 21, 2017
Oct 21, 2017
332
break;
Jul 20, 2017
Jul 20, 2017
333
Oct 21, 2017
Oct 21, 2017
334
335
336
337
338
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
339
}
Oct 21, 2017
Oct 21, 2017
340
/*printf("MPG123 format: %s, channels = %d, rate = %ld\n", mpg123_format_str(encoding), channels, rate);*/
Jul 20, 2017
Jul 20, 2017
341
Oct 21, 2017
Oct 21, 2017
342
343
format = mpg123_format_to_sdl(encoding);
SDL_assert(format != -1);
Jul 20, 2017
Jul 20, 2017
344
Nov 17, 2019
Nov 17, 2019
345
music->stream = SDL_NewAudioStream((SDL_AudioFormat)format, (Uint8)channels, (int)rate,
Oct 21, 2017
Oct 21, 2017
346
347
348
music_spec.format, music_spec.channels, music_spec.freq);
if (!music->stream) {
return -1;
Jul 20, 2017
Jul 20, 2017
349
}
Oct 21, 2017
Oct 21, 2017
350
351
352
353
354
355
356
357
358
359
360
361
362
363
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
364
}
Oct 21, 2017
Oct 21, 2017
365
366
367
368
break;
default:
Mix_SetError("mpg123_read: %s", mpg_err(music->handle, result));
return -1;
Jul 20, 2017
Jul 20, 2017
369
}
Oct 21, 2017
Oct 21, 2017
370
371
372
373
374
375
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
376
377
}
Oct 17, 2017
Oct 17, 2017
378
static int MPG123_Seek(void *context, double secs)
Jul 20, 2017
Jul 20, 2017
379
{
Oct 21, 2017
Oct 21, 2017
380
381
MPG123_Music *music = (MPG123_Music *)context;
off_t offset = (off_t)(music_spec.freq * secs);
Jul 20, 2017
Jul 20, 2017
382
Oct 21, 2017
Oct 21, 2017
383
384
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
385
}
Oct 17, 2017
Oct 17, 2017
386
return 0;
Jul 20, 2017
Jul 20, 2017
387
388
}
Oct 17, 2017
Oct 17, 2017
389
390
static void MPG123_Delete(void *context)
{
Oct 21, 2017
Oct 21, 2017
391
MPG123_Music *music = (MPG123_Music *)context;
Jul 20, 2017
Jul 20, 2017
392
Oct 21, 2017
Oct 21, 2017
393
394
395
if (music->handle) {
mpg123.mpg123_close(music->handle);
mpg123.mpg123_delete(music->handle);
Oct 17, 2017
Oct 17, 2017
396
}
Oct 21, 2017
Oct 21, 2017
397
398
if (music->stream) {
SDL_FreeAudioStream(music->stream);
Oct 17, 2017
Oct 17, 2017
399
}
Oct 21, 2017
Oct 21, 2017
400
401
402
403
if (music->buffer) {
SDL_free(music->buffer);
}
if (music->freesrc) {
Dec 10, 2019
Dec 10, 2019
404
SDL_RWclose(music->mp3file.src);
Oct 21, 2017
Oct 21, 2017
405
406
}
SDL_free(music);
Oct 17, 2017
Oct 17, 2017
407
408
409
410
}
static void MPG123_Close(void)
{
Oct 18, 2017
Oct 18, 2017
411
mpg123.mpg123_exit();
Oct 17, 2017
Oct 17, 2017
412
413
414
415
416
417
418
419
420
421
}
Mix_MusicInterface Mix_MusicInterface_MPG123 =
{
"MPG123",
MIX_MUSIC_MPG123,
MUS_MP3,
SDL_FALSE,
SDL_FALSE,
Oct 18, 2017
Oct 18, 2017
422
MPG123_Load,
Oct 17, 2017
Oct 17, 2017
423
424
425
426
427
MPG123_Open,
MPG123_CreateFromRW,
NULL, /* CreateFromFile */
MPG123_SetVolume,
MPG123_Play,
Oct 21, 2017
Oct 21, 2017
428
NULL, /* IsPlaying */
Oct 17, 2017
Oct 17, 2017
429
430
431
432
MPG123_GetAudio,
MPG123_Seek,
NULL, /* Pause */
NULL, /* Resume */
Oct 21, 2017
Oct 21, 2017
433
NULL, /* Stop */
Oct 17, 2017
Oct 17, 2017
434
435
MPG123_Delete,
MPG123_Close,
Oct 18, 2017
Oct 18, 2017
436
MPG123_Unload
Oct 17, 2017
Oct 17, 2017
437
438
439
440
441
};
#endif /* MUSIC_MP3_MPG123 */
/* vi: set ts=4 sw=4 expandtab: */