comparison decoders/voc.c @ 385:9efb760c4a6b

FIXME removal and cleanups.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 05 Jul 2002 22:32:54 +0000
parents cbb15ecf423a
children fb519e6028e3
comparison
equal deleted inserted replaced
384:fd44db5a5c08 385:9efb760c4a6b
80 }; 80 };
81 81
82 82
83 /* Private data for VOC file */ 83 /* Private data for VOC file */
84 typedef struct vocstuff { 84 typedef struct vocstuff {
85 Uint32 rest; /* bytes remaining in current block */ 85 Uint32 rest; /* bytes remaining in current block */
86 Uint32 rate; /* rate code (byte) of this chunk */ 86 Uint32 rate; /* rate code (byte) of this chunk */
87 int silent; /* sound or silence? */ 87 int silent; /* sound or silence? */
88 Uint32 srate; /* rate code (byte) of silence */ 88 Uint32 srate; /* rate code (byte) of silence */
89 Uint32 blockseek; /* start of current output block */ 89 Uint32 blockseek; /* start of current output block */
90 Uint32 samples; /* number of samples output */ 90 Uint32 samples; /* number of samples output */
91 Uint32 size; /* word length of data */ 91 Uint32 size; /* word length of data */
92 Uint8 channels; /* number of sound channels */ 92 Uint8 channels; /* number of sound channels */
93 int extended; /* Has an extended block been read? */ 93 int extended; /* Has an extended block been read? */
94 Uint32 bufpos; /* byte position in internal->buffer. */ 94 Uint32 bufpos; /* byte position in internal->buffer. */
95 Uint32 start_pos; /* offset to seek to in stream when rewinding. */ 95 Uint32 start_pos; /* offset to seek to in stream when rewinding. */
96 int error; /* error condition (as opposed to EOF). */
96 } vs_t; 97 } vs_t;
98
97 99
98 /* Size field */ 100 /* Size field */
99 /* SJB: note that the 1st 3 are sometimes used as sizeof(type) */ 101 /* SJB: note that the 1st 3 are sometimes used as sizeof(type) */
100 #define ST_SIZE_BYTE 1 102 #define ST_SIZE_BYTE 1
101 #define ST_SIZE_8BIT 1 103 #define ST_SIZE_8BIT 1
138 { 140 {
139 /* it's a no-op. */ 141 /* it's a no-op. */
140 } /* VOC_quit */ 142 } /* VOC_quit */
141 143
142 144
145 static inline int voc_readbytes(SDL_RWops *src, vs_t *v, void *p, int size)
146 {
147 if (SDL_RWread(src, p, size, 1) != 1)
148 {
149 Sound_SetError("VOC: i/o error");
150 v->error = 1;
151 return 0;
152 } /* if */
153
154 return(1);
155 } /* voc_readbytes */
156
157
143 static inline int voc_check_header(SDL_RWops *src) 158 static inline int voc_check_header(SDL_RWops *src)
144 { 159 {
145 /* VOC magic header */ 160 /* VOC magic header */
146 Uint8 signature[20]; /* "Creative Voice File\032" */ 161 Uint8 signature[20]; /* "Creative Voice File\032" */
147 Uint16 datablockofs; 162 Uint16 datablockofs;
148 163 vs_t v; /* dummy struct for voc_readbytes */
149 if (SDL_RWread(src, signature, sizeof (signature), 1) != 1) 164
165 if (!voc_readbytes(src, &v, signature, sizeof (signature)))
150 return(0); 166 return(0);
151 167
152 if (memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0) { 168 if (memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0)
153 Sound_SetError("Unrecognized file type (not VOC)"); 169 {
170 Sound_SetError("VOC: Wrong signature; not a VOC file.");
154 return(0); 171 return(0);
155 } 172 } /* if */
156 173
157 /* get the offset where the first datablock is located */ 174 /* get the offset where the first datablock is located */
158 if (SDL_RWread(src, &datablockofs, sizeof (Uint16), 1) != 1) 175 if (!voc_readbytes(src, &v, &datablockofs, sizeof (Uint16)))
159 return(0); 176 return(0);
160 177
161 datablockofs = SDL_SwapLE16(datablockofs); 178 datablockofs = SDL_SwapLE16(datablockofs);
162 179
163 if (SDL_RWseek(src, datablockofs, SEEK_SET) != datablockofs) 180 if (SDL_RWseek(src, datablockofs, SEEK_SET) != datablockofs)
181 {
182 Sound_SetError("VOC: Failed to seek to data block.");
164 return(0); 183 return(0);
184 } /* if */
165 185
166 return(1); /* success! */ 186 return(1); /* success! */
167 } /* voc_check_header */ 187 } /* voc_check_header */
168 188
169 /* !!! FIXME : Add a flag to vs_t that distinguishes EOF and Error conditions. */
170 189
171 /* Read next block header, save info, leave position at start of data */ 190 /* Read next block header, save info, leave position at start of data */
172 static int voc_get_block(Sound_Sample *sample) 191 static int voc_get_block(Sound_Sample *sample)
173 { 192 {
174 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; 193 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
199 sblen = ( (bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16) ); 218 sblen = ( (bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16) );
200 219
201 switch(block) 220 switch(block)
202 { 221 {
203 case VOC_DATA: 222 case VOC_DATA:
204 if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1) 223 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
205 return 0; 224 return 0;
206 225
207 /* When DATA block preceeded by an EXTENDED */ 226 /* When DATA block preceeded by an EXTENDED */
208 /* block, the DATA blocks rate value is invalid */ 227 /* block, the DATA blocks rate value is invalid */
209 if (!v->extended) 228 if (!v->extended)
210 { 229 {
211 if (uc == 0) 230 if (uc == 0)
212 { 231 {
213 Sound_SetError("VOC Sample rate is zero?"); 232 Sound_SetError("VOC Sample rate is zero?");
214 return 0; 233 return 0;
215 } 234 } /* if */
216 235
217 if ((v->rate != -1) && (uc != v->rate)) 236 if ((v->rate != -1) && (uc != v->rate))
218 { 237 {
219 Sound_SetError("VOC sample rate codes differ"); 238 Sound_SetError("VOC sample rate codes differ");
220 return 0; 239 return 0;
221 } 240 } /* if */
222 241
223 v->rate = uc; 242 v->rate = uc;
224 sample->actual.rate = 1000000.0/(256 - v->rate); 243 sample->actual.rate = 1000000.0/(256 - v->rate);
225 v->channels = 1; 244 v->channels = 1;
226 } 245 } /* if */
227 246
228 if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1) 247 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
229 return 0; 248 return 0;
230 249
231 if (uc != 0) 250 if (uc != 0)
232 { 251 {
233 Sound_SetError("VOC decoder only interprets 8-bit data"); 252 Sound_SetError("VOC decoder only interprets 8-bit data");
234 return 0; 253 return 0;
235 } 254 } /* if */
236 255
237 v->extended = 0; 256 v->extended = 0;
238 v->rest = sblen - 2; 257 v->rest = sblen - 2;
239 v->size = ST_SIZE_BYTE; 258 v->size = ST_SIZE_BYTE;
240 return 1; 259 return 1;
241 260
242 case VOC_DATA_16: 261 case VOC_DATA_16:
243 if (SDL_RWread(src, &new_rate_long, sizeof (new_rate_long), 1) != 1) 262 if (!voc_readbytes(src, v, &new_rate_long, sizeof (Uint32)))
244 return 0; 263 return 0;
264
245 new_rate_long = SDL_SwapLE32(new_rate_long); 265 new_rate_long = SDL_SwapLE32(new_rate_long);
246 if (new_rate_long == 0) 266 if (new_rate_long == 0)
247 { 267 {
248 Sound_SetError("VOC Sample rate is zero?"); 268 Sound_SetError("VOC Sample rate is zero?");
249 return 0; 269 return 0;
250 } 270 } /* if */
251 if ((v->rate != -1) && (new_rate_long != v->rate)) 271 if ((v->rate != -1) && (new_rate_long != v->rate))
252 { 272 {
253 Sound_SetError("VOC sample rate codes differ"); 273 Sound_SetError("VOC sample rate codes differ");
254 return 0; 274 return 0;
255 } 275 } /* if */
256 v->rate = new_rate_long; 276 v->rate = new_rate_long;
257 sample->actual.rate = new_rate_long; 277 sample->actual.rate = new_rate_long;
258 278
259 if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1) 279 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
260 return 0; 280 return 0;
261 281
262 switch (uc) 282 switch (uc)
263 { 283 {
264 case 8: v->size = ST_SIZE_BYTE; break; 284 case 8: v->size = ST_SIZE_BYTE; break;
265 case 16: v->size = ST_SIZE_WORD; break; 285 case 16: v->size = ST_SIZE_WORD; break;
266 default: 286 default:
267 Sound_SetError("VOC with unknown data size"); 287 Sound_SetError("VOC with unknown data size");
268 return 0; 288 return 0;
269 } 289 } /* switch */
270 290
271 if (SDL_RWread(src, &v->channels, sizeof (Uint8), 1) != 1) 291 if (!voc_readbytes(src, v, &v->channels, sizeof (Uint8)))
272 return 0; 292 return 0;
273 293
274 if (SDL_RWread(src, trash, sizeof (Uint8), 6) != 6) 294 if (!voc_readbytes(src, v, trash, sizeof (Uint8) * 6))
275 return 0; 295 return 0;
276 296
277 v->rest = sblen - 12; 297 v->rest = sblen - 12;
278 return 1; 298 return 1;
279 299
280 case VOC_CONT: 300 case VOC_CONT:
281 v->rest = sblen; 301 v->rest = sblen;
282 return 1; 302 return 1;
283 303
284 case VOC_SILENCE: 304 case VOC_SILENCE:
285 if (SDL_RWread(src, &period, sizeof (period), 1) != 1) 305 if (!voc_readbytes(src, v, &period, sizeof (period)))
286 return 0; 306 return 0;
307
287 period = SDL_SwapLE16(period); 308 period = SDL_SwapLE16(period);
288 309
289 if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1) 310 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
290 return 0; 311 return 0;
312
291 if (uc == 0) 313 if (uc == 0)
292 { 314 {
293 Sound_SetError("VOC silence sample rate is zero"); 315 Sound_SetError("VOC silence sample rate is zero");
294 return 0; 316 return 0;
295 } 317 } /* if */
296 318
297 /* 319 /*
298 * Some silence-packed files have gratuitously 320 * Some silence-packed files have gratuitously
299 * different sample rate codes in silence. 321 * different sample rate codes in silence.
300 * Adjust period. 322 * Adjust period.
309 331
310 case VOC_LOOP: 332 case VOC_LOOP:
311 case VOC_LOOPEND: 333 case VOC_LOOPEND:
312 for(i = 0; i < sblen; i++) /* skip repeat loops. */ 334 for(i = 0; i < sblen; i++) /* skip repeat loops. */
313 { 335 {
314 if (SDL_RWread(src, trash, sizeof (Uint8), 1) != 1) 336 if (!voc_readbytes(src, v, trash, sizeof (Uint8)))
315 return 0; 337 return 0;
316 } 338 } /* for */
317 break; 339 break;
318 340
319 case VOC_EXTENDED: 341 case VOC_EXTENDED:
320 /* An Extended block is followed by a data block */ 342 /* An Extended block is followed by a data block */
321 /* Set this byte so we know to use the rate */ 343 /* Set this byte so we know to use the rate */
322 /* value from the extended block and not the */ 344 /* value from the extended block and not the */
323 /* data block. */ 345 /* data block. */
324 v->extended = 1; 346 v->extended = 1;
325 if (SDL_RWread(src, &new_rate_short, sizeof (new_rate_short), 1) != 1) 347 if (!voc_readbytes(src, v, &new_rate_short, sizeof (Uint16)))
326 return 0; 348 return 0;
349
327 new_rate_short = SDL_SwapLE16(new_rate_short); 350 new_rate_short = SDL_SwapLE16(new_rate_short);
328 if (new_rate_short == 0) 351 if (new_rate_short == 0)
329 { 352 {
330 Sound_SetError("VOC sample rate is zero"); 353 Sound_SetError("VOC sample rate is zero");
331 return 0; 354 return 0;
332 } 355 } /* if */
333 if ((v->rate != -1) && (new_rate_short != v->rate)) 356 if ((v->rate != -1) && (new_rate_short != v->rate))
334 { 357 {
335 Sound_SetError("VOC sample rate codes differ"); 358 Sound_SetError("VOC sample rate codes differ");
336 return 0; 359 return 0;
337 } 360 } /* if */
338 v->rate = new_rate_short; 361 v->rate = new_rate_short;
339 362
340 if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1) 363 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
341 return 0; 364 return 0;
342 365
343 if (uc != 0) 366 if (uc != 0)
344 { 367 {
345 Sound_SetError("VOC decoder only interprets 8-bit data"); 368 Sound_SetError("VOC decoder only interprets 8-bit data");
346 return 0; 369 return 0;
347 } 370 } /* if */
348 371
349 if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1) 372 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
350 return 0; 373 return 0;
351 374
352 if (uc) 375 if (uc)
353 sample->actual.channels = 2; /* Stereo */ 376 sample->actual.channels = 2; /* Stereo */
377
354 /* Needed number of channels before finishing 378 /* Needed number of channels before finishing
355 compute for rate */ 379 compute for rate */
356 sample->actual.rate = 380 sample->actual.rate =
357 (256000000L/(65536L - v->rate)) / sample->actual.channels; 381 (256000000L/(65536L - v->rate)) / sample->actual.channels;
358 /* An extended block must be followed by a data */ 382 /* An extended block must be followed by a data */
359 /* block to be valid so loop back to top so it */ 383 /* block to be valid so loop back to top so it */
360 /* can be grabed. */ 384 /* can be grabed. */
361 continue; 385 continue;
362 386
363 case VOC_MARKER: 387 case VOC_MARKER:
364 if (SDL_RWread(src, trash, sizeof (Uint8), 2) != 2) 388 if (!voc_readbytes(src, v, trash, sizeof (Uint8) * 2))
365 return 0; 389 return 0;
366 390
367 /* Falling! Falling! */ 391 /* Falling! Falling! */
368 392
369 default: /* text block or other krapola. */ 393 default: /* text block or other krapola. */
370 for(i = 0; i < sblen; i++) 394 if (!voc_readbytes(src, v, &trash, sizeof (Uint8) * sblen))
371 { 395 return 0;
372 if (SDL_RWread(src, &trash, sizeof (Uint8), 1) != 1)
373 return 0;
374 }
375 396
376 if (block == VOC_TEXT) 397 if (block == VOC_TEXT)
377 continue; /* get next block */ 398 continue; /* get next block */
378 } 399 } /* switch */
379 } 400 } /* while */
380 401
381 return 1; 402 return 1;
382 } /* voc_get_block */ 403 } /* voc_get_block */
383 404
384 405
416 } /* if */ 437 } /* if */
417 438
418 else 439 else
419 { 440 {
420 if (fill_buf) 441 if (fill_buf)
442 {
421 done = SDL_RWread(src, buf + v->bufpos, 1, max); 443 done = SDL_RWread(src, buf + v->bufpos, 1, max);
444 if (done < max)
445 {
446 Sound_SetError("VOC: i/o error");
447 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
448 } /* if */
449 } /* if */
450
422 else 451 else
423 { 452 {
424 int cur, rc; 453 int cur, rc;
425 cur = SDL_RWtell(src); 454 cur = SDL_RWtell(src);
426 if (cur >= 0) 455 if (cur >= 0)
427 { 456 {
428 rc = SDL_RWseek(src, max, SEEK_CUR); 457 rc = SDL_RWseek(src, max, SEEK_CUR);
429 if (rc >= 0) 458 if (rc >= 0)
430 done = rc - cur; 459 done = rc - cur;
460 else
461 {
462 Sound_SetError("VOC: seek error");
463 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
464 } /* else */
431 } /* if */ 465 } /* if */
432 } /* else */ 466 } /* else */
433 467
434 v->rest -= done; 468 v->rest -= done;
435 v->bufpos += done; 469 v->bufpos += done;
436 } /* else */ 470 } /* else */
437 471
438 return done; 472 return(done);
439 } /* voc_read_waveform */ 473 } /* voc_read_waveform */
440 474
441 475
442 static int VOC_open(Sound_Sample *sample, const char *ext) 476 static int VOC_open(Sound_Sample *sample, const char *ext)
443 { 477 {
489 523
490 v->bufpos = 0; 524 v->bufpos = 0;
491 while (v->bufpos < internal->buffer_size) 525 while (v->bufpos < internal->buffer_size)
492 { 526 {
493 Uint32 rc = voc_read_waveform(sample, 1, internal->buffer_size); 527 Uint32 rc = voc_read_waveform(sample, 1, internal->buffer_size);
494 if (rc == 0) /* !!! FIXME: Could be an error... */ 528 if (rc == 0)
495 { 529 {
496 sample->flags |= SOUND_SAMPLEFLAG_EOF; 530 sample->flags |= (v->error) ?
531 SOUND_SAMPLEFLAG_ERROR :
532 SOUND_SAMPLEFLAG_EOF;
497 break; 533 break;
498 } /* if */ 534 } /* if */
499 535
500 if (!voc_get_block(sample)) 536 if (!voc_get_block(sample))
501 { 537 {
502 sample->flags |= SOUND_SAMPLEFLAG_ERROR; 538 sample->flags |= (v->error) ?
539 SOUND_SAMPLEFLAG_ERROR :
540 SOUND_SAMPLEFLAG_EOF;
503 break; 541 break;
504 } /* if */ 542 } /* if */
505 } /* while */ 543 } /* while */
506 544
507 return(v->bufpos); 545 return(v->bufpos);