+static inline int16_t adpcm_ima_alp_expand_nibble(ADPCMChannelStatus *c, int8_t nibble, int shift)
+{
+ int step_index;
+ int predictor;
+ int sign, delta, diff, step;
+
+ step = ff_adpcm_step_table[c->step_index];
+ step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble];
+ step_index = av_clip(step_index, 0, 88);
+
+ sign = nibble & 8;
+ delta = nibble & 7;
+ diff = (delta * step) >> shift;
+ predictor = c->predictor;
+ if (sign) predictor -= diff;
+ else predictor += diff;
+
+ c->predictor = av_clip_int16(predictor);
+ c->step_index = step_index;
+
+ return (int16_t)c->predictor;
+}
+
+static inline int16_t adpcm_ima_mtf_expand_nibble(ADPCMChannelStatus *c, int nibble)
+{
+ int step_index, step, delta, predictor;
+
+ step = ff_adpcm_step_table[c->step_index];
+
+ delta = step * (2 * nibble - 15);
+ predictor = c->predictor + delta;
+
+ step_index = c->step_index + mtf_index_table[(unsigned)nibble];
+ c->predictor = av_clip_int16(predictor >> 4);
+ c->step_index = av_clip(step_index, 0, 88);
+
+ return (int16_t)c->predictor;
+}
+
+static inline int16_t adpcm_ima_cunning_expand_nibble(ADPCMChannelStatus *c, int8_t nibble)
+{
+ int step_index;
+ int predictor;
+ int step;
+
+ nibble = sign_extend(nibble & 0xF, 4);
+
+ step = ff_adpcm_ima_cunning_step_table[c->step_index];
+ step_index = c->step_index + ff_adpcm_ima_cunning_index_table[abs(nibble)];
+ step_index = av_clip(step_index, 0, 60);
+
+ predictor = c->predictor + step * nibble;
+
+ c->predictor = av_clip_int16(predictor);
+ c->step_index = step_index;
+
+ return c->predictor;
+}
+