Skip to content

Latest commit

 

History

History
567 lines (497 loc) · 18.8 KB

music_flac.c

File metadata and controls

567 lines (497 loc) · 18.8 KB
 
Dec 31, 2011
Dec 31, 2011
2
SDL_mixer: An audio mixer library based on the SDL library
Jan 2, 2017
Jan 2, 2017
3
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Dec 31, 2011
Dec 31, 2011
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.
This file is used to support SDL_LoadMUS playback of FLAC files.
May 22, 2013
May 22, 2013
22
~ Austen Dicken (admin@cvpcs.org)
23
24
*/
Oct 17, 2017
Oct 17, 2017
25
#ifdef MUSIC_FLAC
Oct 21, 2017
Oct 21, 2017
27
#include "SDL_assert.h"
Oct 17, 2017
Oct 17, 2017
28
#include "SDL_loadso.h"
29
30
31
#include "music_flac.h"
Oct 17, 2017
Oct 17, 2017
32
33
34
35
36
37
#include <FLAC/stream_decoder.h>
typedef struct {
int loaded;
void *handle;
Oct 18, 2017
Oct 18, 2017
38
FLAC__StreamDecoder *(*FLAC__stream_decoder_new)(void);
Oct 17, 2017
Oct 17, 2017
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
void (*FLAC__stream_decoder_delete)(FLAC__StreamDecoder *decoder);
FLAC__StreamDecoderInitStatus (*FLAC__stream_decoder_init_stream)(
FLAC__StreamDecoder *decoder,
FLAC__StreamDecoderReadCallback read_callback,
FLAC__StreamDecoderSeekCallback seek_callback,
FLAC__StreamDecoderTellCallback tell_callback,
FLAC__StreamDecoderLengthCallback length_callback,
FLAC__StreamDecoderEofCallback eof_callback,
FLAC__StreamDecoderWriteCallback write_callback,
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data);
FLAC__bool (*FLAC__stream_decoder_finish)(FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_flush)(FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_single)(
FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_until_end_of_metadata)(
FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_until_end_of_stream)(
FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_seek_absolute)(
FLAC__StreamDecoder *decoder,
FLAC__uint64 sample);
FLAC__StreamDecoderState (*FLAC__stream_decoder_get_state)(
const FLAC__StreamDecoder *decoder);
} flac_loader;
static flac_loader flac = {
0, NULL
};
#ifdef FLAC_DYNAMIC
Oct 21, 2017
Oct 21, 2017
71
72
73
74
75
76
77
#define FUNCTION_LOADER(FUNC, SIG) \
flac.FUNC = (SIG) SDL_LoadFunction(flac.handle, #FUNC); \
if (flac.FUNC == NULL) { SDL_UnloadObject(flac.handle); return -1; }
#else
#define FUNCTION_LOADER(FUNC, SIG) \
flac.FUNC = FUNC;
#endif
Oct 17, 2017
Oct 17, 2017
78
Oct 18, 2017
Oct 18, 2017
79
static int FLAC_Load(void)
Oct 17, 2017
Oct 17, 2017
80
81
{
if (flac.loaded == 0) {
Oct 21, 2017
Oct 21, 2017
82
#ifdef FLAC_DYNAMIC
Oct 17, 2017
Oct 17, 2017
83
84
85
86
flac.handle = SDL_LoadObject(FLAC_DYNAMIC);
if (flac.handle == NULL) {
return -1;
}
Oct 21, 2017
Oct 21, 2017
87
88
89
90
91
92
#elif defined(__MACOSX__)
extern FLAC__StreamDecoder *FLAC__stream_decoder_new(void) __attribute__((weak_import));
if (FLAC__stream_decoder_new == NULL)
{
/* Missing weakly linked framework */
Mix_SetError("Missing FLAC.framework");
Oct 17, 2017
Oct 17, 2017
93
94
return -1;
}
Oct 21, 2017
Oct 21, 2017
95
96
97
98
99
#endif
FUNCTION_LOADER(FLAC__stream_decoder_new, FLAC__StreamDecoder *(*)(void))
FUNCTION_LOADER(FLAC__stream_decoder_delete, void (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_init_stream, FLAC__StreamDecoderInitStatus (*)(
Oct 17, 2017
Oct 17, 2017
100
101
102
103
104
105
106
107
108
109
FLAC__StreamDecoder *,
FLAC__StreamDecoderReadCallback,
FLAC__StreamDecoderSeekCallback,
FLAC__StreamDecoderTellCallback,
FLAC__StreamDecoderLengthCallback,
FLAC__StreamDecoderEofCallback,
FLAC__StreamDecoderWriteCallback,
FLAC__StreamDecoderMetadataCallback,
FLAC__StreamDecoderErrorCallback,
void *))
Oct 21, 2017
Oct 21, 2017
110
111
112
113
114
115
116
FUNCTION_LOADER(FLAC__stream_decoder_finish, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_flush, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_process_single, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_process_until_end_of_metadata, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_process_until_end_of_stream, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_seek_absolute, FLAC__bool (*)(FLAC__StreamDecoder *, FLAC__uint64))
FUNCTION_LOADER(FLAC__stream_decoder_get_state, FLAC__StreamDecoderState (*)(const FLAC__StreamDecoder *decoder))
Oct 17, 2017
Oct 17, 2017
117
118
}
++flac.loaded;
Oct 17, 2017
Oct 17, 2017
120
121
122
123
return 0;
}
static void FLAC_Unload(void)
Oct 3, 2009
Oct 3, 2009
124
{
Oct 17, 2017
Oct 17, 2017
125
126
127
128
if (flac.loaded == 0) {
return;
}
if (flac.loaded == 1) {
Oct 21, 2017
Oct 21, 2017
129
#ifdef FLAC_DYNAMIC
Oct 17, 2017
Oct 17, 2017
130
SDL_UnloadObject(flac.handle);
Oct 21, 2017
Oct 21, 2017
131
#endif
Oct 17, 2017
Oct 17, 2017
132
133
}
--flac.loaded;
134
135
}
Oct 17, 2017
Oct 17, 2017
136
137
typedef struct {
Oct 21, 2017
Oct 21, 2017
138
139
140
int volume;
int play_count;
FLAC__StreamDecoder *flac_decoder;
Oct 17, 2017
Oct 17, 2017
141
142
143
144
145
unsigned sample_rate;
unsigned channels;
unsigned bits_per_sample;
SDL_RWops *src;
int freesrc;
Oct 21, 2017
Oct 21, 2017
146
147
SDL_AudioStream *stream;
} FLAC_Music;
Oct 17, 2017
Oct 17, 2017
148
149
Oct 21, 2017
Oct 21, 2017
150
151
static int FLAC_Seek(void *context, double position);
152
static FLAC__StreamDecoderReadStatus flac_read_music_cb(
May 22, 2013
May 22, 2013
153
154
155
156
const FLAC__StreamDecoder *decoder,
FLAC__byte buffer[],
size_t *bytes,
void *client_data)
Oct 3, 2009
Oct 3, 2009
157
{
Oct 21, 2017
Oct 21, 2017
158
FLAC_Music *data = (FLAC_Music*)client_data;
May 22, 2013
May 22, 2013
159
Oct 21, 2017
Oct 21, 2017
160
/* make sure there is something to be reading */
May 22, 2013
May 22, 2013
161
if (*bytes > 0) {
Jun 2, 2013
Jun 2, 2013
162
*bytes = SDL_RWread (data->src, buffer, sizeof (FLAC__byte), *bytes);
May 22, 2013
May 22, 2013
163
Oct 21, 2017
Oct 21, 2017
164
if (*bytes == 0) { /* error or no data was read (EOF) */
May 22, 2013
May 22, 2013
165
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
Oct 21, 2017
Oct 21, 2017
166
} else { /* data was read, continue */
May 22, 2013
May 22, 2013
167
168
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
Jun 1, 2013
Jun 1, 2013
169
} else {
May 22, 2013
May 22, 2013
170
171
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
}
172
173
174
}
static FLAC__StreamDecoderSeekStatus flac_seek_music_cb(
May 22, 2013
May 22, 2013
175
176
177
const FLAC__StreamDecoder *decoder,
FLAC__uint64 absolute_byte_offset,
void *client_data)
Oct 3, 2009
Oct 3, 2009
178
{
Oct 21, 2017
Oct 21, 2017
179
FLAC_Music *data = (FLAC_Music*)client_data;
May 22, 2013
May 22, 2013
180
Oct 21, 2017
Oct 21, 2017
181
if (SDL_RWseek(data->src, absolute_byte_offset, RW_SEEK_SET) < 0) {
May 22, 2013
May 22, 2013
182
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
Jun 1, 2013
Jun 1, 2013
183
} else {
May 22, 2013
May 22, 2013
184
185
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
186
187
188
}
static FLAC__StreamDecoderTellStatus flac_tell_music_cb(
May 22, 2013
May 22, 2013
189
190
const FLAC__StreamDecoder *decoder,
FLAC__uint64 *absolute_byte_offset,
Oct 17, 2017
Oct 17, 2017
191
void *client_data)
Oct 3, 2009
Oct 3, 2009
192
{
Oct 21, 2017
Oct 21, 2017
193
FLAC_Music *data = (FLAC_Music*)client_data;
Oct 21, 2017
Oct 21, 2017
195
Sint64 pos = SDL_RWtell(data->src);
May 22, 2013
May 22, 2013
197
198
if (pos < 0) {
return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
Jun 1, 2013
Jun 1, 2013
199
} else {
May 22, 2013
May 22, 2013
200
201
202
*absolute_byte_offset = (FLAC__uint64)pos;
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
203
204
}
Oct 21, 2017
Oct 21, 2017
205
static FLAC__StreamDecoderLengthStatus flac_length_music_cb(
May 22, 2013
May 22, 2013
206
207
208
const FLAC__StreamDecoder *decoder,
FLAC__uint64 *stream_length,
void *client_data)
Oct 3, 2009
Oct 3, 2009
209
{
Oct 21, 2017
Oct 21, 2017
210
FLAC_Music *data = (FLAC_Music*)client_data;
May 22, 2013
May 22, 2013
211
Oct 21, 2017
Oct 21, 2017
212
213
Sint64 pos = SDL_RWtell(data->src);
Sint64 length = SDL_RWseek(data->src, 0, RW_SEEK_END);
May 22, 2013
May 22, 2013
214
Oct 21, 2017
Oct 21, 2017
215
if (SDL_RWseek(data->src, pos, RW_SEEK_SET) != pos || length < 0) {
May 22, 2013
May 22, 2013
216
217
218
/* there was an error attempting to return the stream to the original
* position, or the length was invalid. */
return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
Jun 1, 2013
Jun 1, 2013
219
} else {
May 22, 2013
May 22, 2013
220
221
222
*stream_length = (FLAC__uint64)length;
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
223
224
225
}
static FLAC__bool flac_eof_music_cb(
May 22, 2013
May 22, 2013
226
const FLAC__StreamDecoder *decoder,
Oct 17, 2017
Oct 17, 2017
227
void *client_data)
Oct 3, 2009
Oct 3, 2009
228
{
Oct 21, 2017
Oct 21, 2017
229
FLAC_Music *data = (FLAC_Music*)client_data;
May 22, 2013
May 22, 2013
230
Oct 21, 2017
Oct 21, 2017
231
232
Sint64 pos = SDL_RWtell(data->src);
Sint64 end = SDL_RWseek(data->src, 0, RW_SEEK_END);
May 22, 2013
May 22, 2013
233
Oct 21, 2017
Oct 21, 2017
234
/* was the original position equal to the end (a.k.a. the seek didn't move)? */
May 22, 2013
May 22, 2013
235
if (pos == end) {
Oct 21, 2017
Oct 21, 2017
236
/* must be EOF */
May 22, 2013
May 22, 2013
237
return true;
Jun 1, 2013
Jun 1, 2013
238
} else {
Oct 21, 2017
Oct 21, 2017
239
240
/* not EOF, return to the original position */
SDL_RWseek(data->src, pos, RW_SEEK_SET);
May 22, 2013
May 22, 2013
241
242
return false;
}
243
244
245
}
static FLAC__StreamDecoderWriteStatus flac_write_music_cb(
May 22, 2013
May 22, 2013
246
247
248
249
const FLAC__StreamDecoder *decoder,
const FLAC__Frame *frame,
const FLAC__int32 *const buffer[],
void *client_data)
Oct 3, 2009
Oct 3, 2009
250
{
Oct 21, 2017
Oct 21, 2017
251
252
FLAC_Music *music = (FLAC_Music *)client_data;
Sint16 *data;
Oct 21, 2017
Oct 21, 2017
253
unsigned int i, j, channels;
Oct 21, 2017
Oct 21, 2017
254
int shift_amount = 0;
May 22, 2013
May 22, 2013
255
Oct 21, 2017
Oct 21, 2017
256
if (!music->stream) {
May 22, 2013
May 22, 2013
257
258
259
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
Oct 21, 2017
Oct 21, 2017
260
261
262
263
264
265
266
267
268
269
270
271
switch (music->bits_per_sample) {
case 16:
shift_amount = 0;
break;
case 20:
shift_amount = 4;
break;
case 24:
shift_amount = 8;
break;
default:
SDL_SetError("FLAC decoder doesn't support %d bits_per_sample", music->bits_per_sample);
May 22, 2013
May 22, 2013
272
273
274
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
Oct 21, 2017
Oct 21, 2017
275
276
277
278
279
280
if (music->channels == 3) {
/* We'll just drop the center channel for now */
channels = 2;
} else {
channels = music->channels;
}
May 22, 2013
May 22, 2013
281
Oct 21, 2017
Oct 21, 2017
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
data = SDL_stack_alloc(Sint16, (frame->header.blocksize * channels));
if (!data) {
SDL_SetError("Couldn't allocate %d bytes stack memory", (int)(frame->header.blocksize * channels * sizeof(*data)));
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
if (music->channels == 3) {
Sint16 *dst = data;
for (i = 0; i < frame->header.blocksize; ++i) {
Sint16 FL = (buffer[0][i] >> shift_amount);
Sint16 FR = (buffer[1][i] >> shift_amount);
Sint16 FCmix = (Sint16)((buffer[2][i] >> shift_amount) * 0.5f);
int sample;
sample = (FL + FCmix);
if (sample > SDL_MAX_SINT16) {
*dst = SDL_MAX_SINT16;
} else if (sample < SDL_MIN_SINT16) {
*dst = SDL_MIN_SINT16;
} else {
*dst = sample;
}
++dst;
May 22, 2013
May 22, 2013
304
Oct 21, 2017
Oct 21, 2017
305
306
307
308
309
310
311
sample = (FR + FCmix);
if (sample > SDL_MAX_SINT16) {
*dst = SDL_MAX_SINT16;
} else if (sample < SDL_MIN_SINT16) {
*dst = SDL_MIN_SINT16;
} else {
*dst = sample;
May 22, 2013
May 22, 2013
312
}
Oct 21, 2017
Oct 21, 2017
313
314
315
316
317
318
319
320
++dst;
}
} else {
for (i = 0; i < channels; ++i) {
Sint16 *dst = data + i;
for (j = 0; j < frame->header.blocksize; ++j) {
*dst = (buffer[i][j] >> shift_amount);
dst += channels;
May 22, 2013
May 22, 2013
321
322
323
}
}
}
Oct 21, 2017
Oct 21, 2017
324
325
SDL_AudioStreamPut(music->stream, data, (frame->header.blocksize * channels * sizeof(*data)));
SDL_stack_free(data);
May 22, 2013
May 22, 2013
326
327
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
328
329
330
}
static void flac_metadata_music_cb(
May 22, 2013
May 22, 2013
331
332
333
const FLAC__StreamDecoder *decoder,
const FLAC__StreamMetadata *metadata,
void *client_data)
Oct 3, 2009
Oct 3, 2009
334
{
Oct 21, 2017
Oct 21, 2017
335
336
337
338
339
FLAC_Music *music = (FLAC_Music *)client_data;
int channels;
if (metadata->type != FLAC__METADATA_TYPE_STREAMINFO) {
return;
May 22, 2013
May 22, 2013
340
}
Oct 21, 2017
Oct 21, 2017
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
music->sample_rate = metadata->data.stream_info.sample_rate;
music->channels = metadata->data.stream_info.channels;
music->bits_per_sample = metadata->data.stream_info.bits_per_sample;
/*printf("FLAC: Sample rate = %d, channels = %d, bits_per_sample = %d\n", music->sample_rate, music->channels, music->bits_per_sample);*/
/* SDL's channel mapping and FLAC channel mapping are the same,
except for 3 channels: SDL is FL FR LFE and FLAC is FL FR FC
*/
if (music->channels == 3) {
channels = 2;
} else {
channels = music->channels;
}
/* We check for NULL stream later when we get data */
SDL_assert(!music->stream);
music->stream = SDL_NewAudioStream(AUDIO_S16SYS, channels, music->sample_rate,
music_spec.format, music_spec.channels, music_spec.freq);
359
360
361
}
static void flac_error_music_cb(
May 22, 2013
May 22, 2013
362
363
364
const FLAC__StreamDecoder *decoder,
FLAC__StreamDecoderErrorStatus status,
void *client_data)
Oct 3, 2009
Oct 3, 2009
365
{
Oct 21, 2017
Oct 21, 2017
366
/* print an SDL error based on the error status */
May 22, 2013
May 22, 2013
367
switch (status) {
Oct 21, 2017
Oct 21, 2017
368
369
case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
SDL_SetError("Error processing the FLAC file [LOST_SYNC].");
May 22, 2013
May 22, 2013
370
break;
Oct 21, 2017
Oct 21, 2017
371
372
case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
SDL_SetError("Error processing the FLAC file [BAD_HEADER].");
May 22, 2013
May 22, 2013
373
break;
Oct 21, 2017
Oct 21, 2017
374
375
case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
SDL_SetError("Error processing the FLAC file [CRC_MISMATCH].");
May 22, 2013
May 22, 2013
376
break;
Oct 21, 2017
Oct 21, 2017
377
378
case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
SDL_SetError("Error processing the FLAC file [UNPARSEABLE].");
May 22, 2013
May 22, 2013
379
break;
Oct 21, 2017
Oct 21, 2017
380
381
default:
SDL_SetError("Error processing the FLAC file [UNKNOWN].");
May 22, 2013
May 22, 2013
382
383
break;
}
384
385
386
}
/* Load an FLAC stream from an SDL_RWops object */
Oct 17, 2017
Oct 17, 2017
387
static void *FLAC_CreateFromRW(SDL_RWops *src, int freesrc)
Oct 3, 2009
Oct 3, 2009
388
{
Oct 21, 2017
Oct 21, 2017
389
FLAC_Music *music;
May 22, 2013
May 22, 2013
390
391
392
int init_stage = 0;
int was_error = 1;
Oct 21, 2017
Oct 21, 2017
393
394
395
music = (FLAC_Music *)SDL_calloc(1, sizeof(*music));
if (!music) {
SDL_OutOfMemory();
May 22, 2013
May 22, 2013
396
397
return NULL;
}
Oct 21, 2017
Oct 21, 2017
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
music->src = src;
music->volume = MIX_MAX_VOLUME;
music->flac_decoder = flac.FLAC__stream_decoder_new();
if (music->flac_decoder) {
init_stage++; /* stage 1! */
if (flac.FLAC__stream_decoder_init_stream(
music->flac_decoder,
flac_read_music_cb, flac_seek_music_cb,
flac_tell_music_cb, flac_length_music_cb,
flac_eof_music_cb, flac_write_music_cb,
flac_metadata_music_cb, flac_error_music_cb,
music) == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
init_stage++; /* stage 2! */
if (flac.FLAC__stream_decoder_process_until_end_of_metadata(music->flac_decoder)) {
was_error = 0;
May 22, 2013
May 22, 2013
416
} else {
Oct 21, 2017
Oct 21, 2017
417
SDL_SetError("FLAC__stream_decoder_process_until_end_of_metadata() failed");
May 22, 2013
May 22, 2013
418
419
}
} else {
Oct 21, 2017
Oct 21, 2017
420
SDL_SetError("FLAC__stream_decoder_init_stream() failed");
May 22, 2013
May 22, 2013
421
}
Oct 21, 2017
Oct 21, 2017
422
423
424
} else {
SDL_SetError("FLAC__stream_decoder_new() failed");
}
May 22, 2013
May 22, 2013
425
Oct 21, 2017
Oct 21, 2017
426
427
428
429
430
431
432
433
434
if (was_error) {
switch (init_stage) {
case 2:
flac.FLAC__stream_decoder_finish(music->flac_decoder);
case 1:
flac.FLAC__stream_decoder_delete(music->flac_decoder);
case 0:
SDL_free(music);
break;
May 22, 2013
May 22, 2013
435
}
Oct 21, 2017
Oct 21, 2017
436
return NULL;
May 22, 2013
May 22, 2013
437
}
Oct 21, 2017
Oct 21, 2017
438
439
music->freesrc = freesrc;
May 22, 2013
May 22, 2013
440
return music;
441
442
}
Oct 17, 2017
Oct 17, 2017
443
444
445
/* Set the volume for an FLAC stream */
static void FLAC_SetVolume(void *context, int volume)
{
Oct 21, 2017
Oct 21, 2017
446
FLAC_Music *music = (FLAC_Music *)context;
Oct 17, 2017
Oct 17, 2017
447
448
449
music->volume = volume;
}
450
/* Start playback of a given FLAC stream */
Oct 21, 2017
Oct 21, 2017
451
static int FLAC_Play(void *context, int play_count)
Oct 3, 2009
Oct 3, 2009
452
{
Oct 21, 2017
Oct 21, 2017
453
454
455
FLAC_Music *music = (FLAC_Music *)context;
music->play_count = play_count;
return FLAC_Seek(music, 0.0);
456
457
458
}
/* Read some FLAC stream data and convert it for output */
Oct 21, 2017
Oct 21, 2017
459
static int FLAC_GetSome(void *context, void *data, int bytes, SDL_bool *done)
Oct 3, 2009
Oct 3, 2009
460
{
Oct 21, 2017
Oct 21, 2017
461
462
FLAC_Music *music = (FLAC_Music *)context;
int filled;
May 22, 2013
May 22, 2013
463
Oct 21, 2017
Oct 21, 2017
464
465
466
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
May 22, 2013
May 22, 2013
467
468
}
Oct 21, 2017
Oct 21, 2017
469
470
471
472
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
return 0;
May 22, 2013
May 22, 2013
473
}
Oct 21, 2017
Oct 21, 2017
474
475
476
477
if (!flac.FLAC__stream_decoder_process_single(music->flac_decoder)) {
SDL_SetError("FLAC__stream_decoder_process_single() failed");
return -1;
May 22, 2013
May 22, 2013
478
}
Oct 21, 2017
Oct 21, 2017
479
480
481
482
483
if (flac.FLAC__stream_decoder_get_state(music->flac_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) {
if (music->play_count == 1) {
music->play_count = 0;
SDL_AudioStreamFlush(music->stream);
Oct 17, 2017
Oct 17, 2017
484
} else {
Oct 21, 2017
Oct 21, 2017
485
486
487
488
489
490
491
int play_count = -1;
if (music->play_count > 0) {
play_count = (music->play_count - 1);
}
if (FLAC_Play(music, play_count) < 0) {
return -1;
}
May 22, 2013
May 22, 2013
492
493
}
}
Oct 21, 2017
Oct 21, 2017
494
return 0;
495
496
497
}
/* Play some of a stream previously started with FLAC_play() */
Oct 17, 2017
Oct 17, 2017
498
static int FLAC_GetAudio(void *context, void *data, int bytes)
Oct 3, 2009
Oct 3, 2009
499
{
Oct 21, 2017
Oct 21, 2017
500
501
FLAC_Music *music = (FLAC_Music *)context;
return music_pcm_getaudio(context, data, bytes, music->volume, FLAC_GetSome);
502
503
}
Oct 17, 2017
Oct 17, 2017
504
505
506
/* Jump (seek) to a given position (position is in seconds) */
static int FLAC_Seek(void *context, double position)
{
Oct 21, 2017
Oct 21, 2017
507
508
FLAC_Music *music = (FLAC_Music *)context;
double seek_sample = music->sample_rate * position;
Oct 17, 2017
Oct 17, 2017
509
Oct 21, 2017
Oct 21, 2017
510
511
512
if (!flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, (FLAC__uint64)seek_sample)) {
if (flac.FLAC__stream_decoder_get_state(music->flac_decoder) == FLAC__STREAM_DECODER_SEEK_ERROR) {
flac.FLAC__stream_decoder_flush(music->flac_decoder);
Oct 17, 2017
Oct 17, 2017
513
514
515
516
517
518
519
520
}
SDL_SetError("Seeking of FLAC stream failed: libFLAC seek failed.");
return -1;
}
return 0;
}
Oct 21, 2017
Oct 21, 2017
521
/* Close the given FLAC_Music object */
Oct 17, 2017
Oct 17, 2017
522
static void FLAC_Delete(void *context)
Oct 3, 2009
Oct 3, 2009
523
{
Oct 21, 2017
Oct 21, 2017
524
FLAC_Music *music = (FLAC_Music *)context;
May 22, 2013
May 22, 2013
525
526
if (music) {
if (music->flac_decoder) {
Oct 21, 2017
Oct 21, 2017
527
528
flac.FLAC__stream_decoder_finish(music->flac_decoder);
flac.FLAC__stream_decoder_delete(music->flac_decoder);
May 22, 2013
May 22, 2013
529
}
Oct 21, 2017
Oct 21, 2017
530
531
if (music->stream) {
SDL_FreeAudioStream(music->stream);
May 22, 2013
May 22, 2013
532
}
Jun 2, 2013
Jun 2, 2013
533
534
if (music->freesrc) {
SDL_RWclose(music->src);
May 22, 2013
May 22, 2013
535
}
Oct 21, 2017
Oct 21, 2017
536
SDL_free(music);
May 22, 2013
May 22, 2013
537
}
538
539
}
Oct 17, 2017
Oct 17, 2017
540
Mix_MusicInterface Mix_MusicInterface_FLAC =
Oct 3, 2009
Oct 3, 2009
541
{
Oct 17, 2017
Oct 17, 2017
542
543
544
545
546
547
548
549
550
551
552
553
"FLAC",
MIX_MUSIC_FLAC,
MUS_FLAC,
SDL_FALSE,
SDL_FALSE,
FLAC_Load,
NULL, /* Open */
FLAC_CreateFromRW,
NULL, /* CreateFromFile */
FLAC_SetVolume,
FLAC_Play,
Oct 21, 2017
Oct 21, 2017
554
NULL, /* IsPlaying */
Oct 17, 2017
Oct 17, 2017
555
556
557
558
FLAC_GetAudio,
FLAC_Seek,
NULL, /* Pause */
NULL, /* Resume */
Oct 21, 2017
Oct 21, 2017
559
NULL, /* Stop */
Oct 17, 2017
Oct 17, 2017
560
561
562
563
564
565
566
567
FLAC_Delete,
NULL, /* Close */
FLAC_Unload,
};
#endif /* MUSIC_FLAC */
/* vi: set ts=4 sw=4 expandtab: */