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