comparison vmdav.c @ 3191:7acb3ea20b4c libavcodec

16-bit DPCM and stereo support for Sierra VMD
author kostya
date Sat, 11 Mar 2006 04:26:55 +0000
parents 0b546eab515d
children 432ac9dce673
comparison
equal deleted inserted replaced
3190:e9fa3ac61966 3191:7acb3ea20b4c
412 typedef struct VmdAudioContext { 412 typedef struct VmdAudioContext {
413 AVCodecContext *avctx; 413 AVCodecContext *avctx;
414 int channels; 414 int channels;
415 int bits; 415 int bits;
416 int block_align; 416 int block_align;
417 unsigned char steps8[16]; 417 int predictors[2];
418 unsigned short steps16[16];
419 unsigned short steps128[256];
420 short predictors[2];
421 } VmdAudioContext; 418 } VmdAudioContext;
422 419
420 static uint16_t vmdaudio_table[128] = {
421 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
422 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
423 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
424 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
425 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
426 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
427 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
428 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
429 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
430 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
431 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
432 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
433 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
434 };
435
423 static int vmdaudio_decode_init(AVCodecContext *avctx) 436 static int vmdaudio_decode_init(AVCodecContext *avctx)
424 { 437 {
425 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data; 438 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
426 int i;
427 439
428 s->avctx = avctx; 440 s->avctx = avctx;
429 s->channels = avctx->channels; 441 s->channels = avctx->channels;
430 s->bits = avctx->bits_per_sample; 442 s->bits = avctx->bits_per_sample;
431 s->block_align = avctx->block_align; 443 s->block_align = avctx->block_align;
432 444
433 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", 445 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
434 s->channels, s->bits, s->block_align, avctx->sample_rate); 446 s->channels, s->bits, s->block_align, avctx->sample_rate);
435 447
436 /* set up the steps8 and steps16 tables */ 448 return 0;
437 for (i = 0; i < 8; i++) { 449 }
438 if (i < 4) 450
439 s->steps8[i] = i; 451 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
452 uint8_t *buf, int stereo)
453 {
454 int i;
455 int chan = 0;
456 int16_t *out = (int16_t*)data;
457
458 for(i = 0; i < s->block_align; i++) {
459 if(buf[i] & 0x80)
460 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
440 else 461 else
441 s->steps8[i] = s->steps8[i - 1] + i - 1; 462 s->predictors[chan] += vmdaudio_table[buf[i]];
442 463 s->predictors[chan] = clip(s->predictors[chan], -32768, 32767);
443 if (i == 0) 464 out[i] = s->predictors[chan];
444 s->steps16[i] = 0; 465 chan ^= stereo;
445 else if (i == 1) 466 }
446 s->steps16[i] = 4;
447 else if (i == 2)
448 s->steps16[i] = 16;
449 else
450 s->steps16[i] = 1 << (i + 4);
451 }
452
453 /* set up the step128 table */
454 s->steps128[0] = 0;
455 s->steps128[1] = 8;
456 for (i = 0x02; i <= 0x20; i++)
457 s->steps128[i] = (i - 1) << 4;
458 for (i = 0x21; i <= 0x60; i++)
459 s->steps128[i] = (i + 0x1F) << 3;
460 for (i = 0x61; i <= 0x70; i++)
461 s->steps128[i] = (i - 0x51) << 6;
462 for (i = 0x71; i <= 0x78; i++)
463 s->steps128[i] = (i - 0x69) << 8;
464 for (i = 0x79; i <= 0x7D; i++)
465 s->steps128[i] = (i - 0x75) << 10;
466 s->steps128[0x7E] = 0x3000;
467 s->steps128[0x7F] = 0x4000;
468
469 /* set up the negative half of each table */
470 for (i = 0; i < 8; i++) {
471 s->steps8[i + 8] = -s->steps8[i];
472 s->steps16[i + 8] = -s->steps16[i];
473 }
474 for (i = 0; i < 128; i++)
475 s->steps128[i + 128] = -s->steps128[i];
476
477 return 0;
478 }
479
480 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
481 uint8_t *buf, int ratio) {
482
483 } 467 }
484 468
485 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, 469 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
486 uint8_t *buf, int silence) 470 uint8_t *buf, int silence)
487 { 471 {
488 int bytes_decoded = 0; 472 int bytes_decoded = 0;
489 int i; 473 int i;
490 474
491 if (silence) 475 // if (silence)
492 av_log(s->avctx, AV_LOG_INFO, "silent block!\n"); 476 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
493 if (s->channels == 2) { 477 if (s->channels == 2) {
494 478
495 /* stereo handling */ 479 /* stereo handling */
496 if ((s->block_align & 0x01) == 0) { 480 if (silence) {
497 if (silence) 481 memset(data, 0, s->block_align * 2);
498 memset(data, 0, s->block_align * 2); 482 } else {
483 if (s->bits == 16)
484 vmdaudio_decode_audio(s, data, buf, 1);
499 else 485 else
500 vmdaudio_decode_audio(s, data, buf, 1); 486 /* copy the data but convert it to signed */
501 } else { 487 for (i = 0; i < s->block_align; i++)
502 if (silence) 488 data[i * 2 + 1] = buf[i] + 0x80;
503 memset(data, 0, s->block_align * 2);
504 else
505 vmdaudio_decode_audio(s, data, buf, 1);
506 } 489 }
507 } else { 490 } else {
491 bytes_decoded = s->block_align * 2;
508 492
509 /* mono handling */ 493 /* mono handling */
510 if (silence) { 494 if (silence) {
495 memset(data, 0, s->block_align * 2);
496 } else {
511 if (s->bits == 16) { 497 if (s->bits == 16) {
512 memset(data, 0, s->block_align * 2); 498 vmdaudio_decode_audio(s, data, buf, 0);
513 bytes_decoded = s->block_align * 2;
514 } else { 499 } else {
515 // memset(data, 0x00, s->block_align); 500 /* copy the data but convert it to signed */
516 // bytes_decoded = s->block_align; 501 for (i = 0; i < s->block_align; i++)
517 memset(data, 0x00, s->block_align * 2); 502 data[i * 2 + 1] = buf[i] + 0x80;
518 bytes_decoded = s->block_align * 2; 503 }
519 } 504 }
520 } else { 505 }
521 /* copy the data but convert it to signed */ 506
522 for (i = 0; i < s->block_align; i++) 507 return s->block_align * 2;
523 data[i * 2 + 1] = buf[i] + 0x80;
524 bytes_decoded = s->block_align * 2;
525 }
526 }
527
528 return bytes_decoded;
529 } 508 }
530 509
531 static int vmdaudio_decode_frame(AVCodecContext *avctx, 510 static int vmdaudio_decode_frame(AVCodecContext *avctx,
532 void *data, int *data_size, 511 void *data, int *data_size,
533 uint8_t *buf, int buf_size) 512 uint8_t *buf, int buf_size)