1 /*
2 * fLaC streaming music support, loosely based QuakeForge implementation
3 * with modifications. requires libFLAC >= 1.0.4 at compile and runtime.
4 *
5 * Copyright (C) 2005 Bill Currie <bill@taniwha.org>
6 * Copyright (C) 2013 O.Sezer <sezero@users.sourceforge.net>
7 *
8 * $Id: snd_flac.c 5850 2017-04-30 08:51:03Z sezero $
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27 #include "quakedef.h"
28
29 #if defined(USE_CODEC_FLAC)
30 #include "snd_codec.h"
31 #include "snd_codeci.h"
32 #include "snd_flac.h"
33
34 #undef LEGACY_FLAC
35 #include <FLAC/stream_decoder.h>
36 /* FLAC 1.1.3 has FLAC_API_VERSION_CURRENT == 8 */
37 #if !defined(FLAC_API_VERSION_CURRENT) || ((FLAC_API_VERSION_CURRENT+0) < 8)
38 #define LEGACY_FLAC
39 #include <FLAC/seekable_stream_decoder.h>
40 #endif
41
42 #ifdef LEGACY_FLAC
43 #define FLAC__StreamDecoder FLAC__SeekableStreamDecoder
44 #define FLAC__StreamDecoderReadStatus FLAC__SeekableStreamDecoderReadStatus
45 #define FLAC__StreamDecoderSeekStatus FLAC__SeekableStreamDecoderSeekStatus
46 #define FLAC__StreamDecoderTellStatus FLAC__SeekableStreamDecoderTellStatus
47 #define FLAC__StreamDecoderLengthStatus FLAC__SeekableStreamDecoderLengthStatus
48
49 #define FLAC__stream_decoder_new FLAC__seekable_stream_decoder_new
50 #define FLAC__stream_decoder_finish FLAC__seekable_stream_decoder_finish
51 #define FLAC__stream_decoder_delete FLAC__seekable_stream_decoder_delete
52 #define FLAC__stream_decoder_process_single FLAC__seekable_stream_decoder_process_single
53 #define FLAC__stream_decoder_seek_absolute FLAC__seekable_stream_decoder_seek_absolute
54 #define FLAC__stream_decoder_process_until_end_of_metadata FLAC__seekable_stream_decoder_process_until_end_of_metadata
55 #define FLAC__stream_decoder_get_state FLAC__seekable_stream_decoder_get_state
56
57 #define FLAC__STREAM_DECODER_INIT_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_OK
58 #define FLAC__STREAM_DECODER_READ_STATUS_CONTINUE FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK
59 #define FLAC__STREAM_DECODER_READ_STATUS_ABORT FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR
60 #define FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK /* !!! */
61 #define FLAC__STREAM_DECODER_WRITE_STATUS_ABORT FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
62 #define FLAC__STREAM_DECODER_SEEK_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK
63 #define FLAC__STREAM_DECODER_SEEK_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR
64 #define FLAC__STREAM_DECODER_TELL_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK
65 #define FLAC__STREAM_DECODER_TELL_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
66 #define FLAC__STREAM_DECODER_LENGTH_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK
67 typedef unsigned FLAC_SIZE_T;
68 #else
69 typedef size_t FLAC_SIZE_T;
70 #endif
71
72 typedef struct {
73 FLAC__StreamDecoder *decoder;
74 fshandle_t *file;
75 snd_info_t *info;
76 byte *buffer;
77 int size, pos, error;
78 } flacfile_t;
79
80 /* CALLBACK FUNCTIONS: */
81 static void
flac_error_func(const FLAC__StreamDecoder * decoder,FLAC__StreamDecoderErrorStatus status,void * client_data)82 flac_error_func (const FLAC__StreamDecoder *decoder,
83 FLAC__StreamDecoderErrorStatus status, void *client_data)
84 {
85 flacfile_t *ff = (flacfile_t *) client_data;
86 ff->error = -1;
87 Con_Printf ("FLAC: decoder error %i\n", status);
88 }
89
90 static FLAC__StreamDecoderReadStatus
flac_read_func(const FLAC__StreamDecoder * decoder,FLAC__byte buffer[],FLAC_SIZE_T * bytes,void * client_data)91 flac_read_func (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[],
92 FLAC_SIZE_T *bytes, void *client_data)
93 {
94 flacfile_t *ff = (flacfile_t *) client_data;
95 if (*bytes > 0)
96 {
97 *bytes = FS_fread(buffer, 1, *bytes, ff->file);
98 if (FS_ferror(ff->file))
99 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
100 if (*bytes == 0)
101 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
102 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
103 }
104 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
105 }
106
107 static FLAC__StreamDecoderSeekStatus
flac_seek_func(const FLAC__StreamDecoder * decoder,FLAC__uint64 absolute_byte_offset,void * client_data)108 flac_seek_func (const FLAC__StreamDecoder *decoder,
109 FLAC__uint64 absolute_byte_offset, void *client_data)
110 {
111 flacfile_t *ff = (flacfile_t *) client_data;
112 if (FS_fseek(ff->file, (long)absolute_byte_offset, SEEK_SET) < 0)
113 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
114 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
115 }
116
117 static FLAC__StreamDecoderTellStatus
flac_tell_func(const FLAC__StreamDecoder * decoder,FLAC__uint64 * absolute_byte_offset,void * client_data)118 flac_tell_func (const FLAC__StreamDecoder *decoder,
119 FLAC__uint64 *absolute_byte_offset, void *client_data)
120 {
121 flacfile_t *ff = (flacfile_t *) client_data;
122 long pos = FS_ftell (ff->file);
123 if (pos < 0) return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
124 *absolute_byte_offset = (FLAC__uint64) pos;
125 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
126 }
127
128 static FLAC__StreamDecoderLengthStatus
flac_length_func(const FLAC__StreamDecoder * decoder,FLAC__uint64 * stream_length,void * client_data)129 flac_length_func (const FLAC__StreamDecoder *decoder,
130 FLAC__uint64 *stream_length, void *client_data)
131 {
132 flacfile_t *ff = (flacfile_t *) client_data;
133 *stream_length = (FLAC__uint64) FS_filelength (ff->file);
134 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
135 }
136
137 static FLAC__bool
flac_eof_func(const FLAC__StreamDecoder * decoder,void * client_data)138 flac_eof_func (const FLAC__StreamDecoder *decoder, void *client_data)
139 {
140 flacfile_t *ff = (flacfile_t *) client_data;
141 if (FS_feof (ff->file)) return true;
142 return false;
143 }
144
145 static FLAC__StreamDecoderWriteStatus
flac_write_func(const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)146 flac_write_func (const FLAC__StreamDecoder *decoder,
147 const FLAC__Frame *frame, const FLAC__int32 * const buffer[],
148 void *client_data)
149 {
150 flacfile_t *ff = (flacfile_t *) client_data;
151
152 if (!ff->buffer) {
153 #if !defined(CODECS_USE_ZONE)
154 ff->buffer = (byte *) malloc (ff->info->blocksize * ff->info->channels * ff->info->width);
155 if (!ff->buffer) {
156 ff->error = -1; /* needn't set this here, but... */
157 Con_Printf("Insufficient memory for fLaC audio\n");
158 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
159 }
160 #else
161 ff->buffer = (byte *) Z_Malloc (ff->info->blocksize * ff->info->channels * ff->info->width, Z_MAINZONE);
162 #endif
163 }
164
165 if (ff->info->channels == 1)
166 {
167 unsigned i;
168 const FLAC__int32 *in = buffer[0];
169
170 if (ff->info->bits == 8)
171 {
172 byte *out = ff->buffer;
173 for (i = 0; i < frame->header.blocksize; i++)
174 *out++ = *in++ + 128;
175 }
176 else
177 {
178 short *out = (short *) ff->buffer;
179 for (i = 0; i < frame->header.blocksize; i++)
180 *out++ = *in++;
181 }
182 }
183 else
184 {
185 unsigned i;
186 const FLAC__int32 *li = buffer[0];
187 const FLAC__int32 *ri = buffer[1];
188
189 if (ff->info->bits == 8)
190 {
191 char *lo = (char *) ff->buffer + 0;
192 char *ro = (char *) ff->buffer + 1;
193 for (i = 0; i < frame->header.blocksize; i++, lo++, ro++)
194 {
195 *lo++ = *li++ + 128;
196 *ro++ = *ri++ + 128;
197 }
198 }
199 else
200 {
201 short *lo = (short *) ff->buffer + 0;
202 short *ro = (short *) ff->buffer + 1;
203 for (i = 0; i < frame->header.blocksize; i++, lo++, ro++)
204 {
205 *lo++ = *li++;
206 *ro++ = *ri++;
207 }
208 }
209 }
210
211 ff->size = frame->header.blocksize * ff->info->width * ff->info->channels;
212 ff->pos = 0;
213 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
214 }
215
216 static void
flac_meta_func(const FLAC__StreamDecoder * decoder,const FLAC__StreamMetadata * metadata,void * client_data)217 flac_meta_func (const FLAC__StreamDecoder *decoder,
218 const FLAC__StreamMetadata *metadata, void *client_data)
219 {
220 flacfile_t *ff = (flacfile_t *) client_data;
221 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
222 {
223 ff->info->rate = metadata->data.stream_info.sample_rate;
224 ff->info->bits = metadata->data.stream_info.bits_per_sample;
225 ff->info->width = ff->info->bits / 8;
226 ff->info->channels = metadata->data.stream_info.channels;
227 ff->info->blocksize = metadata->data.stream_info.max_blocksize;
228 ff->info->dataofs = 0; /* got the STREAMINFO metadata */
229 }
230 }
231
232
S_FLAC_CodecInitialize(void)233 static qboolean S_FLAC_CodecInitialize (void)
234 {
235 return true;
236 }
237
S_FLAC_CodecShutdown(void)238 static void S_FLAC_CodecShutdown (void)
239 {
240 }
241
S_FLAC_CodecOpenStream(snd_stream_t * stream)242 static qboolean S_FLAC_CodecOpenStream (snd_stream_t *stream)
243 {
244 flacfile_t *ff;
245 int rc;
246
247 ff = (flacfile_t *) Z_Malloc(sizeof(flacfile_t), Z_MAINZONE);
248
249 ff->decoder = FLAC__stream_decoder_new ();
250 if (ff->decoder == NULL)
251 {
252 Con_Printf("Unable to create fLaC decoder\n");
253 goto _fail;
254 }
255
256 stream->priv = ff;
257 ff->info = & stream->info;
258 ff->file = & stream->fh;
259 ff->info->dataofs = -1; /* check for STREAMINFO metadata existence */
260
261 #ifdef LEGACY_FLAC
262 FLAC__seekable_stream_decoder_set_error_callback (ff->decoder, flac_error_func);
263 FLAC__seekable_stream_decoder_set_read_callback (ff->decoder, flac_read_func);
264 FLAC__seekable_stream_decoder_set_seek_callback (ff->decoder, flac_seek_func);
265 FLAC__seekable_stream_decoder_set_tell_callback (ff->decoder, flac_tell_func);
266 FLAC__seekable_stream_decoder_set_length_callback (ff->decoder, flac_length_func);
267 FLAC__seekable_stream_decoder_set_eof_callback (ff->decoder, flac_eof_func);
268 FLAC__seekable_stream_decoder_set_write_callback (ff->decoder, flac_write_func);
269 FLAC__seekable_stream_decoder_set_metadata_callback (ff->decoder, flac_meta_func);
270 FLAC__seekable_stream_decoder_set_client_data (ff->decoder, ff);
271 rc = FLAC__seekable_stream_decoder_init (ff->decoder);
272 #else
273 rc = FLAC__stream_decoder_init_stream(ff->decoder,
274 flac_read_func,
275 flac_seek_func,
276 flac_tell_func,
277 flac_length_func,
278 flac_eof_func,
279 flac_write_func,
280 flac_meta_func,
281 flac_error_func,
282 ff);
283 #endif
284 if (rc != FLAC__STREAM_DECODER_INIT_STATUS_OK) /* unlikely */
285 {
286 Con_Printf ("FLAC: decoder init error %i\n", rc);
287 goto _fail;
288 }
289
290 rc = FLAC__stream_decoder_process_until_end_of_metadata (ff->decoder);
291 if (rc == false || ff->error)
292 {
293 rc = FLAC__stream_decoder_get_state(ff->decoder);
294 Con_Printf("%s not a valid flac file? (decoder state %i)\n",
295 stream->name, rc);
296 goto _fail;
297 }
298
299 if (ff->info->dataofs < 0)
300 {
301 Con_Printf("%s has no STREAMINFO\n", stream->name);
302 goto _fail;
303 }
304 if (ff->info->bits != 8 && ff->info->bits != 16)
305 {
306 Con_Printf("%s is not 8 or 16 bit\n", stream->name);
307 goto _fail;
308 }
309 if (ff->info->channels != 1 && ff->info->channels != 2)
310 {
311 Con_Printf("Unsupported number of channels %d in %s\n",
312 ff->info->channels, stream->name);
313 goto _fail;
314 }
315
316 return true;
317
318 _fail:
319 if (ff->decoder)
320 {
321 FLAC__stream_decoder_finish (ff->decoder);
322 FLAC__stream_decoder_delete (ff->decoder);
323 }
324 Z_Free(ff);
325 return false;
326 }
327
S_FLAC_CodecReadStream(snd_stream_t * stream,int len,void * buffer)328 static int S_FLAC_CodecReadStream (snd_stream_t *stream, int len, void *buffer)
329 {
330 flacfile_t *ff = (flacfile_t *) stream->priv;
331 byte *buf = (byte *) buffer;
332 int count = 0;
333
334 while (len) {
335 int res = 0;
336 if (ff->size == ff->pos)
337 FLAC__stream_decoder_process_single (ff->decoder);
338 if (ff->error) return -1;
339 res = ff->size - ff->pos;
340 if (res > len)
341 res = len;
342 if (res > 0) {
343 memcpy (buf, ff->buffer + ff->pos, res);
344 count += res;
345 len -= res;
346 buf += res;
347 ff->pos += res;
348 } else if (res < 0) { /* error */
349 return -1;
350 } else {
351 Con_DPrintf ("FLAC: EOF\n");
352 break;
353 }
354 }
355 return count;
356 }
357
S_FLAC_CodecCloseStream(snd_stream_t * stream)358 static void S_FLAC_CodecCloseStream (snd_stream_t *stream)
359 {
360 flacfile_t *ff = (flacfile_t *) stream->priv;
361
362 FLAC__stream_decoder_finish (ff->decoder);
363 FLAC__stream_decoder_delete (ff->decoder);
364
365 if (ff->buffer)
366 #if defined(CODECS_USE_ZONE)
367 Z_Free(ff->buffer);
368 #else
369 free(ff->buffer);
370 #endif
371 Z_Free(ff);
372
373 S_CodecUtilClose(&stream);
374 }
375
S_FLAC_CodecRewindStream(snd_stream_t * stream)376 static int S_FLAC_CodecRewindStream (snd_stream_t *stream)
377 {
378 flacfile_t *ff = (flacfile_t *) stream->priv;
379
380 ff->pos = ff->size = 0;
381 if (FLAC__stream_decoder_seek_absolute(ff->decoder, 0)) return 0;
382 return -1;
383 }
384
385 snd_codec_t flac_codec =
386 {
387 CODECTYPE_FLAC,
388 true, /* always available. */
389 "flac",
390 S_FLAC_CodecInitialize,
391 S_FLAC_CodecShutdown,
392 S_FLAC_CodecOpenStream,
393 S_FLAC_CodecReadStream,
394 S_FLAC_CodecRewindStream,
395 S_FLAC_CodecCloseStream,
396 NULL
397 };
398
399 #endif /* USE_CODEC_FLAC */
400
401