When I try to decode IMA ADPCM to 16-bit signed PCM I have half-garbaged PCM
I try to decode and encode IMA ADPCM in WAV file(22050 samples/s, 4 bit/sample, 36(!) byte(?) align(?!), 1 channel).
int16_t decodeImaAdpcmSampleUIS(struct AdpcmState* state, const uint8_t sample){
int diff;
int8_t si=state->stepindex;
int step=i_step_table[si];
int cur=state->current;
diff=step>>3;
if( sample&0x04 ) diff += step;
if( sample&0x02 ) diff += step>>1;
if( sample&0x01 ) diff += step>>2;
if( sample&0x08 ){
cur -= diff;
if(cur<-32768)
cur=-32768;
}else{
cur += diff;
if(cur>32767)
cur=32767;
}
//predictor: cur, state.current
//step_index: si, stepindex
si+=ima_index_table[sample&0b111];
if(si < 0)
si = 0;
if(si > 88)
si = 88;
state->stepindex=si;
return state->current=cur;
}
void decodeImaAdpcm(uint8_t* src, int16_t* dst, size_t srcLen){
struct AdpcmState state={0,0};
for(size_t i=0; i<srcLen; i++){
*(dst++)=decodeImaAdpcmSampleUIS(&state, (*src)&0xf);
*(dst++)=decodeImaAdpcmSampleUIS(&state, (*src)>>4);
src++;
}
}
Full project with WAV files: https://drive.google.com/open?id=1xuxwXj3Y_QhPDWhrQY7nmz8ycBE1cgyL
ADPCM WAV files converted to PCM WAV contains some garbage, but ffmpeg converts it normally. PCM WAV to ADPCM WAV conversion currently not implemented.
This happens because in WAV ADPCM is not stored as continuous stream of encoded sound. Instead it is stored as blocks, where each first 4 bytes of block are initial ADPCM decoder state.
For example: WAV.align=36;//Block size is 36 bytes, block structure is --|current(2 bytes)|step index(2 bytes)|data(WAV.align-4(36-4=32) bytes)|--