Skip to content

Latest commit

 

History

History
432 lines (371 loc) · 12.6 KB

music_mpg123.c

File metadata and controls

432 lines (371 loc) · 12.6 KB
 
Jul 20, 2017
Jul 20, 2017
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
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
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))
Oct 21, 2017
Oct 21, 2017
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
{
Oct 21, 2017
Oct 21, 2017
125
int play_count;
Oct 17, 2017
Oct 17, 2017
126
127
128
129
130
SDL_RWops* src;
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)
{
Jul 20, 2017
Jul 20, 2017
187
188
189
return (ssize_t)SDL_RWread((SDL_RWops*)p, dst, 1, n);
}
Oct 21, 2017
Oct 21, 2017
190
191
static off_t rwops_seek(void* p, off_t offset, int whence)
{
Jul 20, 2017
Jul 20, 2017
192
193
194
return (off_t)SDL_RWseek((SDL_RWops*)p, (Sint64)offset, whence);
}
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)
{
Oct 18, 2017
Oct 18, 2017
204
if (mpg123.mpg123_init() != MPG123_OK) {
Oct 17, 2017
Oct 17, 2017
205
206
207
208
209
210
211
Mix_SetError("mpg123_init() failed");
return -1;
}
return 0;
}
static void *MPG123_CreateFromRW(SDL_RWops *src, int freesrc)
Jul 20, 2017
Jul 20, 2017
212
{
Oct 21, 2017
Oct 21, 2017
213
MPG123_Music *music;
Jul 20, 2017
Jul 20, 2017
214
int result;
Oct 21, 2017
Oct 21, 2017
215
216
const long *rates;
size_t i, num_rates;
Jul 20, 2017
Jul 20, 2017
217
Oct 21, 2017
Oct 21, 2017
218
219
220
221
222
223
224
225
226
227
228
229
230
231
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
232
233
}
Oct 21, 2017
Oct 21, 2017
234
music->handle = mpg123.mpg123_new(0, &result);
Jul 20, 2017
Jul 20, 2017
235
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
236
237
238
MPG123_Delete(music);
Mix_SetError("mpg123_new failed");
return NULL;
Jul 20, 2017
Jul 20, 2017
239
240
}
Oct 18, 2017
Oct 18, 2017
241
result = mpg123.mpg123_replace_reader_handle(
Oct 21, 2017
Oct 21, 2017
242
music->handle,
Jul 20, 2017
Jul 20, 2017
243
rwops_read, rwops_seek, rwops_cleanup
Oct 21, 2017
Oct 21, 2017
244
);
Jul 20, 2017
Jul 20, 2017
245
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
246
247
248
MPG123_Delete(music);
Mix_SetError("mpg123_replace_reader_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
249
250
}
Oct 21, 2017
Oct 21, 2017
251
result = mpg123.mpg123_format_none(music->handle);
Jul 20, 2017
Jul 20, 2017
252
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
253
254
255
MPG123_Delete(music);
Mix_SetError("mpg123_format_none: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
256
257
}
Oct 21, 2017
Oct 21, 2017
258
259
260
261
262
263
264
265
266
267
268
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
269
270
}
Oct 21, 2017
Oct 21, 2017
271
result = mpg123.mpg123_open_handle(music->handle, music->src);
Jul 20, 2017
Jul 20, 2017
272
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
273
274
275
MPG123_Delete(music);
Mix_SetError("mpg123_open_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
276
277
}
Oct 21, 2017
Oct 21, 2017
278
279
music->freesrc = freesrc;
return music;
Jul 20, 2017
Jul 20, 2017
280
281
}
Oct 21, 2017
Oct 21, 2017
282
static void MPG123_SetVolume(void *context, int volume)
Oct 17, 2017
Oct 17, 2017
283
{
Oct 21, 2017
Oct 21, 2017
284
285
MPG123_Music *music = (MPG123_Music *)context;
music->volume = volume;
Jul 20, 2017
Jul 20, 2017
286
287
}
Oct 21, 2017
Oct 21, 2017
288
static int MPG123_Play(void *context, int play_count)
Oct 17, 2017
Oct 17, 2017
289
{
Oct 21, 2017
Oct 21, 2017
290
291
292
MPG123_Music *music = (MPG123_Music *)context;
music->play_count = play_count;
return MPG123_Seek(music, 0.0);
Jul 20, 2017
Jul 20, 2017
293
294
}
Oct 21, 2017
Oct 21, 2017
295
296
/* 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
297
{
Oct 21, 2017
Oct 21, 2017
298
299
300
MPG123_Music *music = (MPG123_Music *)context;
int filled, result;
size_t amount;
Jul 20, 2017
Jul 20, 2017
301
long rate;
Oct 21, 2017
Oct 21, 2017
302
int channels, encoding, format;
Jul 20, 2017
Jul 20, 2017
303
Oct 21, 2017
Oct 21, 2017
304
305
306
307
308
if (music->stream) {
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
}
Jul 20, 2017
Jul 20, 2017
309
310
}
Oct 21, 2017
Oct 21, 2017
311
312
313
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
Jul 20, 2017
Jul 20, 2017
314
315
316
return 0;
}
Oct 21, 2017
Oct 21, 2017
317
318
319
320
321
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
322
}
Oct 21, 2017
Oct 21, 2017
323
break;
Jul 20, 2017
Jul 20, 2017
324
Oct 21, 2017
Oct 21, 2017
325
326
327
328
329
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
330
}
Oct 21, 2017
Oct 21, 2017
331
/*printf("MPG123 format: %s, channels = %d, rate = %ld\n", mpg123_format_str(encoding), channels, rate);*/
Jul 20, 2017
Jul 20, 2017
332
Oct 21, 2017
Oct 21, 2017
333
334
format = mpg123_format_to_sdl(encoding);
SDL_assert(format != -1);
Jul 20, 2017
Jul 20, 2017
335
Oct 21, 2017
Oct 21, 2017
336
337
338
339
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
340
}
Oct 21, 2017
Oct 21, 2017
341
342
343
344
345
346
347
348
349
350
351
352
353
354
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
355
}
Oct 21, 2017
Oct 21, 2017
356
357
358
359
break;
default:
Mix_SetError("mpg123_read: %s", mpg_err(music->handle, result));
return -1;
Jul 20, 2017
Jul 20, 2017
360
}
Oct 21, 2017
Oct 21, 2017
361
362
363
364
365
366
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
367
368
}
Oct 17, 2017
Oct 17, 2017
369
static int MPG123_Seek(void *context, double secs)
Jul 20, 2017
Jul 20, 2017
370
{
Oct 21, 2017
Oct 21, 2017
371
372
MPG123_Music *music = (MPG123_Music *)context;
off_t offset = (off_t)(music_spec.freq * secs);
Jul 20, 2017
Jul 20, 2017
373
Oct 21, 2017
Oct 21, 2017
374
375
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
376
}
Oct 17, 2017
Oct 17, 2017
377
return 0;
Jul 20, 2017
Jul 20, 2017
378
379
}
Oct 17, 2017
Oct 17, 2017
380
381
static void MPG123_Delete(void *context)
{
Oct 21, 2017
Oct 21, 2017
382
MPG123_Music *music = (MPG123_Music *)context;
Jul 20, 2017
Jul 20, 2017
383
Oct 21, 2017
Oct 21, 2017
384
385
386
if (music->handle) {
mpg123.mpg123_close(music->handle);
mpg123.mpg123_delete(music->handle);
Oct 17, 2017
Oct 17, 2017
387
}
Oct 21, 2017
Oct 21, 2017
388
389
if (music->stream) {
SDL_FreeAudioStream(music->stream);
Oct 17, 2017
Oct 17, 2017
390
}
Oct 21, 2017
Oct 21, 2017
391
392
393
394
395
396
397
if (music->buffer) {
SDL_free(music->buffer);
}
if (music->freesrc) {
SDL_RWclose(music->src);
}
SDL_free(music);
Oct 17, 2017
Oct 17, 2017
398
399
400
401
}
static void MPG123_Close(void)
{
Oct 18, 2017
Oct 18, 2017
402
mpg123.mpg123_exit();
Oct 17, 2017
Oct 17, 2017
403
404
405
406
407
408
409
410
411
412
}
Mix_MusicInterface Mix_MusicInterface_MPG123 =
{
"MPG123",
MIX_MUSIC_MPG123,
MUS_MP3,
SDL_FALSE,
SDL_FALSE,
Oct 18, 2017
Oct 18, 2017
413
MPG123_Load,
Oct 17, 2017
Oct 17, 2017
414
415
416
417
418
MPG123_Open,
MPG123_CreateFromRW,
NULL, /* CreateFromFile */
MPG123_SetVolume,
MPG123_Play,
Oct 21, 2017
Oct 21, 2017
419
NULL, /* IsPlaying */
Oct 17, 2017
Oct 17, 2017
420
421
422
423
MPG123_GetAudio,
MPG123_Seek,
NULL, /* Pause */
NULL, /* Resume */
Oct 21, 2017
Oct 21, 2017
424
NULL, /* Stop */
Oct 17, 2017
Oct 17, 2017
425
426
MPG123_Delete,
MPG123_Close,
Oct 18, 2017
Oct 18, 2017
427
MPG123_Unload
Oct 17, 2017
Oct 17, 2017
428
429
430
431
432
};
#endif /* MUSIC_MP3_MPG123 */
/* vi: set ts=4 sw=4 expandtab: */