1 /***********************************************************
2 * Portions of this file are Copyright (c) Ryan C. Gordon
3 ***********************************************************/
6 * $Logfile: /Freespace2/code/Sound/ACM.cpp $
14 * Revision 1.6 2005/03/29 02:18:47 taylor
15 * Various 64-bit platform fixes
16 * Fix compiler errors with MAKE_FS1 and fix gr_set_bitmap() too
17 * Make sure that turrets can fire at asteroids for FS1 (needed for a couple missions)
18 * Streaming audio support (big thanks to Pierre Willenbrock!!)
19 * Removed dependance on strings.tbl for FS1 since we don't actually need it now
31 typedef struct adpcmcoef_tag{
36 typedef struct adpcmblockheader_tag {
43 typedef struct adpcmwaveformat_tag {
45 ushort wSamplesPerBlock;
50 typedef struct ADPCM_FMT_T {
51 ADPCMWAVEFORMAT adpcm;
52 ADPCMBLOCKHEADER *header;
57 uint sample_frame_size;
58 uint samples_left_in_block;
63 typedef struct acm_stream_t {
69 // similar to BIAL_IF_MACRO in SDL_sound
70 #define IF_ERR(a, b) if (a) { printf("IF_ERR-ACM, function: %s, line %d...\n", __FUNCTION__, __LINE__); return b; }
73 /*****************************************************************************
74 * Begin ADPCM compression handler... */
77 * ADPCM decoding routines taken with permission from SDL_sound
78 * Copyright (C) 2001 Ryan C. Gordon.
81 #define FIXED_POINT_COEF_BASE 256
82 #define FIXED_POINT_ADAPTION_BASE 256
83 #define SMALLEST_ADPCM_DELTA 16
87 static int read_ushort(SDL_RWops *rw, ushort *i)
89 int rc = SDL_RWread(rw, i, sizeof(ushort), 1);
95 static int read_short(SDL_RWops *rw, short *i)
97 int rc = SDL_RWread(rw, i, sizeof(short), 1);
103 static int read_ubyte(SDL_RWops *rw, ubyte *i)
105 int rc = SDL_RWread(rw, i, sizeof(ubyte), 1);
110 // decoding functions
111 static int read_adpcm_block_headers(SDL_RWops *rw, adpcm_fmt_t *fmt)
114 int max = fmt->adpcm.wav.num_channels;
116 if (fmt->bytes_remaining < fmt->adpcm.wav.block_align) {
120 fmt->bytes_remaining -= fmt->adpcm.wav.block_align;
121 fmt->bytes_processed += fmt->adpcm.wav.block_align;
123 for (i = 0; i < max; i++)
124 IF_ERR(!read_ubyte(rw, &fmt->header[i].bPredictor), 0);
126 for (i = 0; i < max; i++)
127 IF_ERR(!read_ushort(rw, &fmt->header[i].iDelta), 0);
129 for (i = 0; i < max; i++)
130 IF_ERR(!read_short(rw, &fmt->header[i].iSamp1), 0);
132 for (i = 0; i < max; i++)
133 IF_ERR(!read_short(rw, &fmt->header[i].iSamp2), 0);
135 fmt->samples_left_in_block = fmt->adpcm.wSamplesPerBlock;
136 fmt->nibble_state = 0;
141 static void do_adpcm_nibble(ubyte nib, ADPCMBLOCKHEADER *header, int lPredSamp)
143 static const short max_audioval = ((1<<(16-1))-1);
144 static const short min_audioval = -(1<<(16-1));
145 static const ushort AdaptionTable[] = {
146 230, 230, 230, 230, 307, 409, 512, 614,
147 768, 614, 512, 409, 307, 230, 230, 230
154 lNewSamp = lPredSamp + (header->iDelta * (nib - 0x10));
156 lNewSamp = lPredSamp + (header->iDelta * nib);
160 if (lNewSamp < min_audioval) {
161 lNewSamp = min_audioval;
162 } else if (lNewSamp > max_audioval) {
163 lNewSamp = max_audioval;
166 delta = (header->iDelta * AdaptionTable[nib]) / FIXED_POINT_ADAPTION_BASE;
168 if (delta < SMALLEST_ADPCM_DELTA)
169 delta = SMALLEST_ADPCM_DELTA;
171 header->iDelta = delta;
172 header->iSamp2 = header->iSamp1;
173 header->iSamp1 = (short)lNewSamp;
176 static int decode_adpcm_sample_frame(SDL_RWops *rw, adpcm_fmt_t *fmt)
179 int max = fmt->adpcm.wav.num_channels;
180 ubyte nib = fmt->nibble;
181 short iCoef1, iCoef2;
184 for (i = 0; i < max; i++) {
185 iCoef1 = fmt->adpcm.aCoef[fmt->header[i].bPredictor].iCoef1;
186 iCoef2 = fmt->adpcm.aCoef[fmt->header[i].bPredictor].iCoef2;
187 lPredSamp = ((fmt->header[i].iSamp1 * iCoef1) + (fmt->header[i].iSamp2 * iCoef2)) / FIXED_POINT_COEF_BASE;
189 if (fmt->nibble_state == 0) {
190 IF_ERR(!read_ubyte(rw, &nib), 0);
191 fmt->nibble_state = 1;
192 do_adpcm_nibble(nib >> 4, &fmt->header[i], lPredSamp);
194 fmt->nibble_state = 0;
195 do_adpcm_nibble(nib & 0x0F, &fmt->header[i], lPredSamp);
204 static void put_adpcm_sample_frame1(ubyte *_buf, adpcm_fmt_t *fmt)
206 short *buf = (short *)_buf;
209 for (i = 0; i < fmt->adpcm.wav.num_channels; i++)
210 *buf++ = fmt->header[i].iSamp1;
213 static void put_adpcm_sample_frame2(ubyte *_buf, adpcm_fmt_t *fmt)
215 short *buf = (short *)_buf;
218 for (i = 0; i < fmt->adpcm.wav.num_channels; i++)
219 *buf++ = fmt->header[i].iSamp2;
222 static uint read_sample_fmt_adpcm(ubyte *data, SDL_RWops *rw, adpcm_fmt_t *fmt)
226 while (bw < fmt->buffer_size) {
227 // write ongoing sample frame before reading more data...
228 switch (fmt->samples_left_in_block) {
229 case 0: // need to read a new block...
230 if (!read_adpcm_block_headers(rw, fmt))
233 // only write first sample frame for now.
234 put_adpcm_sample_frame2(data + bw, fmt);
235 fmt->samples_left_in_block--;
236 bw += fmt->sample_frame_size;
239 case 1: // output last sample frame of block...
240 put_adpcm_sample_frame1(data + bw, fmt);
241 fmt->samples_left_in_block--;
242 bw += fmt->sample_frame_size;
245 default: // output latest sample frame and read a new one...
246 put_adpcm_sample_frame1(data + bw, fmt);
247 fmt->samples_left_in_block--;
248 bw += fmt->sample_frame_size;
250 if (!decode_adpcm_sample_frame(rw, fmt))
258 /* End ADPCM Compression Handler *
259 *****************************************************************************/
261 static void adpcm_memory_free(adpcm_fmt_t *fmt)
263 SDL_assert( fmt != NULL );
265 if (fmt->adpcm.aCoef != NULL) {
266 free(fmt->adpcm.aCoef);
267 fmt->adpcm.aCoef = NULL;
270 if (fmt->header != NULL) {
278 // =============================================================================
279 // ACM_convert_ADPCM_to_PCM()
281 // Convert an ADPCM wave file to a PCM wave file using the Audio Compression Manager
283 // parameters: *pwfxSrc => address of WAVE_chunk structure describing the source wave
284 // *src => pointer to raw source wave data
285 // src_len => num bytes of source wave data
286 // **dest => pointer to pointer to dest buffer for wave data
287 // (mem is allocated in this function if *dest is NULL)
288 // max_dest_bytes => Maximum memory allocated to dest
289 // *dest_len => returns num bytes of wave data in converted form (OUTPUT PARAMETER)
290 // *src_bytes_used => returns num bytes of src actually used in the conversion
291 // dest_bps => bits per sample that data should be uncompressed to
293 // returns: 0 => success
294 // -1 => could not convert wav file
298 // 1. Storage for the decompressed audio will be allocated in this function if *dest in NULL.
299 // The caller is responsible for freeing this memory later.
301 int ACM_convert_ADPCM_to_PCM(WAVE_chunk *pwfxSrc, ubyte *src, int src_len, ubyte **dest, int max_dest_bytes, int *dest_len, unsigned int *src_bytes_used, unsigned short dest_bps)
303 SDL_assert( pwfxSrc != NULL );
304 SDL_assert( pwfxSrc->code == WAVE_FORMAT_ADPCM );
305 SDL_assert( pwfxSrc->extra_data != NULL );
306 SDL_assert( src != NULL );
307 SDL_assert( src_len > 0 );
308 SDL_assert( dest_len != NULL );
313 SDL_RWops *hdr = SDL_RWFromMem(pwfxSrc->extra_data, pwfxSrc->extra_size);
314 SDL_RWops *rw = SDL_RWFromMem(src, src_len);
316 adpcm_fmt_t *fmt = NULL;
318 // estimate size of uncompressed data
319 // uncompressed data has: channels=pfwxScr->nChannels, bitPerSample=destbits
320 // compressed data has: channels=pfwxScr->nChannels, bitPerSample=pwfxSrc->wBitsPerSample
321 new_size = ( src_len * dest_bps ) / pwfxSrc->bits_per_sample;
322 new_size *= 2;//buffer must be large enough for all data
324 // DO NOT free() here, *estimated size*
325 if ( *dest == NULL ) {
326 *dest = (ubyte *)malloc(new_size);
332 // memset(*dest, 0x80, new_size); // silence (for 8 bits/sample)
333 memset(*dest, 0x00, new_size); // silence (for 16 bits/sample)
336 fmt = (adpcm_fmt_t *)malloc(sizeof(adpcm_fmt_t));
342 memset(fmt, '\0', sizeof(adpcm_fmt_t));
344 // wav header info (WAVE_chunk)
345 fmt->adpcm.wav.code = pwfxSrc->code;
346 fmt->adpcm.wav.num_channels = pwfxSrc->num_channels;
347 fmt->adpcm.wav.sample_rate = pwfxSrc->sample_rate;
348 fmt->adpcm.wav.bytes_per_second = pwfxSrc->bytes_per_second;
349 fmt->adpcm.wav.block_align = pwfxSrc->block_align;
350 fmt->adpcm.wav.bits_per_sample = pwfxSrc->bits_per_sample;
352 // sanity check, should always be 4
353 if (fmt->adpcm.wav.bits_per_sample != 4) {
357 // adpcm specific header info
358 if ( !read_ushort(hdr, &fmt->adpcm.wSamplesPerBlock) ) {
362 if ( !read_ushort(hdr, &fmt->adpcm.wNumCoef) ) {
366 // allocate memory for COEF struct and fill it
367 fmt->adpcm.aCoef = (ADPCMCOEFSET *)malloc(sizeof(ADPCMCOEFSET) * fmt->adpcm.wNumCoef);
369 if (fmt->adpcm.aCoef == NULL) {
373 for (int i=0; i<fmt->adpcm.wNumCoef; i++) {
374 if ( !read_short(hdr, &fmt->adpcm.aCoef[i].iCoef1) ) {
378 if ( !read_short(hdr, &fmt->adpcm.aCoef[i].iCoef2) ) {
383 // allocate memory for the ADPCM block header that's to be filled later
384 fmt->header = (ADPCMBLOCKHEADER *)malloc(sizeof(ADPCMBLOCKHEADER) * fmt->adpcm.wav.num_channels);
386 if (fmt->header == NULL) {
390 // buffer to estimated size since we have to process the whole thing at once
391 fmt->buffer_size = new_size;
392 fmt->bytes_remaining = src_len;
393 fmt->bytes_processed = 0;
395 fmt->sample_frame_size = dest_bps/8*pwfxSrc->num_channels;
397 if ( !max_dest_bytes ) {
398 max_dest_bytes = new_size;
402 rc = read_sample_fmt_adpcm(*dest, rw, fmt);
408 // send back actual sizes
410 *src_bytes_used = fmt->bytes_processed;
413 adpcm_memory_free(fmt);
421 adpcm_memory_free(fmt);
430 int ACM_stream_open(WAVE_chunk *pwfxSrc, WAVE_chunk *pwfxDest, void **stream, int dest_bps)
432 SDL_assert( pwfxSrc != NULL );
433 SDL_assert( pwfxSrc->code == WAVE_FORMAT_ADPCM );
434 SDL_assert( pwfxSrc->extra_data != NULL );
435 SDL_assert( stream != NULL );
437 SDL_RWops *hdr = SDL_RWFromMem(pwfxSrc->extra_data, pwfxSrc->extra_size);
438 acm_stream_t *str = NULL;
440 adpcm_fmt_t *fmt = (adpcm_fmt_t *)malloc(sizeof(adpcm_fmt_t));
446 memset(fmt, '\0', sizeof(adpcm_fmt_t));
448 // wav header info (WAVE_chunk)
449 fmt->adpcm.wav.code = pwfxSrc->code;
450 fmt->adpcm.wav.num_channels = pwfxSrc->num_channels;
451 fmt->adpcm.wav.sample_rate = pwfxSrc->sample_rate;
452 fmt->adpcm.wav.bytes_per_second = pwfxSrc->bytes_per_second;
453 fmt->adpcm.wav.block_align = pwfxSrc->block_align;
454 fmt->adpcm.wav.bits_per_sample = pwfxSrc->bits_per_sample;
456 // sanity check, should always be 4
457 if (fmt->adpcm.wav.bits_per_sample != 4) {
461 // adpcm specific header info
462 if ( !read_ushort(hdr, &fmt->adpcm.wSamplesPerBlock) ) {
466 if ( !read_ushort(hdr, &fmt->adpcm.wNumCoef) ) {
470 // allocate memory for COEF struct and fill it
471 fmt->adpcm.aCoef = (ADPCMCOEFSET *)malloc(sizeof(ADPCMCOEFSET) * fmt->adpcm.wNumCoef);
473 if (fmt->adpcm.aCoef == NULL) {
477 for (int i=0; i<fmt->adpcm.wNumCoef; i++) {
478 if ( !read_short(hdr, &fmt->adpcm.aCoef[i].iCoef1) ) {
482 if ( !read_short(hdr, &fmt->adpcm.aCoef[i].iCoef2) ) {
487 // allocate memory for the ADPCM block header that's to be filled later
488 fmt->header = (ADPCMBLOCKHEADER *)malloc(sizeof(ADPCMBLOCKHEADER) * fmt->adpcm.wav.num_channels);
490 if (fmt->header == NULL) {
494 fmt->sample_frame_size = dest_bps/8*pwfxSrc->num_channels;
496 str = (acm_stream_t *)malloc(sizeof(acm_stream_t));
503 str->dest_bps = (ushort)dest_bps;
504 str->src_bps = pwfxSrc->bits_per_sample;
513 adpcm_memory_free(fmt);
521 int ACM_stream_close(void *stream)
523 SDL_assert(stream != NULL);
525 acm_stream_t *str = (acm_stream_t *)stream;
527 adpcm_memory_free(str->fmt);
534 * How many bytes are needed to get approximately dest_len bytes output?
536 int ACM_query_source_size(void *stream, int dest_len)
538 SDL_assert(stream != NULL);
540 acm_stream_t *str = (acm_stream_t *)stream;
542 // estimate size of compressed data
543 // uncompressed data has: channels=pfwxScr->nChannels, bitPerSample=destbits
544 // compressed data has: channels=pfwxScr->nChannels, bitPerSample=pwfxSrc->wBitsPerSample
545 return (dest_len * str->src_bps) / str->dest_bps;
549 * How many output bytes would approximately be produced by src_len bytes input?
551 int ACM_query_dest_size(void *stream, int src_len)
553 SDL_assert(stream != NULL);
555 acm_stream_t *str = (acm_stream_t *)stream;
557 // estimate size of uncompressed data
558 // uncompressed data has: channels=pfwxScr->nChannels, bitPerSample=destbits
559 // compressed data has: channels=pfwxScr->nChannels, bitPerSample=pwfxSrc->wBitsPerSample
560 return ( src_len * str->dest_bps ) / str->src_bps;
564 * We are allowed to use fewer bytes than delivered to us
566 int ACM_convert(void *stream, ubyte *src, int src_len, ubyte *dest, int max_dest_bytes, unsigned int *dest_len, unsigned int *src_bytes_used)
568 SDL_assert(stream != NULL);
569 SDL_assert( src != NULL );
570 SDL_assert( src_len > 0 );
571 SDL_assert( dest_len != NULL );
573 acm_stream_t *str = (acm_stream_t *)stream;
576 SDL_RWops *rw = SDL_RWFromMem(src, src_len);
578 // buffer to estimated size since we have to process the whole thing at once
579 str->fmt->buffer_size = max_dest_bytes;
580 str->fmt->bytes_remaining = src_len;
581 str->fmt->bytes_processed = 0;
584 rc = read_sample_fmt_adpcm(dest, rw, str->fmt);
586 // send back actual sizes
588 *src_bytes_used = str->fmt->bytes_processed;