#include #include #include #include #include "adpcm_code.h" /* step table */ static const uint16_t step_table[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; /* step index tables */ static const int index_table[] = { /* adpcm data size is 4 */ -1, -1, -1, -1, 2, 4, 6, 8 }; static const int index_table_3bit[] = { /* adpcm data size is 3 */ -1, -1, 1, 2 }; static const int index_table_5bit[] = { /* adpcm data size is 5 */ -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }; //void adpcm_downsamlpe_2(int16_t *buf, uint32_t size) //{ // int temp = 0; // for(uint32_t i=0; i<(size/2); i++) { // buf[i] = buf[2*i]; // } //} //void adpcm_upsamlpe_2(int16_t *buf, uint32_t size) //{ // int temp = 0; // memcpy(buf+size,buf,size*2); // for(uint32_t i=0; ishaping_weight * pchan->error + 512) >> 10); if (pchan->shaping_weight < 0 && temp) { if (temp == pchan->error) temp = (temp < 0) ? temp + 1 : temp - 1; pchan->error = -sample; sample += temp; } else pchan->error = -(sample += temp); return sample; } static rms_error_t min_error_4bit (const struct adpcm_channel *pchan, int nch, int32_t csample, const int16_t *psample, int flags, int *best_nibble, rms_error_t max_error) { int32_t delta = csample - pchan->pcmdata, csample2; struct adpcm_channel chan = *pchan; uint16_t step = step_table[chan.index]; uint16_t trial_delta = (step >> 3); int nibble, testnbl; rms_error_t min_error; // this odd-looking code always generates the nibble value with the least error, // regardless of step size (which was not true previously) if (delta < 0) { int mag = ((-delta << 2) + (step & 3) + ((step & 1) << 1)) / step; nibble = 0x8 | (mag > 7 ? 7 : mag); } else { int mag = ((delta << 2) + (step & 3) + ((step & 1) << 1)) / step; nibble = mag > 7 ? 7 : mag; } if (nibble & 1) trial_delta += (step >> 2); if (nibble & 2) trial_delta += (step >> 1); if (nibble & 4) trial_delta += step; if (nibble & 8) chan.pcmdata -= trial_delta; else chan.pcmdata += trial_delta; CLIP(chan.pcmdata, -32768, 32767); if (best_nibble) *best_nibble = nibble; min_error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); // if we're at a leaf, or we're not at a leaf but have already exceeded the error limit, return if (!(flags & LOOKAHEAD_DEPTH) || min_error >= max_error) return min_error; // otherwise we execute that naively closest nibble and search deeper for improvement chan.index += index_table[nibble & 0x07]; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; min_error += min_error_4bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, max_error - min_error); // min_error is the error (from here to the leaf) for the naively closest nibble. // Unless we've been told not to try, we may be able to improve on that by choosing // an alternative (not closest) nibble. if (flags & LOOKAHEAD_NO_BRANCHING) return min_error; for (testnbl = 0; testnbl <= 0xF; ++testnbl) { rms_error_t error, threshold; if (testnbl == nibble) // don't do the same value again continue; // we execute this branch if: // 1. we're doing an exhaustive search, or // 2. the test value is one of the maximum values (i.e., 0x7 or 0xf), or // 3. the test value's delta is within three of the initial estimate's delta if (flags & LOOKAHEAD_EXHAUSTIVE || !(~testnbl & 0x7) || abs (NIBBLE_TO_DELTA (4,nibble) - NIBBLE_TO_DELTA (4,testnbl)) <= 3) { trial_delta = (step >> 3); chan = *pchan; if (testnbl & 1) trial_delta += (step >> 2); if (testnbl & 2) trial_delta += (step >> 1); if (testnbl & 4) trial_delta += step; if (testnbl & 8) chan.pcmdata -= trial_delta; else chan.pcmdata += trial_delta; CLIP(chan.pcmdata, -32768, 32767); error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); threshold = max_error < min_error ? max_error : min_error; if (error < threshold) { chan.index += index_table[testnbl & 0x07]; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; error += min_error_4bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, threshold - error); if (error < min_error) { if (best_nibble) *best_nibble = testnbl; min_error = error; } } } } return min_error; } static rms_error_t min_error_2bit (const struct adpcm_channel *pchan, int nch, int32_t csample, const int16_t *psample, int flags, int *best_nibble, rms_error_t max_error) { int32_t delta = csample - pchan->pcmdata, csample2; struct adpcm_channel chan = *pchan; uint16_t step = step_table[chan.index]; int nibble, testnbl; rms_error_t min_error; if (delta < 0) { if (-delta >= step) { chan.pcmdata -= step + (step >> 1); nibble = 3; } else { chan.pcmdata -= step >> 1; nibble = 2; } } else chan.pcmdata += step * ((nibble = delta >= step)) + (step >> 1); CLIP(chan.pcmdata, -32768, 32767); if (best_nibble) *best_nibble = nibble; min_error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); // if we're at a leaf, or we're not at a leaf but have already exceeded the error limit, return if (!(flags & LOOKAHEAD_DEPTH) || min_error >= max_error) return min_error; // otherwise we execute that naively closest nibble and search deeper for improvement chan.index += (nibble & 1) * 3 - 1; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; min_error += min_error_2bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, max_error - min_error); // min_error is the error (from here to the leaf) for the naively closest nibble. // Unless we've been told not to try, we may be able to improve on that by choosing // an alternative (not closest) nibble. if (flags & LOOKAHEAD_NO_BRANCHING) return min_error; for (testnbl = 0; testnbl <= 0x3; ++testnbl) { rms_error_t error, threshold; if (testnbl == nibble) // don't do the same value again continue; chan = *pchan; if (testnbl & 2) chan.pcmdata -= step * (testnbl & 1) + (step >> 1); else chan.pcmdata += step * (testnbl & 1) + (step >> 1); CLIP(chan.pcmdata, -32768, 32767); error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); threshold = max_error < min_error ? max_error : min_error; if (error < threshold) { chan.index += (testnbl & 1) * 3 - 1; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; error += min_error_2bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, threshold - error); if (error < min_error) { if (best_nibble) *best_nibble = testnbl; min_error = error; } } } return min_error; } static rms_error_t min_error_3bit (const struct adpcm_channel *pchan, int nch, int32_t csample, const int16_t *psample, int flags, int *best_nibble, rms_error_t max_error) { int32_t delta = csample - pchan->pcmdata, csample2; struct adpcm_channel chan = *pchan; uint16_t step = step_table[chan.index]; uint16_t trial_delta = (step >> 2); int nibble, testnbl; rms_error_t min_error; if (delta < 0) { int mag = ((-delta << 1) + (step & 1)) / step; nibble = 0x4 | (mag > 3 ? 3 : mag); } else { int mag = ((delta << 1) + (step & 1)) / step; nibble = mag > 3 ? 3 : mag; } if (nibble & 1) trial_delta += (step >> 1); if (nibble & 2) trial_delta += step; if (nibble & 4) chan.pcmdata -= trial_delta; else chan.pcmdata += trial_delta; CLIP(chan.pcmdata, -32768, 32767); if (best_nibble) *best_nibble = nibble; min_error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); // if we're at a leaf, or we're not at a leaf but have already exceeded the error limit, return if (!(flags & LOOKAHEAD_DEPTH) || min_error >= max_error) return min_error; // otherwise we execute that naively closest nibble and search deeper for improvement chan.index += index_table_3bit[nibble & 0x03]; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; min_error += min_error_3bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, max_error - min_error); // min_error is the error (from here to the leaf) for the naively closest nibble. // Unless we've been told not to try, we may be able to improve on that by choosing // an alternative (not closest) nibble. if (flags & LOOKAHEAD_NO_BRANCHING) return min_error; for (testnbl = 0; testnbl <= 0x7; ++testnbl) { rms_error_t error, threshold; if (testnbl == nibble) // don't do the same value again continue; // we execute this branch if: // 1. we're doing an exhaustive search, or // 2. the test value is one of the maximum values (i.e., 0x3 or 0x7), or // 3. the test value's delta is within two of the initial estimate's delta if (flags & LOOKAHEAD_EXHAUSTIVE || !(~testnbl & 0x3) || abs (NIBBLE_TO_DELTA (3,nibble) - NIBBLE_TO_DELTA (3,testnbl)) <= 2) { trial_delta = (step >> 2); chan = *pchan; if (testnbl & 1) trial_delta += (step >> 1); if (testnbl & 2) trial_delta += step; if (testnbl & 4) chan.pcmdata -= trial_delta; else chan.pcmdata += trial_delta; CLIP(chan.pcmdata, -32768, 32767); error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); threshold = max_error < min_error ? max_error : min_error; if (error < threshold) { chan.index += index_table_3bit[testnbl & 0x03]; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; error += min_error_3bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, threshold - error); if (error < min_error) { if (best_nibble) *best_nibble = testnbl; min_error = error; } } } } return min_error; } static rms_error_t min_error_5bit (const struct adpcm_channel *pchan, int nch, int32_t csample, const int16_t *psample, int flags, int *best_nibble, rms_error_t max_error) { static char comp_table [16] = { 0, 0, 0, 5, 0, 6, 4, 10, 0, 7, 6, 10, 4, 11, 11, 13 }; int32_t delta = csample - pchan->pcmdata, csample2; struct adpcm_channel chan = *pchan; uint16_t step = step_table[chan.index]; uint16_t trial_delta = (step >> 4); int nibble, testnbl; rms_error_t min_error; if (delta < 0) { int mag = ((-delta << 3) + comp_table [step & 0xf]) / step; nibble = 0x10 | (mag > 0xf ? 0xf : mag); } else { int mag = ((delta << 3) + comp_table [step & 0xf]) / step; nibble = mag > 0xf ? 0xf : mag; } if (nibble & 1) trial_delta += (step >> 3); if (nibble & 2) trial_delta += (step >> 2); if (nibble & 4) trial_delta += (step >> 1); if (nibble & 8) trial_delta += step; if (nibble & 0x10) chan.pcmdata -= trial_delta; else chan.pcmdata += trial_delta; CLIP(chan.pcmdata, -32768, 32767); if (best_nibble) *best_nibble = nibble; min_error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); // if we're at a leaf, or we're not at a leaf but have already exceeded the error limit, return if (!(flags & LOOKAHEAD_DEPTH) || min_error >= max_error) return min_error; // otherwise we execute that naively closest nibble and search deeper for improvement chan.index += index_table_5bit[nibble & 0x0f]; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; min_error += min_error_5bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, max_error - min_error); // min_error is the error (from here to the leaf) for the naively closest nibble. // Unless we've been told not to try, we may be able to improve on that by choosing // an alternative (not closest) nibble. if (flags & LOOKAHEAD_NO_BRANCHING) return min_error; for (testnbl = 0; testnbl <= 0x1F; ++testnbl) { rms_error_t error, threshold; if (testnbl == nibble) // don't do the same value again continue; // we execute this trial if: // 1. we're doing an exhaustive search, or // 2. the trial value is one of the four maximum values for the sign, or // 3. the test value's delta is within three of the initial estimate's delta if (flags & LOOKAHEAD_EXHAUSTIVE || (testnbl | 3) == (nibble | 0xf) || abs (NIBBLE_TO_DELTA (5,nibble) - NIBBLE_TO_DELTA (5,testnbl)) <= 3) { trial_delta = (step >> 4); chan = *pchan; if (testnbl & 1) trial_delta += (step >> 3); if (testnbl & 2) trial_delta += (step >> 2); if (testnbl & 4) trial_delta += (step >> 1); if (testnbl & 8) trial_delta += step; if (testnbl & 0x10) chan.pcmdata -= trial_delta; else chan.pcmdata += trial_delta; CLIP(chan.pcmdata, -32768, 32767); error = (rms_error_t) (chan.pcmdata - csample) * (chan.pcmdata - csample); threshold = max_error < min_error ? max_error : min_error; if (error < threshold) { chan.index += index_table_5bit [testnbl & 0x0f]; CLIP(chan.index, 0, 88); if (flags & NOISE_SHAPING_ENABLED) { chan.error += chan.pcmdata; csample2 = noise_shape (&chan, psample [nch]); } else csample2 = psample [nch]; error += min_error_5bit (&chan, nch, csample2, psample + nch, flags - 1, NULL, threshold - error); if (error < min_error) { if (best_nibble) *best_nibble = testnbl; min_error = error; } } } } return min_error; } static uint8_t encode_sample (struct adpcm_context *pcnxt, int ch, int bps, const int16_t *psample, int num_samples) { struct adpcm_channel *pchan = pcnxt->channels + ch; uint16_t step = step_table[pchan->index]; int flags = pcnxt->config_flags, nibble; int32_t csample = *psample; uint16_t trial_delta; if (flags & NOISE_SHAPING_ENABLED) csample = noise_shape (pchan, csample); if ((flags & LOOKAHEAD_DEPTH) > num_samples - 1) flags = (flags & ~LOOKAHEAD_DEPTH) + num_samples - 1; if (bps == 2) { min_error_2bit (pchan, pcnxt->num_channels, csample, psample, flags, &nibble, MAX_RMS_ERROR); if (nibble & 2) pchan->pcmdata -= step * (nibble & 1) + (step >> 1); else pchan->pcmdata += step * (nibble & 1) + (step >> 1); pchan->index += (nibble & 1) * 3 - 1; } else if (bps == 3) { min_error_3bit (pchan, pcnxt->num_channels, csample, psample, flags, &nibble, MAX_RMS_ERROR); trial_delta = (step >> 2); if (nibble & 1) trial_delta += (step >> 1); if (nibble & 2) trial_delta += step; if (nibble & 4) pchan->pcmdata -= trial_delta; else pchan->pcmdata += trial_delta; pchan->index += index_table_3bit[nibble & 0x03]; } else if (bps == 4) { min_error_4bit (pchan, pcnxt->num_channels, csample, psample, flags, &nibble, MAX_RMS_ERROR); trial_delta = (step >> 3); if (nibble & 1) trial_delta += (step >> 2); if (nibble & 2) trial_delta += (step >> 1); if (nibble & 4) trial_delta += step; if (nibble & 8) pchan->pcmdata -= trial_delta; else pchan->pcmdata += trial_delta; pchan->index += index_table[nibble & 0x07]; } else { // bps == 5 min_error_5bit (pchan, pcnxt->num_channels, csample, psample, flags, &nibble, MAX_RMS_ERROR); trial_delta = (step >> 4); if (nibble & 1) trial_delta += (step >> 3); if (nibble & 2) trial_delta += (step >> 2); if (nibble & 4) trial_delta += (step >> 1); if (nibble & 8) trial_delta += step; if (nibble & 0x10) pchan->pcmdata -= trial_delta; else pchan->pcmdata += trial_delta; pchan->index += index_table_5bit[nibble & 0x0f]; } CLIP(pchan->index, 0, 88); CLIP(pchan->pcmdata, -32768, 32767); if (flags & NOISE_SHAPING_ENABLED) pchan->error += pchan->pcmdata; return nibble; } static void encode_chunks (struct adpcm_context *pcnxt, uint8_t *outbuf, int *outbufsize, const int16_t *inbuf, int inbufcount, int bps) { const int16_t *pcmbuf; int ch; for (ch = 0; ch < pcnxt->num_channels; ++ch) { int shiftbits = 0, numbits = 0, i, j; if (pcnxt->config_flags & NOISE_SHAPING_STATIC) pcnxt->channels [ch].shaping_weight = pcnxt->static_shaping_weight; pcmbuf = inbuf + ch; for (j = i = 0; i < inbufcount; ++i) { if (pcnxt->config_flags & NOISE_SHAPING_DYNAMIC) pcnxt->channels [ch].shaping_weight = pcnxt->dynamic_shaping_array [i]; shiftbits |= encode_sample (pcnxt, ch, bps, pcmbuf, inbufcount - i) << numbits; pcmbuf += pcnxt->num_channels; if ((numbits += bps) >= 8) { outbuf [(j & ~3) * pcnxt->num_channels + (ch * 4) + (j & 3)] = shiftbits; shiftbits >>= 8; numbits -= 8; j++; } } if (numbits) outbuf [(j & ~3) * pcnxt->num_channels + (ch * 4) + (j & 3)] = shiftbits; } *outbufsize += (inbufcount * bps + 31) / 32 * pcnxt->num_channels * 4; } int adpcm_encode_block(struct adpcm_context *adpcm_cnxt, uint8_t *outbuf, int *outbufsize, const int16_t *inbuf, int inbufcount, int bps) { struct adpcm_context *pcnxt = (struct adpcm_context *) adpcm_cnxt; *outbufsize = 0; int ch = 0; if(bps < 2 || bps > 5) return 0; if(!inbufcount) return 0; for (ch = 0; ch < pcnxt->num_channels; ch++) pcnxt->channels[ch].pcmdata = *inbuf++; inbufcount--; if (inbufcount && (pcnxt->channels [0].index < 0 || (pcnxt->config_flags & LOOKAHEAD_DEPTH) >= 3)) { int flags = 16 | LOOKAHEAD_NO_BRANCHING; if ((flags & LOOKAHEAD_DEPTH) > inbufcount - 1) flags = (flags & ~LOOKAHEAD_DEPTH) + inbufcount - 1; for (ch = 0; ch < pcnxt->num_channels; ch++) { rms_error_t min_error = MAX_RMS_ERROR; rms_error_t error_per_index [89]; int best_index = 0, tindex; for (tindex = 0; tindex <= 88; tindex++) { struct adpcm_channel chan = pcnxt->channels [ch]; chan.index = tindex; chan.shaping_weight = 0; if (bps == 2) error_per_index [tindex] = min_error_2bit (&chan, pcnxt->num_channels, inbuf [ch], inbuf + ch, flags, NULL, MAX_RMS_ERROR); else if (bps == 3) error_per_index [tindex] = min_error_3bit (&chan, pcnxt->num_channels, inbuf [ch], inbuf + ch, flags, NULL, MAX_RMS_ERROR); else if (bps == 5) error_per_index [tindex] = min_error_5bit (&chan, pcnxt->num_channels, inbuf [ch], inbuf + ch, flags, NULL, MAX_RMS_ERROR); else error_per_index [tindex] = min_error_4bit (&chan, pcnxt->num_channels, inbuf [ch], inbuf + ch, flags, NULL, MAX_RMS_ERROR); } // we use a 3-wide average window because the min_error_nbit() results can be noisy for (tindex = 0; tindex <= 87; tindex++) { rms_error_t terror = error_per_index [tindex]; if (tindex) terror = (error_per_index [tindex - 1] + terror + error_per_index [tindex + 1]) / 3; if (terror < min_error) { best_index = tindex; min_error = terror; } } pcnxt->channels [ch].index = best_index; } } // write the block header, which includes the first PCM sample verbatim for (ch = 0; ch < pcnxt->num_channels; ch++) { outbuf[0] = pcnxt->channels[ch].pcmdata; outbuf[1] = pcnxt->channels[ch].pcmdata >> 8; outbuf[2] = pcnxt->channels[ch].index; outbuf[3] = 0; outbuf += 4; *outbufsize += 4; } void generate_dns_values (const int16_t *samples, int sample_count, int num_chans, int sample_rate, int16_t *values, int16_t min_value, int16_t last_value); if (inbufcount && (pcnxt->config_flags & NOISE_SHAPING_DYNAMIC)) { pcnxt->dynamic_shaping_array = malloc (inbufcount * sizeof (int16_t)); generate_dns_values (inbuf, inbufcount, pcnxt->num_channels, pcnxt->sample_rate, pcnxt->dynamic_shaping_array, -512, pcnxt->last_shaping_weight); pcnxt->last_shaping_weight = pcnxt->dynamic_shaping_array [inbufcount - 1]; } // encode the rest of the PCM samples, if any, into 32-bit, possibly interleaved, chunks if (inbufcount) encode_chunks(pcnxt, outbuf, outbufsize, inbuf, inbufcount, bps); if (pcnxt->dynamic_shaping_array && (pcnxt->config_flags & NOISE_SHAPING_DYNAMIC)) { free (pcnxt->dynamic_shaping_array); pcnxt->dynamic_shaping_array = NULL; } return 1; } int adpcm_encode(AdpcmEncoder *adpcm_enc, uint8_t *outbuf, int *outbufsize, int16_t *inbuf, int inbufcount, int bps) { static uint8_t rddancy_encode_flag = 0; if(adpcm_enc->rddancy_num>0) { TYPE_RINGBUF *ringbuf_original = adpcm_enc->ringbuf_original; TYPE_RINGBUF *ringbuf_encode = adpcm_enc->ringbuf_encode; int original_encode_len = (inbufcount*bps/8+4); int reddancy_encode_len = (inbufcount*4/8+4); int reddancy_total_len = 0; int rddancy_num = adpcm_enc->rddancy_num; uint8_t encode_buf[inbufcount*4/8+4]; int16_t original_buf[inbufcount]; push_ringbuf(ringbuf_original, (uint8_t*)inbuf, inbufcount*2); if(rddancy_encode_flag) { reddancy_encode_len = 0; if(adpcm_encode_block(adpcm_enc->rddancy_cnxt,encode_buf,&reddancy_encode_len,inbuf,inbufcount,4) != 1) return 0; if(reddancy_encode_len > 0) { push_ringbuf(ringbuf_encode,encode_buf,reddancy_encode_len); } } if(!rddancy_encode_flag) rddancy_encode_flag = 1; reddancy_total_len = reddancy_encode_len*rddancy_num; if(ringbuf_pop_available(ringbuf_original) >= (rddancy_num+1)*inbufcount*2) { pop_ringbuf(ringbuf_original,(uint8_t*)original_buf,inbufcount*2); original_encode_len = 0; if(adpcm_encode_block(adpcm_enc->normal_cnxt,outbuf+4,&original_encode_len,original_buf,inbufcount,bps) != 1) return 0; if(original_encode_len > 0) { pop_ringbuf(ringbuf_encode,outbuf+4+original_encode_len,reddancy_encode_len); if(rddancy_num>1) pop_ringbuf_notmove(ringbuf_encode,outbuf+4+original_encode_len+reddancy_encode_len, reddancy_total_len-reddancy_encode_len); } *outbufsize = original_encode_len+reddancy_total_len+4; *((uint32_t*)outbuf) = 0x80008000; *((uint16_t*)outbuf) |= original_encode_len; *((uint16_t*)outbuf+1) |= reddancy_encode_len; } else { *outbufsize = original_encode_len+reddancy_total_len+4; memset(outbuf,0,*outbufsize); *((uint16_t*)outbuf) |= original_encode_len; *((uint16_t*)outbuf+1) |= reddancy_encode_len; } } else { if(adpcm_encode_block(adpcm_enc->normal_cnxt,outbuf+4,outbufsize,inbuf,inbufcount,bps) != 1) return 0; *((uint32_t*)outbuf) = 0x8000; *((uint16_t*)outbuf) |= *outbufsize; *outbufsize += 4; } return 1; } int adpcm_decode_4bps (int16_t *outbuf, const uint8_t *inbuf, uint32_t inbufsize, int channels) { int ch, samples = 1, chunks; int32_t pcmdata[2]; int8_t index[2]; if (inbufsize < (uint32_t) channels * 4) return 0; for (ch = 0; ch < channels; ch++) { *outbuf++ = pcmdata[ch] = (int16_t) (inbuf [0] | (inbuf [1] << 8)); index[ch] = inbuf [2]; if (index [ch] < 0 || index [ch] > 88 || inbuf [3]) // sanitize the input a little... return 0; inbufsize -= 4; inbuf += 4; } chunks = inbufsize / (channels * 4); samples += chunks * 8; while (chunks--) { int ch, i; for (ch = 0; ch < channels; ++ch) { for (i = 0; i < 4; ++i) { uint16_t step = step_table [index [ch]], delta = step >> 3; if (*inbuf & 1) delta += (step >> 2); if (*inbuf & 2) delta += (step >> 1); if (*inbuf & 4) delta += step; if (*inbuf & 8) pcmdata[ch] -= delta; else pcmdata[ch] += delta; index[ch] += index_table [*inbuf & 0x7]; CLIP(index[ch], 0, 88); CLIP(pcmdata[ch], -32768, 32767); outbuf [i * 2 * channels] = pcmdata[ch]; step = step_table [index [ch]]; delta = step >> 3; if (*inbuf & 0x10) delta += (step >> 2); if (*inbuf & 0x20) delta += (step >> 1); if (*inbuf & 0x40) delta += step; if (*inbuf & 0x80) pcmdata[ch] -= delta; else pcmdata[ch] += delta; index[ch] += index_table [(*inbuf >> 4) & 0x7]; CLIP(index[ch], 0, 88); CLIP(pcmdata[ch], -32768, 32767); outbuf [(i * 2 + 1) * channels] = pcmdata[ch]; inbuf++; } outbuf++; } outbuf += channels * 7; } return samples; } int adpcm_decode_block(int16_t *outbuf, const uint8_t *inbuf, uint32_t inbufsize, int channels, int bps) { int samples = 1, ch; int32_t pcmdata[2]; int8_t index[2]; if (bps == 4) return adpcm_decode_4bps (outbuf, inbuf, inbufsize, channels); if (bps < 2 || bps > 5 || inbufsize < (uint32_t) channels * 4) return 0; for (ch = 0; ch < channels; ch++) { *outbuf++ = pcmdata[ch] = (int16_t) (inbuf [0] | (inbuf [1] << 8)); index[ch] = inbuf [2]; if (index [ch] < 0 || index [ch] > 88 || inbuf [3]) // sanitize the input a little... return 0; inbufsize -= 4; inbuf += 4; } if (!inbufsize || (inbufsize % (channels * 4))) // extra clean return samples; samples += inbufsize / channels * 8 / bps; switch (bps) { case 2: for (ch = 0; ch < channels; ++ch) { int shiftbits = 0, numbits = 0, i, j; for (j = i = 0; i < samples - 1; ++i) { uint16_t step = step_table [index [ch]]; if (numbits < bps) { shiftbits |= inbuf [(j & ~3) * channels + (ch * 4) + (j & 3)] << numbits; numbits += 8; j++; } if (shiftbits & 2) pcmdata[ch] -= step * (shiftbits & 1) + (step >> 1); else pcmdata[ch] += step * (shiftbits & 1) + (step >> 1); index[ch] += (shiftbits & 1) * 3 - 1; shiftbits >>= bps; numbits -= bps; CLIP(index[ch], 0, 88); CLIP(pcmdata[ch], -32768, 32767); outbuf [i * channels + ch] = pcmdata[ch]; } } break; case 3: for (ch = 0; ch < channels; ++ch) { int shiftbits = 0, numbits = 0, i, j; for (j = i = 0; i < samples - 1; ++i) { uint16_t step = step_table [index [ch]], delta = step >> 2; if (numbits < bps) { shiftbits |= inbuf [(j & ~3) * channels + (ch * 4) + (j & 3)] << numbits; numbits += 8; j++; } if (shiftbits & 1) delta += (step >> 1); if (shiftbits & 2) delta += step; if (shiftbits & 4) pcmdata[ch] -= delta; else pcmdata[ch] += delta; index[ch] += index_table_3bit [shiftbits & 0x3]; shiftbits >>= bps; numbits -= bps; CLIP(index[ch], 0, 88); CLIP(pcmdata[ch], -32768, 32767); outbuf [i * channels + ch] = pcmdata[ch]; } } break; case 5: for (ch = 0; ch < channels; ++ch) { int shiftbits = 0, numbits = 0, i, j; for (j = i = 0; i < samples - 1; ++i) { uint16_t step = step_table [index [ch]], delta = step >> 4; if (numbits < bps) { shiftbits |= inbuf [(j & ~3) * channels + (ch * 4) + (j & 3)] << numbits; numbits += 8; j++; } if (shiftbits & 1) delta += (step >> 3); if (shiftbits & 2) delta += (step >> 2); if (shiftbits & 4) delta += (step >> 1); if (shiftbits & 8) delta += step; if (shiftbits & 0x10) pcmdata[ch] -= delta; else pcmdata[ch] += delta; index[ch] += index_table_5bit [shiftbits & 0xf]; shiftbits >>= bps; numbits -= bps; CLIP(index[ch], 0, 88); CLIP(pcmdata[ch], -32768, 32767); outbuf [i * channels + ch] = pcmdata[ch]; } } break; default: return 0; } return samples; } int adpcm_decode(AdpcmDecoder *adpcm_dec, int16_t *outbuf, const uint8_t *inbuf, uint32_t inbufsize, int bps) { int samples = 0; int original_encode_len = 0; int reddancy_encode_len = 0; uint16_t inbuf_info[2]; memcpy(inbuf_info,inbuf,4); original_encode_len = inbuf_info[0] & 0x7FFF; reddancy_encode_len = inbuf_info[1] & 0x7FFF; if((adpcm_dec->rddancy_num > 0)&&(inbuf_info[1]&0x8000)) { adpcm_dec->rddancy_encode_len = reddancy_encode_len; adpcm_dec->rddancy_encbuf_pos = 0; adpcm_dec->rddancy_encbuf_num = (inbufsize-(4+original_encode_len))/reddancy_encode_len; memcpy(adpcm_dec->rddancy_encbuf,inbuf+4+original_encode_len,inbufsize-(4+original_encode_len)); } samples = adpcm_decode_block(adpcm_dec->decode_buf,inbuf+4,original_encode_len,1,bps); samples -= 1; adpcm_dec->plc_sta = 0; for(uint32_t i=0; ilowcfe, adpcm_dec->decode_buf+FRAMESZ*i); memcpy(outbuf,adpcm_dec->decode_buf,samples*2); return samples; } int adpcm_decode_plc(AdpcmDecoder *adpcm_dec, int16_t *outbuf) { int samples = 0; if(adpcm_dec->rddancy_encbuf_num) { adpcm_dec->rddancy_encbuf_num--; samples = adpcm_decode_block(adpcm_dec->decode_buf,adpcm_dec->rddancy_encbuf+adpcm_dec->rddancy_encbuf_pos, adpcm_dec->rddancy_encode_len,1,4); samples -= 1; adpcm_dec->plc_sta = 1; for(uint32_t i=0; ilowcfe, adpcm_dec->decode_buf+FRAMESZ*i); memcpy(outbuf,adpcm_dec->decode_buf,samples*2); adpcm_dec->rddancy_encbuf_pos += adpcm_dec->rddancy_encode_len; return samples; } else { adpcm_dec->plc_sta = 2; for(uint32_t i=0; iblock_size/FRAMESZ; i++) g711plc_dofe(adpcm_dec->lowcfe, adpcm_dec->decode_buf+FRAMESZ*i); memcpy(outbuf,adpcm_dec->decode_buf,adpcm_dec->block_size*2); return adpcm_dec->block_size; } } struct adpcm_context *adpcm_create_context (int num_channels, int sample_rate, int lookahead, int noise_shaping) { struct adpcm_context *pcnxt = (struct adpcm_context *)adpcm_malloc(sizeof (struct adpcm_context)); int ch; if(!pcnxt) return 0; memset (pcnxt, 0, sizeof (struct adpcm_context)); pcnxt->config_flags = noise_shaping | lookahead; pcnxt->static_shaping_weight = 1024; pcnxt->num_channels = num_channels; pcnxt->sample_rate = sample_rate; // we set the indicies to invalid values so that we always recalculate them // on at least the first frame (and every frame if the depth is sufficient) for (ch = 0; ch < num_channels; ++ch) pcnxt->channels [ch].index = -1; return pcnxt; } void adpcm_free_context(struct adpcm_context *p) { if(p) { adpcm_free(p); p = NULL; } } TYPE_RINGBUF *adpcm_create_ringbuf(int num_channels, int bufsize, int redundancy_num) { TYPE_RINGBUF *ringbuf = NULL; ringbuf = (TYPE_RINGBUF *)adpcm_malloc(sizeof(TYPE_RINGBUF)); if(ringbuf_Init(ringbuf,(bufsize*(redundancy_num+2)*num_channels)) == -1) return 0; ringbuf->data = (uint8_t*)adpcm_malloc(ringbuf->size); if(!ringbuf->data) { ringbuf_del(ringbuf); return 0; } return ringbuf; } void adpcm_free_ringbuf(TYPE_RINGBUF *p) { if(p) { if(p->data) { adpcm_free(p->data); p->data = NULL; } ringbuf_del(p); } } AdpcmEncoder *adpcm_encoder_create(int sample_rate, int lookahead, int noise_shaping, int block_size, int redundancy_num) { struct adpcm_context *adpcm_normal_cnxt = NULL; struct adpcm_context *adpcm_rddancy_cnxt = NULL; TYPE_RINGBUF *ringbuf_original = NULL; TYPE_RINGBUF *ringbuf_encode = NULL; AdpcmEncoder *adpcm_enc = NULL; adpcm_normal_cnxt = adpcm_create_context(1,sample_rate,lookahead,noise_shaping); if(!adpcm_normal_cnxt) goto adpcm_encoder_create_err; if(redundancy_num) { adpcm_rddancy_cnxt = adpcm_create_context(1,sample_rate,lookahead,noise_shaping); if(!adpcm_rddancy_cnxt) goto adpcm_encoder_create_err; ringbuf_original = adpcm_create_ringbuf(1,block_size*2,redundancy_num); if(!ringbuf_original) goto adpcm_encoder_create_err; ringbuf_encode = adpcm_create_ringbuf(1,block_size*4/8+4,redundancy_num); //bps2:block_size*2/8+4 if(!ringbuf_encode) goto adpcm_encoder_create_err; } adpcm_enc = (AdpcmEncoder *)adpcm_malloc(sizeof(AdpcmEncoder)); if(!adpcm_enc) goto adpcm_encoder_create_err; adpcm_enc->normal_cnxt = adpcm_normal_cnxt; adpcm_enc->rddancy_cnxt = adpcm_rddancy_cnxt; adpcm_enc->ringbuf_original = ringbuf_original; adpcm_enc->ringbuf_encode = ringbuf_encode; adpcm_enc->rddancy_num = redundancy_num; return adpcm_enc; adpcm_encoder_create_err: adpcm_free_context(adpcm_normal_cnxt); adpcm_free_context(adpcm_rddancy_cnxt); adpcm_free_ringbuf(ringbuf_original); adpcm_free_ringbuf(ringbuf_encode); return 0; } void adpcm_free_encoder(AdpcmEncoder *adpcm_enc) { if(adpcm_enc) { adpcm_free_context(adpcm_enc->normal_cnxt); adpcm_free_context(adpcm_enc->rddancy_cnxt); adpcm_free_ringbuf(adpcm_enc->ringbuf_original); adpcm_free_ringbuf(adpcm_enc->ringbuf_encode); adpcm_free(adpcm_enc); adpcm_enc = NULL; } } AdpcmDecoder *adpcm_decoder_create(int block_size, int redundancy_num) { uint8_t *rddancy_encbuf = NULL; AdpcmDecoder *adpcm_dec = NULL; LowcFE_c *lc = NULL; int16_t *decode_buf = NULL; if(redundancy_num) { rddancy_encbuf = (uint8_t*)adpcm_malloc(1*(block_size*4/8+4)*redundancy_num); if(!rddancy_encbuf) goto adpcm_decoder_create_err; } lc = (LowcFE_c *)adpcm_malloc(sizeof(LowcFE_c)); if(!lc) goto adpcm_decoder_create_err; adpcm_dec = (AdpcmDecoder *)adpcm_malloc(sizeof(AdpcmDecoder)); if(!adpcm_dec) goto adpcm_decoder_create_err; decode_buf = (int16_t *)adpcm_malloc(sizeof(short)*(block_size+1)); if(!decode_buf) goto adpcm_decoder_create_err; adpcm_dec->rddancy_encbuf = rddancy_encbuf; adpcm_dec->lowcfe = lc; adpcm_dec->rddancy_num = redundancy_num; adpcm_dec->rddancy_encbuf_num = 0; adpcm_dec->block_size = block_size; adpcm_dec->decode_buf = decode_buf; g711plc_construct(adpcm_dec->lowcfe); return adpcm_dec; adpcm_decoder_create_err: if(rddancy_encbuf) { adpcm_free(rddancy_encbuf); rddancy_encbuf = NULL; } if(lc) { adpcm_free(lc); lc = NULL; } if(decode_buf) { adpcm_free(decode_buf); decode_buf = NULL; } return 0; } void adpcm_free_decoder(AdpcmDecoder *adpcm_dec) { if(adpcm_dec) { if(adpcm_dec->rddancy_encbuf) { adpcm_free(adpcm_dec->rddancy_encbuf); adpcm_dec->rddancy_encbuf = NULL; } if(adpcm_dec->lowcfe) { adpcm_free(adpcm_dec->lowcfe); adpcm_dec->lowcfe = NULL; } if(adpcm_dec->decode_buf) { adpcm_free(adpcm_dec->decode_buf); adpcm_dec->decode_buf = NULL; } adpcm_free(adpcm_dec); adpcm_dec = NULL; } }