1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  */
16 
17 /* Sound file decoder for .wav, .mod, .ogg (to be used with OpenAL)
18  * API is heavily influenced by SDL_sound.
19  */
20 
21 #include <string.h>
22 #include <stdlib.h>
23 #include "port.h"
24 #include "libs/memlib.h"
25 #include "libs/file.h"
26 #include "libs/log.h"
27 #include "decoder.h"
28 #include "wav.h"
29 #include "dukaud.h"
30 #include "modaud.h"
31 #ifndef OVCODEC_NONE
32 #	include "oggaud.h"
33 #endif  /* OVCODEC_NONE */
34 #include "aiffaud.h"
35 
36 
37 #define MAX_REG_DECODERS 31
38 
39 #define THIS_PTR TFB_SoundDecoder*
40 
41 static const char* bufa_GetName (void);
42 static bool bufa_InitModule (int flags, const TFB_DecoderFormats*);
43 static void bufa_TermModule (void);
44 static uint32 bufa_GetStructSize (void);
45 static int bufa_GetError (THIS_PTR);
46 static bool bufa_Init (THIS_PTR);
47 static void bufa_Term (THIS_PTR);
48 static bool bufa_Open (THIS_PTR, uio_DirHandle *dir, const char *filename);
49 static void bufa_Close (THIS_PTR);
50 static int bufa_Decode (THIS_PTR, void* buf, sint32 bufsize);
51 static uint32 bufa_Seek (THIS_PTR, uint32 pcm_pos);
52 static uint32 bufa_GetFrame (THIS_PTR);
53 
54 TFB_SoundDecoderFuncs bufa_DecoderVtbl =
55 {
56 	bufa_GetName,
57 	bufa_InitModule,
58 	bufa_TermModule,
59 	bufa_GetStructSize,
60 	bufa_GetError,
61 	bufa_Init,
62 	bufa_Term,
63 	bufa_Open,
64 	bufa_Close,
65 	bufa_Decode,
66 	bufa_Seek,
67 	bufa_GetFrame,
68 };
69 
70 typedef struct tfb_bufsounddecoder
71 {
72 	// always the first member
73 	TFB_SoundDecoder decoder;
74 
75 	// private
76 	void* data;
77 	uint32 max_pcm;
78 	uint32 cur_pcm;
79 
80 } TFB_BufSoundDecoder;
81 
82 #define SD_MIN_SIZE   (sizeof (TFB_BufSoundDecoder))
83 
84 static const char* nula_GetName (void);
85 static bool nula_InitModule (int flags, const TFB_DecoderFormats*);
86 static void nula_TermModule (void);
87 static uint32 nula_GetStructSize (void);
88 static int nula_GetError (THIS_PTR);
89 static bool nula_Init (THIS_PTR);
90 static void nula_Term (THIS_PTR);
91 static bool nula_Open (THIS_PTR, uio_DirHandle *dir, const char *filename);
92 static void nula_Close (THIS_PTR);
93 static int nula_Decode (THIS_PTR, void* buf, sint32 bufsize);
94 static uint32 nula_Seek (THIS_PTR, uint32 pcm_pos);
95 static uint32 nula_GetFrame (THIS_PTR);
96 
97 TFB_SoundDecoderFuncs nula_DecoderVtbl =
98 {
99 	nula_GetName,
100 	nula_InitModule,
101 	nula_TermModule,
102 	nula_GetStructSize,
103 	nula_GetError,
104 	nula_Init,
105 	nula_Term,
106 	nula_Open,
107 	nula_Close,
108 	nula_Decode,
109 	nula_Seek,
110 	nula_GetFrame,
111 };
112 
113 typedef struct tfb_nullsounddecoder
114 {
115 	// always the first member
116 	TFB_SoundDecoder decoder;
117 
118 	// private
119 	uint32 cur_pcm;
120 
121 } TFB_NullSoundDecoder;
122 
123 #undef THIS_PTR
124 
125 
126 struct TFB_RegSoundDecoder
127 {
128 	bool builtin;
129 	bool used;        // ever used indicator
130 	const char* ext;
131 	const TFB_SoundDecoderFuncs* funcs;
132 };
133 static TFB_RegSoundDecoder sd_decoders[MAX_REG_DECODERS + 1] =
134 {
135 	{true,  true,  "wav", &wava_DecoderVtbl},
136 	{true,  true,  "mod", &moda_DecoderVtbl},
137 #ifndef OVCODEC_NONE
138 	{true,  true,  "ogg", &ova_DecoderVtbl},
139 #endif  /* OVCODEC_NONE */
140 	{true,  true,  "duk", &duka_DecoderVtbl},
141 	{true,  true,  "aif", &aifa_DecoderVtbl},
142 	{false, false,  NULL, NULL}, // null term
143 };
144 
145 static TFB_DecoderFormats decoder_formats;
146 static int sd_flags = 0;
147 
148 /* change endianness of 16bit words
149  * Only works optimal when 'data' is aligned on a 32 bits boundary.
150  */
151 void
SoundDecoder_SwapWords(uint16 * data,uint32 size)152 SoundDecoder_SwapWords (uint16* data, uint32 size)
153 {
154 	uint32 fsize = size & (~3U);
155 
156 	size -= fsize;
157 	fsize >>= 2;
158 	for (; fsize; fsize--, data += 2)
159 	{
160 		uint32 v = *(uint32*)data;
161 		*(uint32*)data = ((v & 0x00ff00ff) << 8)
162 				| ((v & 0xff00ff00) >> 8);
163 	}
164 	if (size)
165 	{
166 		/* leftover word */
167 		*data = ((*data & 0x00ff) << 8) | ((*data & 0xff00) >> 8);
168 	}
169 }
170 
171 const char*
SoundDecoder_GetName(TFB_SoundDecoder * decoder)172 SoundDecoder_GetName (TFB_SoundDecoder *decoder)
173 {
174 	if (!decoder || !decoder->funcs)
175 		return "(Null)";
176 	return decoder->funcs->GetName ();
177 }
178 
179 sint32
SoundDecoder_Init(int flags,TFB_DecoderFormats * formats)180 SoundDecoder_Init (int flags, TFB_DecoderFormats *formats)
181 {
182 	TFB_RegSoundDecoder* info;
183 	sint32 ret = 0;
184 
185 	if (!formats)
186 	{
187 		log_add (log_Error, "SoundDecoder_Init(): missing decoder formats");
188 		return 1;
189 	}
190 	decoder_formats = *formats;
191 
192 	// init built-in decoders
193 	for (info = sd_decoders; info->ext; info++)
194 	{
195 		if (!info->funcs->InitModule (flags, &decoder_formats))
196 		{
197 			log_add (log_Error, "SoundDecoder_Init(): "
198 					"%s audio decoder init failed",
199 					info->funcs->GetName ());
200 			ret = 1;
201 		}
202 	}
203 
204 	sd_flags = flags;
205 
206 	return ret;
207 }
208 
209 void
SoundDecoder_Uninit(void)210 SoundDecoder_Uninit (void)
211 {
212 	TFB_RegSoundDecoder* info;
213 
214 	// uninit all decoders
215 	// and unregister loaded decoders
216 	for (info = sd_decoders; info->used; info++)
217 	{
218 		if (info->ext) // check if present
219 			info->funcs->TermModule ();
220 
221 		if (!info->builtin)
222 		{
223 			info->used = false;
224 			info->ext = NULL;
225 		}
226 	}
227 }
228 
229 TFB_RegSoundDecoder*
SoundDecoder_Register(const char * fileext,TFB_SoundDecoderFuncs * decvtbl)230 SoundDecoder_Register (const char* fileext, TFB_SoundDecoderFuncs* decvtbl)
231 {
232 	TFB_RegSoundDecoder* info;
233 	TFB_RegSoundDecoder* newslot = NULL;
234 
235 	if (!decvtbl)
236 	{
237 		log_add (log_Warning, "SoundDecoder_Register(): Null decoder table");
238 		return NULL;
239 	}
240 	if (!fileext)
241 	{
242 		log_add (log_Warning, "SoundDecoder_Register(): Bad file type for %s",
243 				decvtbl->GetName ());
244 		return NULL;
245 	}
246 
247 	// check if extension already registered
248 	for (info = sd_decoders; info->used &&
249 			(!info->ext || strcmp (info->ext, fileext) != 0);
250 			++info)
251 	{
252 		// and pick up an empty slot (where available)
253 		if (!newslot && !info->ext)
254 			newslot = info;
255 	}
256 
257 	if (info >= sd_decoders + MAX_REG_DECODERS)
258 	{
259 		log_add (log_Warning, "SoundDecoder_Register(): Decoders limit reached");
260 		return NULL;
261 	}
262 	else if (info->ext)
263 	{
264 		log_add (log_Warning, "SoundDecoder_Register(): "
265 				"'%s' decoder already registered (%s denied)",
266 				fileext, decvtbl->GetName ());
267 		return NULL;
268 	}
269 
270 	if (!decvtbl->InitModule (sd_flags, &decoder_formats))
271 	{
272 		log_add (log_Warning, "SoundDecoder_Register(): %s decoder init failed",
273 				decvtbl->GetName ());
274 		return NULL;
275 	}
276 
277 	if (!newslot)
278 	{
279 		newslot = info;
280 		newslot->used = true;
281 		// make next one a term
282 		info[1].builtin = false;
283 		info[1].used = false;
284 		info[1].ext = NULL;
285 	}
286 
287 	newslot->ext = fileext;
288 	newslot->funcs = decvtbl;
289 
290 	return newslot;
291 }
292 
293 void
SoundDecoder_Unregister(TFB_RegSoundDecoder * regdec)294 SoundDecoder_Unregister (TFB_RegSoundDecoder* regdec)
295 {
296 	if (regdec < sd_decoders || regdec >= sd_decoders + MAX_REG_DECODERS ||
297 			!regdec->ext || !regdec->funcs)
298 	{
299 		log_add (log_Warning, "SoundDecoder_Unregister(): "
300 				"Invalid or expired decoder passed");
301 		return;
302 	}
303 
304 	regdec->funcs->TermModule ();
305 	regdec->ext = NULL;
306 	regdec->funcs = NULL;
307 }
308 
309 const TFB_SoundDecoderFuncs*
SoundDecoder_Lookup(const char * fileext)310 SoundDecoder_Lookup (const char* fileext)
311 {
312 	TFB_RegSoundDecoder* info;
313 
314 	for (info = sd_decoders; info->used &&
315 			(!info->ext || strcmp (info->ext, fileext) != 0);
316 			++info)
317 		;
318 	return info->ext ? info->funcs : NULL;
319 }
320 
321 TFB_SoundDecoder*
SoundDecoder_Load(uio_DirHandle * dir,char * filename,uint32 buffer_size,uint32 startTime,sint32 runTime)322 SoundDecoder_Load (uio_DirHandle *dir, char *filename,
323 		uint32 buffer_size, uint32 startTime, sint32 runTime)
324 			// runTime < 0 specifies a default length for a nul decoder
325 {
326 	const char* pext;
327 	TFB_RegSoundDecoder* info;
328 	const TFB_SoundDecoderFuncs* funcs;
329 	TFB_SoundDecoder* decoder;
330 	uint32 struct_size;
331 
332 	pext = strrchr (filename, '.');
333 	if (!pext)
334 	{
335 		log_add (log_Warning, "SoundDecoder_Load(): Unknown file type (%s)",
336 				filename);
337 		return NULL;
338 	}
339 	++pext;
340 
341 	for (info = sd_decoders; info->used &&
342 			(!info->ext || strcmp (info->ext, pext) != 0);
343 			++info)
344 		;
345 	if (!info->ext)
346 	{
347 		log_add (log_Warning, "SoundDecoder_Load(): Unsupported file type (%s)",
348 			filename);
349 
350 		if (runTime)
351 		{
352 			runTime = abs (runTime);
353 			startTime = 0;
354 			funcs = &nula_DecoderVtbl;
355 		}
356 		else
357 		{
358 			return NULL;
359 		}
360 	}
361 	else
362 	{
363 		funcs = info->funcs;
364 	}
365 
366 	if (!fileExists2 (dir, filename))
367 	{
368 		if (runTime)
369 		{
370 			runTime = abs (runTime);
371 			startTime = 0;
372 			funcs = &nula_DecoderVtbl;
373 		}
374 		else
375 		{
376 			log_add (log_Warning, "SoundDecoder_Load(): %s does not exist",
377 					filename);
378 			return NULL;
379 		}
380 	}
381 
382 	struct_size = funcs->GetStructSize ();
383 	if (struct_size < SD_MIN_SIZE)
384 		struct_size = SD_MIN_SIZE;
385 
386 	decoder = (TFB_SoundDecoder*) HCalloc (struct_size);
387 	decoder->funcs = funcs;
388 	if (!decoder->funcs->Init (decoder))
389 	{
390 		log_add (log_Warning, "SoundDecoder_Load(): "
391 				"%s decoder instance failed init",
392 				decoder->funcs->GetName ());
393 		HFree (decoder);
394 		return NULL;
395 	}
396 
397 	if (!decoder->funcs->Open (decoder, dir, filename))
398 	{
399 		log_add (log_Warning, "SoundDecoder_Load(): "
400 				"%s decoder could not load %s",
401 				decoder->funcs->GetName (), filename);
402 		decoder->funcs->Term (decoder);
403 		HFree (decoder);
404 		return NULL;
405 	}
406 
407 	decoder->buffer = HMalloc (buffer_size);
408 	decoder->buffer_size = buffer_size;
409 	decoder->looping = false;
410 	decoder->error = SOUNDDECODER_OK;
411 	decoder->dir = dir;
412 	decoder->filename = (char *) HMalloc (strlen (filename) + 1);
413 	strcpy (decoder->filename, filename);
414 
415 	if (decoder->is_null)
416 	{	// fake decoder, keeps voiceovers and etc. going
417 		decoder->length = (float) (runTime / 1000.0);
418 	}
419 
420 	decoder->length -= startTime / 1000.0f;
421 	if (decoder->length < 0)
422 		decoder->length = 0;
423 	else if (runTime > 0 && runTime / 1000.0 < decoder->length)
424 		decoder->length = (float)(runTime / 1000.0);
425 
426 	decoder->start_sample = (uint32)(startTime / 1000.0f * decoder->frequency);
427 	decoder->end_sample = decoder->start_sample +
428 			(unsigned long)(decoder->length * decoder->frequency);
429 	if (decoder->start_sample != 0)
430 		decoder->funcs->Seek (decoder, decoder->start_sample);
431 
432 	if (decoder->format == decoder_formats.mono8)
433 		decoder->bytes_per_samp = 1;
434 	else if (decoder->format == decoder_formats.mono16)
435 		decoder->bytes_per_samp = 2;
436 	else if (decoder->format == decoder_formats.stereo8)
437 		decoder->bytes_per_samp = 2;
438 	else if (decoder->format == decoder_formats.stereo16)
439 		decoder->bytes_per_samp = 4;
440 
441 	decoder->pos = decoder->start_sample * decoder->bytes_per_samp;
442 
443 	return decoder;
444 }
445 
446 uint32
SoundDecoder_Decode(TFB_SoundDecoder * decoder)447 SoundDecoder_Decode (TFB_SoundDecoder *decoder)
448 {
449 	long decoded_bytes;
450 	long rc;
451 	long buffer_size;
452 	uint32 max_bytes = UINT32_MAX;
453 	uint8 *buffer;
454 
455 	if (!decoder || !decoder->funcs)
456 	{
457 		log_add (log_Warning, "SoundDecoder_Decode(): null or bad decoder");
458 		return 0;
459 	}
460 
461 	buffer = (uint8*) decoder->buffer;
462 	buffer_size = decoder->buffer_size;
463 	if (!decoder->looping && decoder->end_sample > 0)
464 	{
465 		max_bytes = decoder->end_sample * decoder->bytes_per_samp;
466 		if (max_bytes - decoder->pos < decoder->buffer_size)
467 			buffer_size = max_bytes - decoder->pos;
468 	}
469 
470 	if (buffer_size == 0)
471 	{	// nothing more to decode
472 		decoder->error = SOUNDDECODER_EOF;
473 		return 0;
474 	}
475 
476 	for (decoded_bytes = 0, rc = 1; rc > 0 && decoded_bytes < buffer_size; )
477 	{
478 		rc = decoder->funcs->Decode (decoder, buffer + decoded_bytes,
479 					buffer_size - decoded_bytes);
480 		if (rc < 0)
481 		{
482 			log_add (log_Warning, "SoundDecoder_Decode(): "
483 					"error decoding %s, code %ld",
484 					decoder->filename, rc);
485 		}
486 		else if (rc == 0)
487 		{	// probably EOF
488 			if (decoder->looping)
489 			{
490 				SoundDecoder_Rewind (decoder);
491 				if (decoder->error)
492 				{
493 					log_add (log_Warning, "SoundDecoder_Decode(): "
494 							"tried to loop %s but couldn't rewind, "
495 							"error code %d",
496 							decoder->filename, decoder->error);
497 				}
498 				else
499 				{
500 					log_add (log_Info, "SoundDecoder_Decode(): "
501 							"looping %s", decoder->filename);
502 					rc = 1;	// prime the loop again
503 				}
504 			}
505 			else
506 			{
507 				log_add (log_Info, "SoundDecoder_Decode(): eof for %s",
508 						decoder->filename);
509 			}
510 		}
511 		else
512 		{	// some bytes decoded
513 			decoded_bytes += rc;
514 		}
515 	}
516 	decoder->pos += decoded_bytes;
517 	if (rc < 0)
518 		decoder->error = SOUNDDECODER_ERROR;
519 	else if (rc == 0 || decoder->pos >= max_bytes)
520 		decoder->error = SOUNDDECODER_EOF;
521 	else
522 		decoder->error = SOUNDDECODER_OK;
523 
524 	if (decoder->need_swap && decoded_bytes > 0 &&
525 			(decoder->format == decoder_formats.stereo16 ||
526 			decoder->format == decoder_formats.mono16))
527 	{
528 		SoundDecoder_SwapWords (
529 				decoder->buffer, decoded_bytes);
530 	}
531 
532 	return decoded_bytes;
533 }
534 
535 uint32
SoundDecoder_DecodeAll(TFB_SoundDecoder * decoder)536 SoundDecoder_DecodeAll (TFB_SoundDecoder *decoder)
537 {
538 	uint32 decoded_bytes;
539 	long rc;
540 	uint32 reqbufsize;
541 
542 	if (!decoder || !decoder->funcs)
543 	{
544 		log_add (log_Warning, "SoundDecoder_DecodeAll(): null or bad decoder");
545 		return 0;
546 	}
547 
548 	reqbufsize = decoder->buffer_size;
549 
550 	if (decoder->looping)
551 	{
552 		log_add (log_Warning, "SoundDecoder_DecodeAll(): "
553 				"called for %s with looping", decoder->filename);
554 		return 0;
555 	}
556 
557 	if (reqbufsize < 4096)
558 		reqbufsize = 4096;
559 
560 	for (decoded_bytes = 0, rc = 1; rc > 0; )
561 	{
562 		if (decoded_bytes >= decoder->buffer_size)
563 		{	// need to grow buffer
564 			decoder->buffer_size += reqbufsize;
565 			decoder->buffer = HRealloc (
566 					decoder->buffer, decoder->buffer_size);
567 		}
568 
569 		rc = decoder->funcs->Decode (decoder,
570 				(uint8*) decoder->buffer + decoded_bytes,
571 				decoder->buffer_size - decoded_bytes);
572 
573 		if (rc > 0)
574 			decoded_bytes += rc;
575 	}
576 	decoder->buffer_size = decoded_bytes;
577 	decoder->pos += decoded_bytes;
578 	// Free up some unused memory
579 	decoder->buffer = HRealloc (decoder->buffer, decoded_bytes);
580 
581 	if (decoder->need_swap && decoded_bytes > 0 &&
582 			(decoder->format == decoder_formats.stereo16 ||
583 			decoder->format == decoder_formats.mono16))
584 	{
585 		SoundDecoder_SwapWords (
586 				decoder->buffer, decoded_bytes);
587 	}
588 
589 	if (rc < 0)
590 	{
591 		decoder->error = SOUNDDECODER_ERROR;
592 		log_add (log_Warning, "SoundDecoder_DecodeAll(): "
593 				"error decoding %s, code %ld",
594 				decoder->filename, rc);
595 		return decoded_bytes;
596 	}
597 
598 	// switch to Buffer decoder
599 	decoder->funcs->Close (decoder);
600 	decoder->funcs->Term (decoder);
601 
602 	decoder->funcs = &bufa_DecoderVtbl;
603 	decoder->funcs->Init (decoder);
604 	decoder->pos = 0;
605 	decoder->start_sample = 0;
606 	decoder->error = SOUNDDECODER_OK;
607 
608 	return decoded_bytes;
609 }
610 
611 void
SoundDecoder_Rewind(TFB_SoundDecoder * decoder)612 SoundDecoder_Rewind (TFB_SoundDecoder *decoder)
613 {
614 	SoundDecoder_Seek (decoder, 0);
615 }
616 
617 // seekTime is specified in mili-seconds
618 void
SoundDecoder_Seek(TFB_SoundDecoder * decoder,uint32 seekTime)619 SoundDecoder_Seek (TFB_SoundDecoder *decoder, uint32 seekTime)
620 {
621 	uint32 pcm_pos;
622 
623 	if (!decoder)
624 		return;
625 	if (!decoder->funcs)
626 	{
627 		log_add (log_Warning, "SoundDecoder_Seek(): bad decoder passed");
628 		return;
629 	}
630 
631 	pcm_pos = (uint32) (seekTime / 1000.0f * decoder->frequency);
632 	pcm_pos = decoder->funcs->Seek (decoder,
633 			decoder->start_sample + pcm_pos);
634 	decoder->pos = pcm_pos * decoder->bytes_per_samp;
635 	decoder->error = SOUNDDECODER_OK;
636 }
637 
638 void
SoundDecoder_Free(TFB_SoundDecoder * decoder)639 SoundDecoder_Free (TFB_SoundDecoder *decoder)
640 {
641 	if (!decoder)
642 		return;
643 	if (!decoder->funcs)
644 	{
645 		log_add (log_Warning, "SoundDecoder_Free(): bad decoder passed");
646 		return;
647 	}
648 
649 	decoder->funcs->Close (decoder);
650 	decoder->funcs->Term (decoder);
651 
652 	HFree (decoder->buffer);
653 	HFree (decoder->filename);
654 	HFree (decoder);
655 }
656 
657 float
SoundDecoder_GetTime(TFB_SoundDecoder * decoder)658 SoundDecoder_GetTime (TFB_SoundDecoder *decoder)
659 {
660 	if (!decoder)
661 		return 0.0f;
662 	if (!decoder->funcs)
663 	{
664 		log_add (log_Warning, "SoundDecoder_GetTime(): bad decoder passed");
665 		return 0.0f;
666 	}
667 
668 	return (float)
669 			((decoder->pos / decoder->bytes_per_samp)
670 			 - decoder->start_sample
671 			) / decoder->frequency;
672 }
673 
674 uint32
SoundDecoder_GetFrame(TFB_SoundDecoder * decoder)675 SoundDecoder_GetFrame (TFB_SoundDecoder *decoder)
676 {
677 	if (!decoder)
678 		return 0;
679 	if (!decoder->funcs)
680 	{
681 		log_add (log_Warning, "SoundDecoder_GetFrame(): bad decoder passed");
682 		return 0;
683 	}
684 
685 	return decoder->funcs->GetFrame (decoder);
686 }
687 
688 
689 #define THIS_PTR TFB_SoundDecoder* This
690 
691 static const char*
bufa_GetName(void)692 bufa_GetName (void)
693 {
694 	return "Buffer";
695 }
696 
697 static bool
bufa_InitModule(int flags,const TFB_DecoderFormats * fmts)698 bufa_InitModule (int flags, const TFB_DecoderFormats* fmts)
699 {
700 	// this should never be called
701 	log_add (log_Debug, "bufa_InitModule(): dead function called");
702 	return false;
703 
704 	(void)flags; (void)fmts; // laugh at compiler warning
705 }
706 
707 static void
bufa_TermModule(void)708 bufa_TermModule (void)
709 {
710 	// this should never be called
711 	log_add (log_Debug, "bufa_TermModule(): dead function called");
712 }
713 
714 static uint32
bufa_GetStructSize(void)715 bufa_GetStructSize (void)
716 {
717 	return sizeof (TFB_BufSoundDecoder);
718 }
719 
720 static int
bufa_GetError(THIS_PTR)721 bufa_GetError (THIS_PTR)
722 {
723 	return 0; // error? what error?!
724 
725 	(void)This;	// laugh at compiler warning
726 }
727 
728 static bool
bufa_Init(THIS_PTR)729 bufa_Init (THIS_PTR)
730 {
731 	TFB_BufSoundDecoder* bufa = (TFB_BufSoundDecoder*) This;
732 
733 	This->need_swap = false;
734 	// hijack the buffer
735 	bufa->data = This->buffer;
736 	bufa->max_pcm = This->buffer_size / This->bytes_per_samp;
737 	bufa->cur_pcm = bufa->max_pcm;
738 
739 	return true;
740 }
741 
742 static void
bufa_Term(THIS_PTR)743 bufa_Term (THIS_PTR)
744 {
745 	//TFB_BufSoundDecoder* bufa = (TFB_BufSoundDecoder*) This;
746 	bufa_Close (This); // ensure cleanup
747 }
748 
749 static bool
bufa_Open(THIS_PTR,uio_DirHandle * dir,const char * filename)750 bufa_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
751 {
752 	// this should never be called
753 	log_add (log_Debug, "bufa_Open(): dead function called");
754 	return false;
755 
756 	// laugh at compiler warnings
757 	(void)This; (void)dir; (void)filename;
758 }
759 
760 static void
bufa_Close(THIS_PTR)761 bufa_Close (THIS_PTR)
762 {
763 	TFB_BufSoundDecoder* bufa = (TFB_BufSoundDecoder*) This;
764 
765 	// restore the status quo
766 	if (bufa->data)
767 	{
768 		This->buffer = bufa->data;
769 		bufa->data = NULL;
770 	}
771 	bufa->cur_pcm = 0;
772 }
773 
774 static int
bufa_Decode(THIS_PTR,void * buf,sint32 bufsize)775 bufa_Decode (THIS_PTR, void* buf, sint32 bufsize)
776 {
777 	TFB_BufSoundDecoder* bufa = (TFB_BufSoundDecoder*) This;
778 	uint32 dec_pcm;
779 	uint32 dec_bytes;
780 
781 	dec_pcm = bufsize / This->bytes_per_samp;
782 	if (dec_pcm > bufa->max_pcm - bufa->cur_pcm)
783 		dec_pcm = bufa->max_pcm - bufa->cur_pcm;
784 	dec_bytes = dec_pcm * This->bytes_per_samp;
785 
786 	// Buffer decode is a hack
787 	This->buffer = (uint8*) bufa->data
788 			+ bufa->cur_pcm * This->bytes_per_samp;
789 
790 	if (dec_pcm > 0)
791 		bufa->cur_pcm += dec_pcm;
792 
793 	return dec_bytes;
794 
795 	(void)buf;	// laugh at compiler warning
796 }
797 
798 static uint32
bufa_Seek(THIS_PTR,uint32 pcm_pos)799 bufa_Seek (THIS_PTR, uint32 pcm_pos)
800 {
801 	TFB_BufSoundDecoder* bufa = (TFB_BufSoundDecoder*) This;
802 
803 	if (pcm_pos > bufa->max_pcm)
804 		pcm_pos = bufa->max_pcm;
805 	bufa->cur_pcm = pcm_pos;
806 
807 	return pcm_pos;
808 }
809 
810 static uint32
bufa_GetFrame(THIS_PTR)811 bufa_GetFrame (THIS_PTR)
812 {
813 	return 0; // only 1 frame
814 
815 	(void)This; // laugh at compiler warning
816 }
817 
818 
819 static const char*
nula_GetName(void)820 nula_GetName (void)
821 {
822 	return "Null";
823 }
824 
825 static bool
nula_InitModule(int flags,const TFB_DecoderFormats * fmts)826 nula_InitModule (int flags, const TFB_DecoderFormats* fmts)
827 {
828 	// this should never be called
829 	log_add (log_Debug, "nula_InitModule(): dead function called");
830 	return false;
831 
832 	(void)flags; (void)fmts; // laugh at compiler warning
833 }
834 
835 static void
nula_TermModule(void)836 nula_TermModule (void)
837 {
838 	// this should never be called
839 	log_add (log_Debug, "nula_TermModule(): dead function called");
840 }
841 
842 static uint32
nula_GetStructSize(void)843 nula_GetStructSize (void)
844 {
845 	return sizeof (TFB_NullSoundDecoder);
846 }
847 
848 static int
nula_GetError(THIS_PTR)849 nula_GetError (THIS_PTR)
850 {
851 	return 0; // error? what error?!
852 
853 	(void)This;	// laugh at compiler warning
854 }
855 
856 static bool
nula_Init(THIS_PTR)857 nula_Init (THIS_PTR)
858 {
859 	TFB_NullSoundDecoder* nula = (TFB_NullSoundDecoder*) This;
860 
861 	This->need_swap = false;
862 	nula->cur_pcm = 0;
863 	return true;
864 }
865 
866 static void
nula_Term(THIS_PTR)867 nula_Term (THIS_PTR)
868 {
869 	//TFB_NullSoundDecoder* nula = (TFB_NullSoundDecoder*) This;
870 	nula_Close (This); // ensure cleanup
871 }
872 
873 static bool
nula_Open(THIS_PTR,uio_DirHandle * dir,const char * filename)874 nula_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
875 {
876 	This->frequency = 11025;
877 	This->format = decoder_formats.mono16;
878 	This->is_null = true;
879 	return true;
880 
881 	// laugh at compiler warnings
882 	(void)dir; (void)filename;
883 }
884 
885 static void
nula_Close(THIS_PTR)886 nula_Close (THIS_PTR)
887 {
888 	TFB_NullSoundDecoder* nula = (TFB_NullSoundDecoder*) This;
889 
890 	nula->cur_pcm = 0;
891 }
892 
893 static int
nula_Decode(THIS_PTR,void * buf,sint32 bufsize)894 nula_Decode (THIS_PTR, void* buf, sint32 bufsize)
895 {
896 	TFB_NullSoundDecoder* nula = (TFB_NullSoundDecoder*) This;
897 	uint32 max_pcm;
898 	uint32 dec_pcm;
899 	uint32 dec_bytes;
900 
901 	max_pcm = (uint32) (This->length * This->frequency);
902 	dec_pcm = bufsize / This->bytes_per_samp;
903 	if (dec_pcm > max_pcm - nula->cur_pcm)
904 		dec_pcm = max_pcm - nula->cur_pcm;
905 	dec_bytes = dec_pcm * This->bytes_per_samp;
906 
907 	if (dec_pcm > 0)
908 	{
909 		memset (buf, 0, dec_bytes);
910 		nula->cur_pcm += dec_pcm;
911 	}
912 
913 	return dec_bytes;
914 }
915 
916 static uint32
nula_Seek(THIS_PTR,uint32 pcm_pos)917 nula_Seek (THIS_PTR, uint32 pcm_pos)
918 {
919 	TFB_NullSoundDecoder* nula = (TFB_NullSoundDecoder*) This;
920 	uint32 max_pcm;
921 
922 	max_pcm = (uint32) (This->length * This->frequency);
923 	if (pcm_pos > max_pcm)
924 		pcm_pos = max_pcm;
925 	nula->cur_pcm = pcm_pos;
926 
927 	return pcm_pos;
928 }
929 
930 static uint32
nula_GetFrame(THIS_PTR)931 nula_GetFrame (THIS_PTR)
932 {
933 	return 0; // only 1 frame
934 
935 	(void)This; // laugh at compiler warning
936 }
937