*/
#include "avcodec.h"
#include "bitstream.h"
+#include "bytestream.h"
/**
* @file adpcm.c
* by Mike Melanson (melanson@pcisys.net)
* CD-ROM XA ADPCM codec by BERO
* EA ADPCM decoder by Robin Kay (komadori@myrealbox.com)
+ * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl)
*
* Features and limitations:
*
#define BLKSIZE 1024
-#define CLAMP_TO_SHORT(value) \
-if (value > 32767) \
- value = 32767; \
-else if (value < -32768) \
- value = -32768; \
-
/* step_table[] and index_table[] are from the ADPCM reference source */
/* This is the index table: */
static const int index_table[16] = {
int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */
ADPCMChannelStatus status[2];
short sample_buffer[32]; /* hold left samples while waiting for right samples */
-
- /* SWF only */
- int nb_bits;
- int nb_samples;
} ADPCMContext;
/* XXX: implement encoding */
avctx->frame_size = BLKSIZE * avctx->channels;
avctx->block_align = BLKSIZE;
break;
+ case CODEC_ID_ADPCM_SWF:
+ if (avctx->sample_rate != 11025 &&
+ avctx->sample_rate != 22050 &&
+ avctx->sample_rate != 44100) {
+ av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, 22050 or 44100\n");
+ return -1;
+ }
+ avctx->frame_size = 512 * (avctx->sample_rate / 11025);
+ break;
default:
return -1;
break;
{
int delta = sample - c->prev_sample;
int nibble = FFMIN(7, abs(delta)*4/step_table[c->step_index]) + (delta<0)*8;
- c->prev_sample = c->prev_sample + ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8);
- CLAMP_TO_SHORT(c->prev_sample);
- c->step_index = clip(c->step_index + index_table[nibble], 0, 88);
+ c->prev_sample += ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8);
+ c->prev_sample = av_clip_int16(c->prev_sample);
+ c->step_index = av_clip(c->step_index + index_table[nibble], 0, 88);
return nibble;
}
else bias=-c->idelta/2;
nibble= (nibble + bias) / c->idelta;
- nibble= clip(nibble, -8, 7)&0x0F;
+ nibble= av_clip(nibble, -8, 7)&0x0F;
predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta;
- CLAMP_TO_SHORT(predictor);
c->sample2 = c->sample1;
- c->sample1 = predictor;
+ c->sample1 = av_clip_int16(predictor);
c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8;
if (c->idelta < 16) c->idelta = 16;
nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8;
- c->predictor = c->predictor + ((c->step * yamaha_difflookup[nibble]) / 8);
- CLAMP_TO_SHORT(c->predictor);
+ c->predictor += ((c->step * yamaha_difflookup[nibble]) / 8);
+ c->predictor = av_clip_int16(c->predictor);
c->step = (c->step * yamaha_indexscale[nibble]) >> 8;
- c->step = clip(c->step, 127, 24567);
+ c->step = av_clip(c->step, 127, 24567);
return nibble;
}
nodes[0]->step = c->step_index;
nodes[0]->sample1 = c->sample1;
nodes[0]->sample2 = c->sample2;
- if(version == CODEC_ID_ADPCM_IMA_WAV)
+ if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_SWF))
nodes[0]->sample1 = c->prev_sample;
if(version == CODEC_ID_ADPCM_MS)
nodes[0]->step = c->idelta;
if(version == CODEC_ID_ADPCM_MS) {
const int predictor = ((nodes[j]->sample1 * c->coeff1) + (nodes[j]->sample2 * c->coeff2)) / 256;
const int div = (sample - predictor) / step;
- const int nmin = clip(div-range, -8, 6);
- const int nmax = clip(div+range, -7, 7);
+ const int nmin = av_clip(div-range, -8, 6);
+ const int nmax = av_clip(div+range, -7, 7);
for(nidx=nmin; nidx<=nmax; nidx++) {
const int nibble = nidx & 0xf;
int dec_sample = predictor + nidx * step;
#define STORE_NODE(NAME, STEP_INDEX)\
int d;\
uint32_t ssd;\
- CLAMP_TO_SHORT(dec_sample);\
+ dec_sample = av_clip_int16(dec_sample);\
d = sample - dec_sample;\
ssd = nodes[j]->ssd + d*d;\
if(nodes_next[frontier-1] && ssd >= nodes_next[frontier-1]->ssd)\
next_##NAME:;
STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8));
}
- } else if(version == CODEC_ID_ADPCM_IMA_WAV) {
+ } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_SWF)) {
#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\
const int predictor = nodes[j]->sample1;\
const int div = (sample - predictor) * 4 / STEP_TABLE;\
- int nmin = clip(div-range, -7, 6);\
- int nmax = clip(div+range, -6, 7);\
+ int nmin = av_clip(div-range, -7, 6);\
+ int nmax = av_clip(div+range, -6, 7);\
if(nmin<=0) nmin--; /* distinguish -0 from +0 */\
if(nmax<0) nmax--;\
for(nidx=nmin; nidx<=nmax; nidx++) {\
int dec_sample = predictor + (STEP_TABLE * yamaha_difflookup[nibble]) / 8;\
STORE_NODE(NAME, STEP_INDEX);\
}
- LOOP_NODES(ima, step_table[step], clip(step + index_table[nibble], 0, 88));
+ LOOP_NODES(ima, step_table[step], av_clip(step + index_table[nibble], 0, 88));
} else { //CODEC_ID_ADPCM_YAMAHA
- LOOP_NODES(yamaha, step, clip((step * yamaha_indexscale[nibble]) >> 8, 127, 24567));
+ LOOP_NODES(yamaha, step, av_clip((step * yamaha_indexscale[nibble]) >> 8, 127, 24567));
#undef LOOP_NODES
#undef STORE_NODE
}
n = avctx->frame_size / 8;
c->status[0].prev_sample = (signed short)samples[0]; /* XXX */
/* c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */
- *dst++ = (c->status[0].prev_sample) & 0xFF; /* little endian */
- *dst++ = (c->status[0].prev_sample >> 8) & 0xFF;
+ bytestream_put_le16(&dst, c->status[0].prev_sample);
*dst++ = (unsigned char)c->status[0].step_index;
*dst++ = 0; /* unknown */
samples++;
if (avctx->channels == 2) {
c->status[1].prev_sample = (signed short)samples[1];
/* c->status[1].step_index = 0; */
- *dst++ = (c->status[1].prev_sample) & 0xFF;
- *dst++ = (c->status[1].prev_sample >> 8) & 0xFF;
+ bytestream_put_le16(&dst, c->status[1].prev_sample);
*dst++ = (unsigned char)c->status[1].step_index;
*dst++ = 0;
samples++;
samples += 8 * avctx->channels;
}
break;
+ case CODEC_ID_ADPCM_SWF:
+ {
+ int i;
+ PutBitContext pb;
+ init_put_bits(&pb, dst, buf_size*8);
+
+ n = avctx->frame_size-1;
+
+ //Store AdpcmCodeSize
+ put_bits(&pb, 2, 2); //Set 4bits flash adpcm format
+
+ //Init the encoder state
+ for(i=0; i<avctx->channels; i++){
+ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits
+ put_bits(&pb, 16, samples[i] & 0xFFFF);
+ put_bits(&pb, 6, c->status[i].step_index);
+ c->status[i].prev_sample = (signed short)samples[i];
+ }
+
+ if(avctx->trellis > 0) {
+ uint8_t buf[2][n];
+ adpcm_compress_trellis(avctx, samples+2, buf[0], &c->status[0], n);
+ if (avctx->channels == 2)
+ adpcm_compress_trellis(avctx, samples+3, buf[1], &c->status[1], n);
+ for(i=0; i<n; i++) {
+ put_bits(&pb, 4, buf[0][i]);
+ if (avctx->channels == 2)
+ put_bits(&pb, 4, buf[1][i]);
+ }
+ } else {
+ for (i=1; i<avctx->frame_size; i++) {
+ put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i]) & 0xF);
+ if (avctx->channels == 2)
+ put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1]) & 0xF);
+ }
+ }
+ flush_put_bits(&pb);
+ dst += put_bits_count(&pb)>>3;
+ break;
+ }
case CODEC_ID_ADPCM_MS:
for(i=0; i<avctx->channels; i++){
int predictor=0;
if (c->status[i].idelta < 16)
c->status[i].idelta = 16;
- *dst++ = c->status[i].idelta & 0xFF;
- *dst++ = c->status[i].idelta >> 8;
+ bytestream_put_le16(&dst, c->status[i].idelta);
}
for(i=0; i<avctx->channels; i++){
c->status[i].sample1= *samples++;
- *dst++ = c->status[i].sample1 & 0xFF;
- *dst++ = c->status[i].sample1 >> 8;
+ bytestream_put_le16(&dst, c->status[i].sample1);
}
for(i=0; i<avctx->channels; i++){
c->status[i].sample2= *samples++;
- *dst++ = c->status[i].sample2 & 0xFF;
- *dst++ = c->status[i].sample2 >> 8;
+ bytestream_put_le16(&dst, c->status[i].sample2);
}
if(avctx->trellis > 0) {
case CODEC_ID_ADPCM_CT:
c->status[0].step = c->status[1].step = 511;
break;
+ case CODEC_ID_ADPCM_IMA_WS:
+ if (avctx->extradata && avctx->extradata_size == 2 * 4) {
+ c->status[0].predictor = AV_RL32(avctx->extradata);
+ c->status[1].predictor = AV_RL32(avctx->extradata + 4);
+ }
+ break;
default:
break;
}
if (sign) predictor -= diff;
else predictor += diff;
- CLAMP_TO_SHORT(predictor);
- c->predictor = predictor;
+ c->predictor = av_clip_int16(predictor);
c->step_index = step_index;
- return (short)predictor;
+ return (short)c->predictor;
}
static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble)
predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256;
predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta;
- CLAMP_TO_SHORT(predictor);
c->sample2 = c->sample1;
- c->sample1 = predictor;
+ c->sample1 = av_clip_int16(predictor);
c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8;
if (c->idelta < 16) c->idelta = 16;
- return (short)predictor;
+ return c->sample1;
}
static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble)
{
- int predictor;
int sign, delta, diff;
int new_step;
* the reference ADPCM implementation since modern CPUs can do the mults
* quickly enough */
diff = ((2 * delta + 1) * c->step) >> 3;
- predictor = c->predictor;
/* predictor update is not so trivial: predictor is multiplied on 254/256 before updating */
- if(sign)
- predictor = ((predictor * 254) >> 8) - diff;
- else
- predictor = ((predictor * 254) >> 8) + diff;
+ c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff);
+ c->predictor = av_clip_int16(c->predictor);
/* calculate new step and clamp it to range 511..32767 */
new_step = (ct_adpcm_table[nibble & 7] * c->step) >> 8;
- c->step = new_step;
- if(c->step < 511)
- c->step = 511;
- if(c->step > 32767)
- c->step = 32767;
-
- CLAMP_TO_SHORT(predictor);
- c->predictor = predictor;
- return (short)predictor;
+ c->step = av_clip(new_step, 511, 32767);
+
+ return (short)c->predictor;
}
static inline short adpcm_sbpro_expand_nibble(ADPCMChannelStatus *c, char nibble, int size, int shift)
delta = nibble & ((1<<(size-1))-1);
diff = delta << (7 + c->step + shift);
- if (sign)
- c->predictor -= diff;
- else
- c->predictor += diff;
-
/* clamp result */
- if (c->predictor > 16256)
- c->predictor = 16256;
- else if (c->predictor < -16384)
- c->predictor = -16384;
+ c->predictor = av_clip(c->predictor + (sign ? -diff : diff), -16384,16256);
/* calculate new step */
if (delta >= (2*size - 3) && c->step < 3)
}
c->predictor += (c->step * yamaha_difflookup[nibble]) / 8;
- CLAMP_TO_SHORT(c->predictor);
+ c->predictor = av_clip_int16(c->predictor);
c->step = (c->step * yamaha_indexscale[nibble]) >> 8;
- c->step = clip(c->step, 127, 24567);
+ c->step = av_clip(c->step, 127, 24567);
return c->predictor;
}
t = (signed char)(d<<4)>>4;
s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6);
- CLAMP_TO_SHORT(s);
- *out = s;
- out += inc;
s_2 = s_1;
- s_1 = s;
+ s_1 = av_clip_int16(s);
+ *out = s_1;
+ out += inc;
}
if (inc==2) { /* stereo */
t = (signed char)d >> 4;
s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6);
- CLAMP_TO_SHORT(s);
- *out = s;
- out += inc;
s_2 = s_1;
- s_1 = s;
+ s_1 = av_clip_int16(s);
+ *out = s_1;
+ out += inc;
}
if (inc==2) { /* stereo */
if(cs->predictor & 0x8000)
cs->predictor -= 0x10000;
- CLAMP_TO_SHORT(cs->predictor);
+ cs->predictor = av_clip_int16(cs->predictor);
cs->step_index = (*src++) & 0x7F;
n = buf_size - 7 * avctx->channels;
if (n < 0)
return -1;
- block_predictor[0] = clip(*src++, 0, 7);
+ block_predictor[0] = av_clip(*src++, 0, 7);
block_predictor[1] = 0;
if (st)
- block_predictor[1] = clip(*src++, 0, 7);
+ block_predictor[1] = av_clip(*src++, 0, 7);
c->status[0].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
src+=2;
if (st){
next_right_sample = (next_right_sample +
(current_right_sample * coeff1r) +
(previous_right_sample * coeff2r) + 0x80) >> 8;
- CLAMP_TO_SHORT(next_left_sample);
- CLAMP_TO_SHORT(next_right_sample);
previous_left_sample = current_left_sample;
- current_left_sample = next_left_sample;
+ current_left_sample = av_clip_int16(next_left_sample);
previous_right_sample = current_right_sample;
- current_right_sample = next_right_sample;
+ current_right_sample = av_clip_int16(next_right_sample);
*samples++ = (unsigned short)current_left_sample;
*samples++ = (unsigned short)current_right_sample;
}
{
GetBitContext gb;
const int *table;
- int k0, signmask;
+ int k0, signmask, nb_bits, count;
int size = buf_size*8;
init_get_bits(&gb, buf, size);
-//FIXME the following return -1 may be removed only after
-//1. correctly spliting the stream into packets at demuxer or parser level
-//2. checking array bounds when writing
-//3. moving the global nb_bits header into extradata
-return -1;
- // first frame, read bits & inital values
- if (!c->nb_bits)
- {
- c->nb_bits = get_bits(&gb, 2)+2;
-// av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", c->nb_bits);
- }
-
- table = swf_index_tables[c->nb_bits-2];
- k0 = 1 << (c->nb_bits-2);
- signmask = 1 << (c->nb_bits-1);
-
- while (get_bits_count(&gb) <= size)
- {
- int i;
-
- c->nb_samples++;
- // wrap around at every 4096 samples...
- if ((c->nb_samples & 0xfff) == 1)
- {
- for (i = 0; i <= st; i++)
- {
- *samples++ = c->status[i].predictor = get_sbits(&gb, 16);
- c->status[i].step_index = get_bits(&gb, 6);
- }
+ //read bits & initial values
+ nb_bits = get_bits(&gb, 2)+2;
+ //av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", nb_bits);
+ table = swf_index_tables[nb_bits-2];
+ k0 = 1 << (nb_bits-2);
+ signmask = 1 << (nb_bits-1);
+
+ while (get_bits_count(&gb) <= size - 22*avctx->channels) {
+ for (i = 0; i < avctx->channels; i++) {
+ *samples++ = c->status[i].predictor = get_sbits(&gb, 16);
+ c->status[i].step_index = get_bits(&gb, 6);
}
- // similar to IMA adpcm
- for (i = 0; i <= st; i++)
- {
- int delta = get_bits(&gb, c->nb_bits);
- int step = step_table[c->status[i].step_index];
- long vpdiff = 0; // vpdiff = (delta+0.5)*step/4
- int k = k0;
-
- do {
- if (delta & k)
- vpdiff += step;
- step >>= 1;
- k >>= 1;
- } while(k);
- vpdiff += step;
-
- if (delta & signmask)
- c->status[i].predictor -= vpdiff;
- else
- c->status[i].predictor += vpdiff;
-
- c->status[i].step_index += table[delta & (~signmask)];
-
- c->status[i].step_index = clip(c->status[i].step_index, 0, 88);
- c->status[i].predictor = clip(c->status[i].predictor, -32768, 32767);
-
- *samples++ = c->status[i].predictor;
+ for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) {
+ int i;
+
+ for (i = 0; i < avctx->channels; i++) {
+ // similar to IMA adpcm
+ int delta = get_bits(&gb, nb_bits);
+ int step = step_table[c->status[i].step_index];
+ long vpdiff = 0; // vpdiff = (delta+0.5)*step/4
+ int k = k0;
+
+ do {
+ if (delta & k)
+ vpdiff += step;
+ step >>= 1;
+ k >>= 1;
+ } while(k);
+ vpdiff += step;
+
+ if (delta & signmask)
+ c->status[i].predictor -= vpdiff;
+ else
+ c->status[i].predictor += vpdiff;
+
+ c->status[i].step_index += table[delta & (~signmask)];
+
+ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88);
+ c->status[i].predictor = av_clip_int16(c->status[i].predictor);
+
+ *samples++ = c->status[i].predictor;
+ if (samples >= samples_end) {
+ av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");
+ return -1;
+ }
+ }
}
}
-
-// src += get_bits_count(&gb)*8;
- src += size;
-
+ src += buf_size;
break;
}
case CODEC_ID_ADPCM_YAMAHA:
src++;
}
break;
+ case CODEC_ID_ADPCM_THP:
+ {
+ int table[2][16];
+ unsigned int samplecnt;
+ int prev[2][2];
+ int ch;
+
+ if (buf_size < 80) {
+ av_log(avctx, AV_LOG_ERROR, "frame too small\n");
+ return -1;
+ }
+
+ src+=4;
+ samplecnt = bytestream_get_be32(&src);
+
+ for (i = 0; i < 32; i++)
+ table[0][i] = (int16_t)bytestream_get_be16(&src);
+
+ /* Initialize the previous sample. */
+ for (i = 0; i < 4; i++)
+ prev[0][i] = (int16_t)bytestream_get_be16(&src);
+
+ if (samplecnt >= (samples_end - samples) / (st + 1)) {
+ av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");
+ return -1;
+ }
+
+ for (ch = 0; ch <= st; ch++) {
+ samples = (unsigned short *) data + ch;
+
+ /* Read in every sample for this channel. */
+ for (i = 0; i < samplecnt / 14; i++) {
+ int index = (*src >> 4) & 7;
+ unsigned int exp = 28 - (*src++ & 15);
+ int factor1 = table[ch][index * 2];
+ int factor2 = table[ch][index * 2 + 1];
+
+ /* Decode 14 samples. */
+ for (n = 0; n < 14; n++) {
+ int32_t sampledat;
+ if(n&1) sampledat= *src++ <<28;
+ else sampledat= (*src&0xF0)<<24;
+
+ sampledat = ((prev[ch][0]*factor1
+ + prev[ch][1]*factor2) >> 11) + (sampledat>>exp);
+ *samples = av_clip_int16(sampledat);
+ prev[ch][1] = prev[ch][0];
+ prev[ch][0] = *samples++;
+
+ /* In case of stereo, skip one sample, this sample
+ is for the other channel. */
+ samples += st;
+ }
+ }
+ }
+
+ /* In the previous loop, in case stereo is used, samples is
+ increased exactly one time too often. */
+ samples -= st;
+ break;
+ }
+
default:
return -1;
}
ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4);
ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3);
ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2);
+ADPCM_CODEC(CODEC_ID_ADPCM_THP, adpcm_thp);
#undef ADPCM_CODEC