FS2_Open
Open source remastering of the Freespace 2 engine
acm.cpp
Go to the documentation of this file.
1 /***********************************************************
2  * Portions of this file are Copyright (c) Ryan C. Gordon
3  ***********************************************************/
4 
5 
6 #ifdef _WIN32
7 #define NONEWWAVE
8 #include <windows.h>
9 #endif
10 
11 #include "globalincs/pstypes.h"
12 #include "sound/acm.h"
13 
14 // we aren't including all of mmreg.h on Windows so this picks up the slack
15 #ifndef WAVE_FORMAT_ADPCM
16 #define WAVE_FORMAT_ADPCM 2
17 #endif
18 
19 
20 typedef struct adpcmcoef_tag {
21  short iCoef1;
22  short iCoef2;
23 } ADPCMCOEFSET;
24 
25 typedef struct adpcmblockheader_tag {
28  short iSamp1;
29  short iSamp2;
31 
32 typedef struct adpcmwaveformat_tag {
35  WORD wNumCoef;
38 
39 typedef struct ADPCM_FMT_T {
42 
50 
52 } adpcm_fmt_t;
53 
54 typedef struct acm_stream_t {
58 } acm_stream_t;
59 
60 
61 // similar to BIAL_IF_MACRO in SDL_sound
62 #define IF_ERR(a, b) if (a) { mprintf(("ACM ERROR, line %d...\n", __LINE__)); return b; }
63 #define IF_ERR2(a, b) if (a) { mprintf(("ACM ERROR, line %d...\n", __LINE__)); b; }
64 
65 
66 /*****************************************************************************
67  * Begin ADPCM compression handler... */
68 
69 /*
70  * ADPCM decoding routines taken with permission from SDL_sound
71  * Copyright (C) 2001 Ryan C. Gordon.
72  */
73 
74 #define FIXED_POINT_COEF_BASE 256
75 #define FIXED_POINT_ADAPTION_BASE 256
76 #define SMALLEST_ADPCM_DELTA 16
77 
78 
79 // utility functions
80 static int read_ushort(HMMIO rw, ushort *i)
81 {
82  int rc = mmioRead( rw, (char *)i, sizeof(ushort) );
83  IF_ERR(rc != sizeof(ushort), 0);
84  *i = INTEL_SHORT(*i); //-V570
85  return 1;
86 }
87 
88 static int read_word(HMMIO rw, WORD *i)
89 {
90  int rc = mmioRead( rw, (char *)i, sizeof(WORD) );
91  IF_ERR(rc != sizeof(WORD), 0);
92  return 1;
93 }
94 
95 // same as read_word() but swapped
96 static int read_word_s(HMMIO rw, WORD *i)
97 {
98  int rc = mmioRead( rw, (char *)i, sizeof(WORD) );
99  IF_ERR(rc != sizeof(WORD), 0);
100  *i = INTEL_SHORT(*i); //-V570
101  return 1;
102 }
103 
104 static int read_short(HMMIO rw, short *i)
105 {
106  int rc = mmioRead( rw, (char *)i, sizeof(short) );
107  IF_ERR(rc != sizeof(short), 0);
108  *i = INTEL_SHORT(*i); //-V570
109  return 1;
110 }
111 
112 static int read_dword(HMMIO rw, DWORD *i)
113 {
114  int rc = mmioRead( rw, (char *)i, sizeof(DWORD) );
115  IF_ERR(rc != sizeof(DWORD), 0);
116  return 1;
117 }
118 
119 static int read_ubyte(HMMIO rw, ubyte *i)
120 {
121  int rc = mmioRead( rw, (char *)i, sizeof(ubyte) );
122  IF_ERR(rc != sizeof(ubyte), 0);
123  return 1;
124 }
125 
126 // decoding functions
127 static int read_adpcm_block_headers(HMMIO rw, adpcm_fmt_t *fmt)
128 {
129  int i;
130  int max = fmt->adpcm.wav.nChannels;
131 
132  if (fmt->bytes_remaining < fmt->adpcm.wav.nBlockAlign) {
133  return 0;
134  }
135 
136  fmt->bytes_remaining -= fmt->adpcm.wav.nBlockAlign;
137  fmt->bytes_processed += fmt->adpcm.wav.nBlockAlign;
138 
139  for (i = 0; i < max; i++) {
140  IF_ERR(!read_ubyte(rw, &fmt->header[i].bPredictor), 0);
141  }
142 
143  for (i = 0; i < max; i++) {
144  IF_ERR(!read_ushort(rw, &fmt->header[i].iDelta), 0);
145  }
146 
147  for (i = 0; i < max; i++) {
148  IF_ERR(!read_short(rw, &fmt->header[i].iSamp1), 0);
149  }
150 
151  for (i = 0; i < max; i++) {
152  IF_ERR(!read_short(rw, &fmt->header[i].iSamp2), 0);
153  }
154 
156  fmt->nibble_state = 0;
157 
158  return 1;
159 }
160 
161 static void do_adpcm_nibble(ubyte nib, ADPCMBLOCKHEADER *header, int lPredSamp)
162 {
163  static const short max_audioval = ((1<<(16-1))-1);
164  static const short min_audioval = -(1<<(16-1));
165  static const ushort AdaptionTable[] = {
166  230, 230, 230, 230, 307, 409, 512, 614,
167  768, 614, 512, 409, 307, 230, 230, 230
168  };
169 
170  int lNewSamp;
171  ushort delta;
172 
173  if (nib & 0x08) {
174  lNewSamp = lPredSamp + (header->iDelta * (nib - 0x10));
175  } else {
176  lNewSamp = lPredSamp + (header->iDelta * nib);
177  }
178 
179  // clamp value...
180  if (lNewSamp < min_audioval) {
181  lNewSamp = min_audioval;
182  } else if (lNewSamp > max_audioval) {
183  lNewSamp = max_audioval;
184  }
185 
186  delta = (header->iDelta * AdaptionTable[nib]) / FIXED_POINT_ADAPTION_BASE;
187 
188  if (delta < SMALLEST_ADPCM_DELTA) {
189  delta = SMALLEST_ADPCM_DELTA;
190  }
191 
192  header->iDelta = delta;
193  header->iSamp2 = header->iSamp1;
194  header->iSamp1 = (short)lNewSamp;
195 }
196 
197 static int decode_adpcm_sample_frame(HMMIO rw, adpcm_fmt_t *fmt)
198 {
199  int i;
200  int max = fmt->adpcm.wav.nChannels;
201  ubyte nib = fmt->nibble;
202  short iCoef1, iCoef2;
203  int lPredSamp;
204 
205  for (i = 0; i < max; i++) {
206  iCoef1 = fmt->adpcm.aCoef[fmt->header[i].bPredictor].iCoef1;
207  iCoef2 = fmt->adpcm.aCoef[fmt->header[i].bPredictor].iCoef2;
208  lPredSamp = ((fmt->header[i].iSamp1 * iCoef1) + (fmt->header[i].iSamp2 * iCoef2)) / FIXED_POINT_COEF_BASE;
209 
210  if (fmt->nibble_state == 0) {
211  IF_ERR(!read_ubyte(rw, &nib), 0);
212  fmt->nibble_state = 1;
213  do_adpcm_nibble(nib >> 4, &fmt->header[i], lPredSamp);
214  } else {
215  fmt->nibble_state = 0;
216  do_adpcm_nibble(nib & 0x0F, &fmt->header[i], lPredSamp);
217  }
218  }
219 
220  fmt->nibble = nib;
221 
222  return 1;
223 }
224 
225 static void put_adpcm_sample_frame1(ubyte *_buf, adpcm_fmt_t *fmt)
226 {
227  int i;
228 
229  if (fmt->dest_bps == 16) {
230  short *buf = (short *)_buf;
231 
232  for (i = 0; i < fmt->adpcm.wav.nChannels; i++) {
233  *buf++ = fmt->header[i].iSamp1;
234  }
235  } else {
236  Assert( fmt->dest_bps == 8 );
237 
238  for (i = 0; i < fmt->adpcm.wav.nChannels; i++) {
239  int i_val = (int)(fmt->header[i].iSamp1 / 255) + 128;
240  CLAMP(i_val, 0, 255);
241 
242  *_buf++ = (ubyte)i_val;
243  }
244  }
245 }
246 
247 static void put_adpcm_sample_frame2(ubyte *_buf, adpcm_fmt_t *fmt)
248 {
249  int i;
250 
251  if (fmt->dest_bps == 16) {
252  short *buf = (short *)_buf;
253 
254  for (i = 0; i < fmt->adpcm.wav.nChannels; i++) {
255  *buf++ = fmt->header[i].iSamp2;
256  }
257  } else {
258  Assert( fmt->dest_bps == 8 );
259 
260  for (i = 0; i < fmt->adpcm.wav.nChannels; i++) {
261  int i_val = (int)(fmt->header[i].iSamp2 / 255) + 128;
262  CLAMP(i_val, 0, 255);
263 
264  *_buf++ = (ubyte)i_val;
265  }
266  }
267 }
268 
269 static uint read_sample_fmt_adpcm(ubyte *data, HMMIO rw, adpcm_fmt_t *fmt)
270 {
271  uint bw = 0;
272 
273  while (bw < fmt->buffer_size) {
274  // write ongoing sample frame before reading more data...
275  switch (fmt->samples_left_in_block) {
276  case 0: // need to read a new block...
277 
278  if (!read_adpcm_block_headers(rw, fmt)) {
279  return(bw); // EOF
280  }
281 
282  // only write first sample frame for now.
283  put_adpcm_sample_frame2(data + bw, fmt);
284  fmt->samples_left_in_block--;
285  bw += fmt->sample_frame_size;
286  break;
287 
288  case 1: // output last sample frame of block...
289  put_adpcm_sample_frame1(data + bw, fmt);
290  fmt->samples_left_in_block--;
291  bw += fmt->sample_frame_size;
292  break;
293 
294  default: // output latest sample frame and read a new one...
295  put_adpcm_sample_frame1(data + bw, fmt);
296  fmt->samples_left_in_block--;
297  bw += fmt->sample_frame_size;
298 
299  if (!decode_adpcm_sample_frame(rw, fmt)) {
300  return(bw);
301  }
302  }
303  }
304 
305  return(bw);
306 }
307 
308 /* End ADPCM Compression Handler *
309  *****************************************************************************/
310 
311 static void adpcm_memory_free(adpcm_fmt_t *fmt)
312 {
313  if (fmt->adpcm.aCoef != NULL) {
314  vm_free(fmt->adpcm.aCoef);
315  fmt->adpcm.aCoef = NULL;
316  }
317 
318  if (fmt->header != NULL) {
319  vm_free(fmt->header);
320  fmt->header = NULL;
321  }
322 
323  if (fmt != NULL) {
324  vm_free(fmt);
325  fmt = NULL;
326  }
327 }
328 
329 // =============================================================================
330 // ACM_convert_ADPCM_to_PCM()
331 //
332 // Convert an ADPCM wave file to a PCM wave file using the Audio Compression Manager
333 //
334 // parameters: *pwfxSrc => address of WAVEFORMATEX structure describing the source wave
335 // *src => pointer to raw source wave data
336 // src_len => num bytes of source wave data
337 // **dest => pointer to pointer to dest buffer for wave data
338 // (mem is allocated in this function if *dest is NULL)
339 // max_dest_bytes => Maximum memory allocated to dest
340 // *dest_len => returns num bytes of wave data in converted form (OUTPUT PARAMETER)
341 // *src_bytes_used => returns num bytes of src actually used in the conversion
342 // dest_bps => bits per sample that data should be uncompressed to
343 //
344 // returns: 0 => success
345 // 1 => could not convert wav file
346 //
347 // NOTES:
348 // 1. Storage for the decompressed audio will be allocated in this function if *dest in NULL.
349 // The caller is responsible for freeing this memory later.
350 //
351 int ACM_convert_ADPCM_to_PCM(WAVEFORMATEX *pwfxSrc, ubyte *src, int src_len, ubyte **dest, int max_dest_bytes, int *dest_len, unsigned int *src_bytes_used, int dest_bps)
352 {
353  Assert( src != NULL );
354  Assert( src_len > 0 );
355  Assert( dest_len != NULL );
356 
357  if (pwfxSrc == NULL) {
358  Int3();
359  return -1;
360  }
361 
362  Assert( pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM );
363 
364  MMIOINFO IOhdr, IOrw;
365 
366  memset( &IOhdr, 0, sizeof(MMIOINFO) );
367  memset( &IOrw, 0, sizeof(MMIOINFO) );
368 
369  IOhdr.pchBuffer = (char *)pwfxSrc;
370  IOhdr.fccIOProc = FOURCC_MEM;
371  IOhdr.cchBuffer = (sizeof(WAVEFORMATEX) + pwfxSrc->cbSize);
372 
373  IOrw.pchBuffer = (char *)src;
374  IOrw.fccIOProc = FOURCC_MEM;
375  IOrw.cchBuffer = src_len;
376 
377  HMMIO hdr = mmioOpen( NULL, &IOhdr, MMIO_READ );
378  HMMIO rw = mmioOpen( NULL, &IOrw, MMIO_READ );
379  uint rc;
380  uint new_size = 0;
381  int left_over = 0;
382  int i;
383 
384  adpcm_fmt_t *fmt = (adpcm_fmt_t *)vm_malloc(sizeof(adpcm_fmt_t));
385  IF_ERR(fmt == NULL, -1);
386  memset(fmt, '\0', sizeof(adpcm_fmt_t));
387 
388  // wav header info (WAVEFORMATEX)
389  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.wFormatTag), goto Error);
390  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.nChannels), goto Error);
391  IF_ERR2(!read_dword(hdr, &fmt->adpcm.wav.nSamplesPerSec), goto Error);
392  IF_ERR2(!read_dword(hdr, &fmt->adpcm.wav.nAvgBytesPerSec), goto Error);
393  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.nBlockAlign), goto Error);
394  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.wBitsPerSample), goto Error);
395  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.cbSize), goto Error);
396  // adpcm specific header info
397  IF_ERR2(!read_word_s(hdr, &fmt->adpcm.wSamplesPerBlock), goto Error);
398  IF_ERR2(!read_word_s(hdr, &fmt->adpcm.wNumCoef), goto Error);
399 
400  // allocate memory for COEF struct and fill it
401  fmt->adpcm.aCoef = (ADPCMCOEFSET *)vm_malloc(sizeof(ADPCMCOEFSET) * fmt->adpcm.wNumCoef);
402  IF_ERR2(fmt->adpcm.aCoef == NULL, goto Error);
403 
404  for (i = 0; i < fmt->adpcm.wNumCoef; i++) {
405  IF_ERR2(!read_short(hdr, &fmt->adpcm.aCoef[i].iCoef1), goto Error);
406  IF_ERR2(!read_short(hdr, &fmt->adpcm.aCoef[i].iCoef2), goto Error);
407  }
408 
409  // allocate memory for the ADPCM block header that's to be filled later
411  IF_ERR2(fmt->header == NULL, goto Error);
412 
413  // estimate size of uncompressed data
414  // uncompressed data has: channels=pfwxScr->nChannels, bitPerSample=destbits
415  // compressed data has: channels=pfwxScr->nChannels, bitPerSample=pwfxSrc->wBitsPerSample
416  new_size = (src_len / fmt->adpcm.wav.nBlockAlign) * fmt->adpcm.wSamplesPerBlock * (dest_bps / 8);
417 
418  // DO NOT free() here, *estimated size*
419  if ( *dest == NULL ) {
420  *dest = (ubyte *)vm_malloc(new_size);
421 
422  if (*dest == NULL) {
423  goto Error;
424  }
425 
426  // silence
427  if (dest_bps == 8) {
428  memset(*dest, 0x80, new_size);
429  } else {
430  memset(*dest, 0x00, new_size);
431  }
432  }
433 
434  // buffer to estimated size since we have to process the whole thing at once
435  fmt->buffer_size = new_size;
436  fmt->bytes_remaining = src_len;
437  fmt->bytes_processed = 0;
438 
439  // really fix and REMOVE
440  if (fmt->adpcm.wav.wBitsPerSample != 4) {
442  }
443 
444  // sanity check, should always be 4
445  if (fmt->adpcm.wav.wBitsPerSample != 4) {
446  goto Error;
447  }
448 
449  fmt->sample_frame_size = ((dest_bps / 8) * pwfxSrc->nChannels);
450  fmt->dest_bps = (ushort)dest_bps;
451 
452  if ( !max_dest_bytes ) {
453  max_dest_bytes = new_size;
454  }
455 
456  // convert to PCM
457  rc = read_sample_fmt_adpcm(*dest, rw, fmt);
458 
459  left_over = (src_len - fmt->bytes_processed);
460 
461  if ( (left_over > 0) && (left_over < fmt->adpcm.wav.nBlockAlign) ) {
462  // hmm, we have some left over, probably a crappy file. just add in the
463  // remainder since we don't have enough frame size left over for a decode
464  // but we should have decoded most of the data already
465  mprintf(("ACM ERROR: Have leftover data after decode!!\n"));
466  fmt->bytes_processed += left_over;
467  }
468 
469  // send back actual sizes
470  if (dest_len) {
471  *dest_len = rc;
472  }
473 
474  if (src_bytes_used) {
475  *src_bytes_used = fmt->bytes_processed;
476  }
477 
478  // cleanup
479  adpcm_memory_free(fmt);
480 
481  // cleanup mmio stuff
482  mmioClose( rw, 0 );
483  mmioClose( hdr, 0 );
484 
485  return 0;
486 
487 Error:
488  // cleanup
489  if (fmt) {
490  adpcm_memory_free(fmt);
491  }
492 
493  mmioClose( rw, 0 );
494  mmioClose( hdr, 0 );
495 
496  return -1;
497 }
498 
499 int ACM_stream_open(WAVEFORMATEX *pwfxSrc, WAVEFORMATEX *pwfxDest, void **stream, int dest_bps)
500 {
501  Assert( stream != NULL );
502 
503  if (pwfxSrc == NULL) {
504  Int3();
505  return -1;
506  }
507 
508  Assert( pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM );
509 
510  int i;
511  acm_stream_t *str = NULL;
512  MMIOINFO IOhdr;
513 
514  memset( &IOhdr, 0, sizeof(MMIOINFO) );
515 
516  IOhdr.pchBuffer = (char *)pwfxSrc;
517  IOhdr.fccIOProc = FOURCC_MEM;
518  IOhdr.cchBuffer = (sizeof(WAVEFORMATEX) + pwfxSrc->cbSize);
519 
520  HMMIO hdr = mmioOpen( NULL, &IOhdr, MMIO_READ );
521 
522  adpcm_fmt_t *fmt = (adpcm_fmt_t *)vm_malloc(sizeof(adpcm_fmt_t));
523  IF_ERR2(fmt == NULL, goto Error);
524  memset(fmt, '\0', sizeof(adpcm_fmt_t));
525 
526  // wav header info (WAVEFORMATEX)
527  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.wFormatTag), goto Error);
528  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.nChannels), goto Error);
529  IF_ERR2(!read_dword(hdr, &fmt->adpcm.wav.nSamplesPerSec), goto Error);
530  IF_ERR2(!read_dword(hdr, &fmt->adpcm.wav.nAvgBytesPerSec), goto Error);
531  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.nBlockAlign), goto Error);
532  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.wBitsPerSample), goto Error);
533  IF_ERR2(!read_word(hdr, &fmt->adpcm.wav.cbSize), goto Error);
534  // adpcm specific header info
535  IF_ERR2(!read_word_s(hdr, &fmt->adpcm.wSamplesPerBlock), goto Error);
536  IF_ERR2(!read_word_s(hdr, &fmt->adpcm.wNumCoef), goto Error);
537 
538  // allocate memory for COEF struct and fill it
539  fmt->adpcm.aCoef = (ADPCMCOEFSET *)vm_malloc(sizeof(ADPCMCOEFSET) * fmt->adpcm.wNumCoef);
540  IF_ERR2(fmt->adpcm.aCoef == NULL, goto Error);
541 
542  for (i = 0; i < fmt->adpcm.wNumCoef; i++) {
543  IF_ERR2(!read_short(hdr, &fmt->adpcm.aCoef[i].iCoef1), goto Error);
544  IF_ERR2(!read_short(hdr, &fmt->adpcm.aCoef[i].iCoef2), goto Error);
545  }
546 
547  // allocate memory for the ADPCM block header that's to be filled later
549  IF_ERR2(fmt->header == NULL, goto Error);
550 
551  // sanity check, should always be 4
552  if (fmt->adpcm.wav.wBitsPerSample != 4) {
553  adpcm_memory_free(fmt);
554  mmioClose( hdr, 0 );
555 
556  return -1;
557  }
558 
559  fmt->sample_frame_size = dest_bps/8*pwfxSrc->nChannels;
560  fmt->dest_bps = (ushort)dest_bps;
561 
562  str = (acm_stream_t *)vm_malloc(sizeof(acm_stream_t));
563  IF_ERR2(str == NULL, goto Error);
564  str->fmt = fmt;
565  str->dest_bps = (ushort)dest_bps;
566  str->src_bps = pwfxSrc->wBitsPerSample;
567 
568  if (stream) {
569  *stream = str;
570  }
571 
572  // close the io stream
573  mmioClose( hdr, 0 );
574 
575  return 0;
576 
577 Error:
578  if (fmt) {
579  adpcm_memory_free(fmt);
580  }
581 
582  if (str) {
583  vm_free(str);
584  }
585 
586  mmioClose( hdr, 0 );
587 
588  return -1;
589 }
590 
592 {
593  if (stream == NULL) {
594  Int3();
595  return 0;
596  }
597 
598  acm_stream_t *str = (acm_stream_t *)stream;
599  adpcm_memory_free(str->fmt);
600  vm_free(str);
601 
602  return 0;
603 }
604 
605 int ACM_query_source_size(void *stream, int dest_len)
606 {
607  if (stream == NULL) {
608  Int3();
609  return 0;
610  }
611 
612  acm_stream_t *str = (acm_stream_t *)stream;
613 
614  // estimate size of compressed data
615  // uncompressed data has: channels=pfwxScr->nChannels, bitPerSample=destbits
616  // compressed data has: channels=pfwxScr->nChannels, bitPerSample=pwfxSrc->wBitsPerSample
617  return (dest_len * str->src_bps) / str->dest_bps;
618 }
619 
620 int ACM_query_dest_size(void *stream, int src_len)
621 {
622  if (stream == NULL) {
623  Int3();
624  return 0;
625  }
626 
627  acm_stream_t *str = (acm_stream_t *)stream;
628 
629  // estimate size of uncompressed data
630  // uncompressed data has: channels=pfwxScr->nChannels, bitPerSample=destbits
631  // compressed data has: channels=pfwxScr->nChannels, bitPerSample=pwfxSrc->wBitsPerSample
632  return ( src_len * str->dest_bps ) / str->src_bps;
633 }
634 
635 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)
636 {
637  Assert( src != NULL );
638  Assert( src_len > 0 );
639  Assert( dest_len != NULL );
640 
641  if (stream == NULL) {
642  Int3();
643  return 0;
644  }
645 
646  acm_stream_t *str = (acm_stream_t *)stream;
647  uint rc;
648  MMIOINFO IOrw;
649 
650  memset( &IOrw, 0, sizeof(MMIOINFO) );
651 
652  IOrw.pchBuffer = (char *)src;
653  IOrw.fccIOProc = FOURCC_MEM;
654  IOrw.cchBuffer = src_len;
655 
656  HMMIO rw = mmioOpen( NULL, &IOrw, MMIO_READ );
657 
658  // buffer to estimated size since we have to process the whole thing at once
659  str->fmt->buffer_size = max_dest_bytes;
660  str->fmt->bytes_remaining = src_len;
661  str->fmt->bytes_processed = 0;
662 
663  // convert to PCM
664  rc = read_sample_fmt_adpcm(dest, rw, str->fmt);
665 
666  // send back actual sizes
667  if (dest_len) {
668  *dest_len = rc;
669  }
670 
671  if (src_bytes_used) {
672  *src_bytes_used = str->fmt->bytes_processed;
673  }
674 
675  mmioClose( rw, 0 );
676 
677  return 0;
678 }
short iCoef2
Definition: mmreg.h:1436
uint bytes_processed
Definition: acm.cpp:44
#define FOURCC_MEM
Definition: config.h:249
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
ADPCMBLOCKHEADER * header
Definition: acm.cpp:41
GLuint GLuint stream
Definition: Glext.h:7079
uint samples_left_in_block
Definition: acm.cpp:47
FOURCC fccIOProc
Definition: config.h:230
Assert(pm!=NULL)
WORD nChannels
Definition: config.h:166
#define mprintf(args)
Definition: pstypes.h:238
DWORD nAvgBytesPerSec
Definition: config.h:168
WORD nBlockAlign
Definition: config.h:169
SDL_RWops * HMMIO
Definition: config.h:93
#define INTEL_SHORT(x)
Definition: pstypes.h:389
adpcm_fmt_t * fmt
Definition: acm.cpp:55
int ACM_query_source_size(void *stream, int dest_len)
Definition: acm.cpp:605
ADPCMCOEFSET aCoef[]
Definition: mmreg.h:1456
#define Int3()
Definition: pstypes.h:292
MMRESULT mmioClose(HMMIO hmmio, uint wFlags)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
int nibble_state
Definition: acm.cpp:48
#define CLAMP(x, min, max)
Definition: pstypes.h:488
LONG cchBuffer
Definition: config.h:234
struct acm_stream_t acm_stream_t
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define WAVE_FORMAT_ADPCM
Definition: acm.cpp:16
struct adpcmcoef_tag ADPCMCOEFSET
int ACM_query_dest_size(void *stream, int src_len)
Definition: acm.cpp:620
ubyte bPredictor
Definition: acm.cpp:26
unsigned int uint
Definition: pstypes.h:64
#define MMIO_READ
Definition: config.h:251
ADPCMWAVEFORMAT adpcm
Definition: acm.cpp:40
#define IF_ERR(a, b)
Definition: acm.cpp:62
int ACM_convert_ADPCM_to_PCM(WAVEFORMATEX *pwfxSrc, ubyte *src, int src_len, ubyte **dest, int max_dest_bytes, int *dest_len, unsigned int *src_bytes_used, int dest_bps)
Definition: acm.cpp:351
short iCoef1
Definition: mmreg.h:1435
int bytes_remaining
Definition: acm.cpp:43
struct ADPCM_FMT_T adpcm_fmt_t
WORD wSamplesPerBlock
Definition: mmreg.h:1454
#define SMALLEST_ADPCM_DELTA
Definition: acm.cpp:76
uint buffer_size
Definition: acm.cpp:45
WORD wFormatTag
Definition: config.h:165
int ACM_stream_close(void *stream)
Definition: acm.cpp:591
unsigned long DWORD
Definition: config.h:90
ADPCMCOEFSET * aCoef
Definition: acm.cpp:36
#define delta
Definition: fvi.cpp:418
struct tWAVEFORMATEX WAVEFORMATEX
uint sample_frame_size
Definition: acm.cpp:46
unsigned char ubyte
Definition: pstypes.h:62
WORD cbSize
Definition: config.h:171
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
#define vm_malloc(size)
Definition: pstypes.h:547
int ACM_stream_open(WAVEFORMATEX *pwfxSrc, WAVEFORMATEX *pwfxDest, void **stream, int dest_bps)
Definition: acm.cpp:499
ushort dest_bps
Definition: acm.cpp:56
DWORD nSamplesPerSec
Definition: config.h:167
ushort dest_bps
Definition: acm.cpp:51
#define FIXED_POINT_ADAPTION_BASE
Definition: acm.cpp:75
ubyte nibble
Definition: acm.cpp:49
struct adpcmblockheader_tag ADPCMBLOCKHEADER
unsigned short WORD
Definition: config.h:81
ushort src_bps
Definition: acm.cpp:57
struct adpcmwaveformat_tag ADPCMWAVEFORMAT
WORD wBitsPerSample
Definition: config.h:170
Definition: multi.h:385
#define IF_ERR2(a, b)
Definition: acm.cpp:63
unsigned short ushort
Definition: pstypes.h:63
#define FIXED_POINT_COEF_BASE
Definition: acm.cpp:74
GLenum src
Definition: Glext.h:5917
GLenum GLsizei GLenum GLenum const GLvoid * data
Definition: Gl.h:1509
long mmioRead(HMMIO hmmio, HPSTR pch, long cch)
WAVEFORMATEX wav
Definition: acm.cpp:33
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)
Definition: acm.cpp:635
HPSTR pchBuffer
Definition: config.h:235
HMMIO mmioOpen(LPSTR szFilename, LPMMIOINFO lpmmioinfo, DWORD dwOpenFlags)