Skip to content

Latest commit

 

History

History
470 lines (405 loc) · 13.9 KB

music_mpg123.c

File metadata and controls

470 lines (405 loc) · 13.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
SDL_AudioStream *stream;
unsigned char *buffer;
size_t buffer_size;
Dec 17, 2019
Dec 17, 2019
134
long sample_rate;
Oct 21, 2017
Oct 21, 2017
135
} MPG123_Music;
Oct 17, 2017
Oct 17, 2017
136
Jul 20, 2017
Jul 20, 2017
137
Oct 21, 2017
Oct 21, 2017
138
139
static int MPG123_Seek(void *context, double secs);
static void MPG123_Delete(void *context);
Jul 20, 2017
Jul 20, 2017
140
Dec 17, 2019
Dec 17, 2019
141
Oct 21, 2017
Oct 21, 2017
142
static int mpg123_format_to_sdl(int fmt)
Jul 20, 2017
Jul 20, 2017
143
144
145
{
switch (fmt)
{
Oct 21, 2017
Oct 21, 2017
146
147
148
149
150
151
152
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
153
154
155
}
}
Dec 17, 2019
Dec 17, 2019
156
157
/*#define DEBUG_MPG123*/
#ifdef DEBUG_MPG123
Oct 21, 2017
Oct 21, 2017
158
static const char *mpg123_format_str(int fmt)
Jul 20, 2017
Jul 20, 2017
159
160
161
162
163
164
165
166
167
{
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
168
f(MPG123_ENC_FLOAT_32)
Jul 20, 2017
Jul 20, 2017
169
170
171
172
#undef f
}
return "unknown";
}
Dec 17, 2019
Dec 17, 2019
173
#endif
Jul 20, 2017
Jul 20, 2017
174
Oct 21, 2017
Oct 21, 2017
175
static char const* mpg_err(mpg123_handle* mpg, int result)
Jul 20, 2017
Jul 20, 2017
176
177
178
{
char const* err = "unknown error";
Oct 21, 2017
Oct 21, 2017
179
if (mpg && result == MPG123_ERR) {
Oct 18, 2017
Oct 18, 2017
180
err = mpg123.mpg123_strerror(mpg);
Jul 20, 2017
Jul 20, 2017
181
} else {
Oct 21, 2017
Oct 21, 2017
182
err = mpg123.mpg123_plain_strerror(result);
Jul 20, 2017
Jul 20, 2017
183
184
185
186
187
}
return err;
}
/* we're gonna override mpg123's I/O with these wrappers for RWops */
Oct 21, 2017
Oct 21, 2017
188
189
static ssize_t rwops_read(void* p, void* dst, size_t n)
{
Dec 10, 2019
Dec 10, 2019
190
return (ssize_t)MP3_RWread((struct mp3file_t *)p, dst, 1, n);
Jul 20, 2017
Jul 20, 2017
191
192
}
Oct 21, 2017
Oct 21, 2017
193
194
static off_t rwops_seek(void* p, off_t offset, int whence)
{
Dec 10, 2019
Dec 10, 2019
195
return (off_t)MP3_RWseek((struct mp3file_t *)p, (Sint64)offset, whence);
Jul 20, 2017
Jul 20, 2017
196
197
}
Oct 21, 2017
Oct 21, 2017
198
199
static void rwops_cleanup(void* p)
{
Jul 20, 2017
Jul 20, 2017
200
201
202
203
(void)p;
/* do nothing, we will free the file later */
}
Oct 17, 2017
Oct 17, 2017
204
205
206
static int MPG123_Open(const SDL_AudioSpec *spec)
{
Nov 17, 2019
Nov 17, 2019
207
(void)spec;
Oct 18, 2017
Oct 18, 2017
208
if (mpg123.mpg123_init() != MPG123_OK) {
Oct 17, 2017
Oct 17, 2017
209
210
211
212
213
214
215
Mix_SetError("mpg123_init() failed");
return -1;
}
return 0;
}
static void *MPG123_CreateFromRW(SDL_RWops *src, int freesrc)
Jul 20, 2017
Jul 20, 2017
216
{
Oct 21, 2017
Oct 21, 2017
217
MPG123_Music *music;
Dec 17, 2019
Dec 17, 2019
218
219
int result, format, channels, encoding;
long rate;
Oct 21, 2017
Oct 21, 2017
220
221
const long *rates;
size_t i, num_rates;
Jul 20, 2017
Jul 20, 2017
222
Oct 21, 2017
Oct 21, 2017
223
224
225
226
music = (MPG123_Music*)SDL_calloc(1, sizeof(*music));
if (!music) {
return NULL;
}
Dec 10, 2019
Dec 10, 2019
227
music->mp3file.src = src;
Oct 21, 2017
Oct 21, 2017
228
229
music->volume = MIX_MAX_VOLUME;
Dec 10, 2019
Dec 10, 2019
230
231
232
233
234
235
236
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;
}
Oct 21, 2017
Oct 21, 2017
237
238
239
240
241
242
243
/* 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
244
245
}
Oct 21, 2017
Oct 21, 2017
246
music->handle = mpg123.mpg123_new(0, &result);
Jul 20, 2017
Jul 20, 2017
247
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
248
249
250
MPG123_Delete(music);
Mix_SetError("mpg123_new failed");
return NULL;
Jul 20, 2017
Jul 20, 2017
251
252
}
Oct 18, 2017
Oct 18, 2017
253
result = mpg123.mpg123_replace_reader_handle(
Oct 21, 2017
Oct 21, 2017
254
music->handle,
Jul 20, 2017
Jul 20, 2017
255
rwops_read, rwops_seek, rwops_cleanup
Oct 21, 2017
Oct 21, 2017
256
);
Jul 20, 2017
Jul 20, 2017
257
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
258
259
260
MPG123_Delete(music);
Mix_SetError("mpg123_replace_reader_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
261
262
}
Oct 21, 2017
Oct 21, 2017
263
result = mpg123.mpg123_format_none(music->handle);
Jul 20, 2017
Jul 20, 2017
264
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
265
266
267
MPG123_Delete(music);
Mix_SetError("mpg123_format_none: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
268
269
}
Oct 21, 2017
Oct 21, 2017
270
271
272
273
274
275
276
277
278
279
280
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
281
282
}
Dec 10, 2019
Dec 10, 2019
283
result = mpg123.mpg123_open_handle(music->handle, &music->mp3file);
Jul 20, 2017
Jul 20, 2017
284
if (result != MPG123_OK) {
Oct 21, 2017
Oct 21, 2017
285
286
287
MPG123_Delete(music);
Mix_SetError("mpg123_open_handle: %s", mpg_err(music->handle, result));
return NULL;
Jul 20, 2017
Jul 20, 2017
288
289
}
Dec 17, 2019
Dec 17, 2019
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
result = mpg123.mpg123_getformat(music->handle, &rate, &channels, &encoding);
if (result != MPG123_OK) {
MPG123_Delete(music);
Mix_SetError("mpg123_getformat: %s", mpg_err(music->handle, result));
return NULL;
}
#ifdef DEBUG_MPG123
printf("MPG123 format: %s, channels: %d, rate: %ld\n",
mpg123_format_str(encoding), channels, rate);
#endif
format = mpg123_format_to_sdl(encoding);
SDL_assert(format != -1);
music->sample_rate = rate;
music->stream = SDL_NewAudioStream((SDL_AudioFormat)format, (Uint8)channels, (int)rate,
music_spec.format, music_spec.channels, music_spec.freq);
if (!music->stream) {
MPG123_Delete(music);
return NULL;
}
Oct 21, 2017
Oct 21, 2017
312
313
music->freesrc = freesrc;
return music;
Jul 20, 2017
Jul 20, 2017
314
315
}
Oct 21, 2017
Oct 21, 2017
316
static void MPG123_SetVolume(void *context, int volume)
Oct 17, 2017
Oct 17, 2017
317
{
Oct 21, 2017
Oct 21, 2017
318
319
MPG123_Music *music = (MPG123_Music *)context;
music->volume = volume;
Jul 20, 2017
Jul 20, 2017
320
321
}
Oct 21, 2017
Oct 21, 2017
322
static int MPG123_Play(void *context, int play_count)
Oct 17, 2017
Oct 17, 2017
323
{
Oct 21, 2017
Oct 21, 2017
324
325
326
MPG123_Music *music = (MPG123_Music *)context;
music->play_count = play_count;
return MPG123_Seek(music, 0.0);
Jul 20, 2017
Jul 20, 2017
327
328
}
Oct 21, 2017
Oct 21, 2017
329
330
/* 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
331
{
Oct 21, 2017
Oct 21, 2017
332
333
334
MPG123_Music *music = (MPG123_Music *)context;
int filled, result;
size_t amount;
Jul 20, 2017
Jul 20, 2017
335
long rate;
Oct 21, 2017
Oct 21, 2017
336
int channels, encoding, format;
Jul 20, 2017
Jul 20, 2017
337
Oct 21, 2017
Oct 21, 2017
338
339
340
341
342
if (music->stream) {
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
}
Jul 20, 2017
Jul 20, 2017
343
344
}
Oct 21, 2017
Oct 21, 2017
345
346
347
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
Jul 20, 2017
Jul 20, 2017
348
349
350
return 0;
}
Oct 21, 2017
Oct 21, 2017
351
352
353
354
355
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
356
}
Oct 21, 2017
Oct 21, 2017
357
break;
Jul 20, 2017
Jul 20, 2017
358
Oct 21, 2017
Oct 21, 2017
359
360
361
362
363
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
364
}
Dec 17, 2019
Dec 17, 2019
365
366
367
368
#ifdef DEBUG_MPG123
printf("MPG123 format: %s, channels: %d, rate: %ld\n",
mpg123_format_str(encoding), channels, rate);
#endif
Jul 20, 2017
Jul 20, 2017
369
Oct 21, 2017
Oct 21, 2017
370
371
format = mpg123_format_to_sdl(encoding);
SDL_assert(format != -1);
Jul 20, 2017
Jul 20, 2017
372
Nov 17, 2019
Nov 17, 2019
373
music->stream = SDL_NewAudioStream((SDL_AudioFormat)format, (Uint8)channels, (int)rate,
Oct 21, 2017
Oct 21, 2017
374
375
376
music_spec.format, music_spec.channels, music_spec.freq);
if (!music->stream) {
return -1;
Jul 20, 2017
Jul 20, 2017
377
}
Dec 17, 2019
Dec 17, 2019
378
music->sample_rate = rate;
Oct 21, 2017
Oct 21, 2017
379
380
381
382
383
384
385
386
387
388
389
390
391
392
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
393
}
Oct 21, 2017
Oct 21, 2017
394
395
396
397
break;
default:
Mix_SetError("mpg123_read: %s", mpg_err(music->handle, result));
return -1;
Jul 20, 2017
Jul 20, 2017
398
}
Oct 21, 2017
Oct 21, 2017
399
400
401
402
403
404
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
405
406
}
Oct 17, 2017
Oct 17, 2017
407
static int MPG123_Seek(void *context, double secs)
Jul 20, 2017
Jul 20, 2017
408
{
Oct 21, 2017
Oct 21, 2017
409
MPG123_Music *music = (MPG123_Music *)context;
Dec 17, 2019
Dec 17, 2019
410
off_t offset = (off_t)(music->sample_rate * secs);
Jul 20, 2017
Jul 20, 2017
411
Oct 21, 2017
Oct 21, 2017
412
413
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
414
}
Oct 17, 2017
Oct 17, 2017
415
return 0;
Jul 20, 2017
Jul 20, 2017
416
417
}
Oct 17, 2017
Oct 17, 2017
418
419
static void MPG123_Delete(void *context)
{
Oct 21, 2017
Oct 21, 2017
420
MPG123_Music *music = (MPG123_Music *)context;
Jul 20, 2017
Jul 20, 2017
421
Oct 21, 2017
Oct 21, 2017
422
423
424
if (music->handle) {
mpg123.mpg123_close(music->handle);
mpg123.mpg123_delete(music->handle);
Oct 17, 2017
Oct 17, 2017
425
}
Oct 21, 2017
Oct 21, 2017
426
427
if (music->stream) {
SDL_FreeAudioStream(music->stream);
Oct 17, 2017
Oct 17, 2017
428
}
Oct 21, 2017
Oct 21, 2017
429
430
431
432
if (music->buffer) {
SDL_free(music->buffer);
}
if (music->freesrc) {
Dec 10, 2019
Dec 10, 2019
433
SDL_RWclose(music->mp3file.src);
Oct 21, 2017
Oct 21, 2017
434
435
}
SDL_free(music);
Oct 17, 2017
Oct 17, 2017
436
437
438
439
}
static void MPG123_Close(void)
{
Oct 18, 2017
Oct 18, 2017
440
mpg123.mpg123_exit();
Oct 17, 2017
Oct 17, 2017
441
442
443
444
445
446
447
448
449
450
}
Mix_MusicInterface Mix_MusicInterface_MPG123 =
{
"MPG123",
MIX_MUSIC_MPG123,
MUS_MP3,
SDL_FALSE,
SDL_FALSE,
Oct 18, 2017
Oct 18, 2017
451
MPG123_Load,
Oct 17, 2017
Oct 17, 2017
452
453
454
455
456
MPG123_Open,
MPG123_CreateFromRW,
NULL, /* CreateFromFile */
MPG123_SetVolume,
MPG123_Play,
Oct 21, 2017
Oct 21, 2017
457
NULL, /* IsPlaying */
Oct 17, 2017
Oct 17, 2017
458
459
460
461
MPG123_GetAudio,
MPG123_Seek,
NULL, /* Pause */
NULL, /* Resume */
Oct 21, 2017
Oct 21, 2017
462
NULL, /* Stop */
Oct 17, 2017
Oct 17, 2017
463
464
MPG123_Delete,
MPG123_Close,
Oct 18, 2017
Oct 18, 2017
465
MPG123_Unload
Oct 17, 2017
Oct 17, 2017
466
467
468
469
470
};
#endif /* MUSIC_MP3_MPG123 */
/* vi: set ts=4 sw=4 expandtab: */