diff --git a/freeaptx.c b/freeaptx.c index 46be682..0c24b94 100644 --- a/freeaptx.c +++ b/freeaptx.c @@ -124,15 +124,10 @@ struct aptx_channel { }; struct aptx_context { - size_t decode_sync_packets; - size_t decode_dropped; struct aptx_channel channels[NB_CHANNELS]; uint8_t hd; uint8_t sync_idx; uint8_t encode_remaining; - uint8_t decode_skip_leading; - uint8_t decode_sync_buffer_len; - unsigned char decode_sync_buffer[6]; }; @@ -704,35 +699,6 @@ static inline void aptx_qmf_polyphase_synthesis(struct aptx_filter_signal signal } } -/* - * Two stage QMF synthesis tree. - * Join 4 subbands and upsample by 4. - * So for each 4 subbands sample that goes in, a group of 4 samples goes out. - */ -static void aptx_qmf_tree_synthesis(struct aptx_QMF_analysis *qmf, - const int32_t subband_samples[NB_SUBBANDS], - int32_t samples[4]) -{ - int32_t intermediate_samples[4]; - unsigned i; - - /* Join 4 subbands into 2 intermediate subbands upsampled to 2 samples. */ - for (i = 0; i < 2; i++) - aptx_qmf_polyphase_synthesis(qmf->inner_filter_signal[i], - aptx_qmf_inner_coeffs, 22, - subband_samples[2*i+0], - subband_samples[2*i+1], - &intermediate_samples[2*i]); - - /* Join 2 samples from intermediate subbands upsampled to 4 samples. */ - for (i = 0; i < 2; i++) - aptx_qmf_polyphase_synthesis(qmf->outer_filter_signal, - aptx_qmf_outer_coeffs, 21, - intermediate_samples[0+i], - intermediate_samples[2+i], - &samples[2*i]); -} - static inline int32_t aptx_bin_search(int32_t value, int32_t factor, const int32_t *intervals, int nb_intervals) @@ -810,16 +776,6 @@ static void aptx_encode_channel(struct aptx_channel *channel, const int32_t samp } } -static void aptx_decode_channel(struct aptx_channel *channel, int32_t samples[4]) -{ - int32_t subband_samples[NB_SUBBANDS]; - unsigned subband; - - for (subband = 0; subband < NB_SUBBANDS; subband++) - subband_samples[subband] = channel->prediction[subband].previous_reconstructed_sample; - aptx_qmf_tree_synthesis(&channel->qmf, subband_samples, samples); -} - static void aptx_invert_quantization(struct aptx_invert_quantize *invert_quantize, int32_t quantized_sample, int32_t dither, @@ -993,26 +949,6 @@ static uint32_t aptxhd_pack_codeword(const struct aptx_channel *channel) | (((channel->quantize[0].quantized_sample & 0x1FF) ) << 0)); } -static void aptx_unpack_codeword(struct aptx_channel *channel, uint16_t codeword) -{ - channel->quantize[0].quantized_sample = sign_extend(codeword >> 0, 7); - channel->quantize[1].quantized_sample = sign_extend(codeword >> 7, 4); - channel->quantize[2].quantized_sample = sign_extend(codeword >> 11, 2); - channel->quantize[3].quantized_sample = sign_extend(codeword >> 13, 3); - channel->quantize[3].quantized_sample = (channel->quantize[3].quantized_sample & ~1) - | aptx_quantized_parity(channel); -} - -static void aptxhd_unpack_codeword(struct aptx_channel *channel, uint32_t codeword) -{ - channel->quantize[0].quantized_sample = sign_extend((int32_t)(codeword >> 0), 9); - channel->quantize[1].quantized_sample = sign_extend((int32_t)(codeword >> 9), 6); - channel->quantize[2].quantized_sample = sign_extend((int32_t)(codeword >> 15), 4); - channel->quantize[3].quantized_sample = sign_extend((int32_t)(codeword >> 19), 5); - channel->quantize[3].quantized_sample = (channel->quantize[3].quantized_sample & ~1) - | aptx_quantized_parity(channel); -} - static void aptx_encode_samples(struct aptx_context *ctx, int32_t samples[NB_CHANNELS][4], uint8_t *output) @@ -1038,57 +974,6 @@ static void aptx_encode_samples(struct aptx_context *ctx, } } -static int aptx_decode_samples(struct aptx_context *ctx, - const uint8_t *input, - int32_t samples[NB_CHANNELS][4]) -{ - unsigned channel; - int ret; - - for (channel = 0; channel < NB_CHANNELS; channel++) { - aptx_generate_dither(&ctx->channels[channel]); - - if (ctx->hd) - aptxhd_unpack_codeword(&ctx->channels[channel], - ((uint32_t)input[3*channel+0] << 16) | - ((uint32_t)input[3*channel+1] << 8) | - ((uint32_t)input[3*channel+2] << 0)); - else - aptx_unpack_codeword(&ctx->channels[channel], (uint16_t)( - ((uint16_t)input[2*channel+0] << 8) | - ((uint16_t)input[2*channel+1] << 0))); - aptx_invert_quantize_and_prediction(&ctx->channels[channel], ctx->hd); - } - - ret = aptx_check_parity(ctx->channels, &ctx->sync_idx); - - for (channel = 0; channel < NB_CHANNELS; channel++) - aptx_decode_channel(&ctx->channels[channel], samples[channel]); - - return ret; -} - -static void aptx_reset_decode_sync(struct aptx_context *ctx) -{ - const size_t decode_dropped = ctx->decode_dropped; - const size_t decode_sync_packets = ctx->decode_sync_packets; - const uint8_t decode_sync_buffer_len = ctx->decode_sync_buffer_len; - unsigned char decode_sync_buffer[6]; - unsigned i; - - for (i = 0; i < 6; i++) - decode_sync_buffer[i] = ctx->decode_sync_buffer[i]; - - aptx_reset(ctx); - - for (i = 0; i < 6; i++) - ctx->decode_sync_buffer[i] = decode_sync_buffer[i]; - - ctx->decode_sync_buffer_len = decode_sync_buffer_len; - ctx->decode_sync_packets = decode_sync_packets; - ctx->decode_dropped = decode_dropped; -} - const int aptx_major = FREEAPTX_MAJOR; const int aptx_minor = FREEAPTX_MINOR; @@ -1119,7 +1004,6 @@ void aptx_reset(struct aptx_context *ctx) ((unsigned char *)ctx)[i] = 0; ctx->hd = hd; - ctx->decode_skip_leading = (LATENCY_SAMPLES+3)/4; ctx->encode_remaining = (LATENCY_SAMPLES+3)/4; for (chan = 0; chan < NB_CHANNELS; chan++) { @@ -1186,140 +1070,30 @@ int aptx_encode_finish(struct aptx_context *ctx, unsigned char *output, size_t o size_t aptx_decode(struct aptx_context *ctx, const unsigned char *input, size_t input_size, unsigned char *output, size_t output_size, size_t *written) { - const size_t sample_size = ctx->hd ? 6 : 4; - int32_t samples[NB_CHANNELS][4]; - unsigned sample, channel; - size_t ipos, opos; - - for (ipos = 0, opos = 0; ipos + sample_size <= input_size && (opos + 3*NB_CHANNELS*4 <= output_size || ctx->decode_skip_leading > 0); ipos += sample_size) { - if (aptx_decode_samples(ctx, input + ipos, samples)) - break; - sample = 0; - if (ctx->decode_skip_leading > 0) { - ctx->decode_skip_leading--; - if (ctx->decode_skip_leading > 0) - continue; - sample = LATENCY_SAMPLES%4; - } - for (; sample < 4; sample++) { - for (channel = 0; channel < NB_CHANNELS; channel++, opos += 3) { - /* samples contain 24bit signed integers stored as 32bit signed integers */ - /* we do not need to care about negative integers specially as they have 23th bit set */ - output[opos+0] = (uint8_t)(((uint32_t)samples[channel][sample] >> 0) & 0xFF); - output[opos+1] = (uint8_t)(((uint32_t)samples[channel][sample] >> 8) & 0xFF); - output[opos+2] = (uint8_t)(((uint32_t)samples[channel][sample] >> 16) & 0xFF); - } - } - } - - *written = opos; - return ipos; + (void)ctx; + (void)input; + (void)input_size; + (void)output; + (void)output_size; + *written = 0; + return 0; } size_t aptx_decode_sync(struct aptx_context *ctx, const unsigned char *input, size_t input_size, unsigned char *output, size_t output_size, size_t *written, int *synced, size_t *dropped) { - const size_t sample_size = ctx->hd ? 6 : 4; - size_t input_size_step; - size_t processed_step; - size_t written_step; - size_t ipos = 0; - size_t opos = 0; - size_t i; - + (void)ctx; + (void)input; + (void)input_size; + (void)output; + (void)output_size; *synced = 0; *dropped = 0; - - /* If we have some unprocessed bytes in internal cache, first fill remaining data to internal cache except the final byte */ - if (ctx->decode_sync_buffer_len > 0 && sample_size-1 - ctx->decode_sync_buffer_len <= input_size) { - while (ctx->decode_sync_buffer_len < sample_size-1) - ctx->decode_sync_buffer[ctx->decode_sync_buffer_len++] = input[ipos++]; - } - - /* Internal cache decode loop, use it only when sample is split between internal cache and input buffer */ - while (ctx->decode_sync_buffer_len == sample_size-1 && ipos < sample_size && ipos < input_size && (opos + 3*NB_CHANNELS*4 <= output_size || ctx->decode_skip_leading > 0 || ctx->decode_dropped > 0)) { - ctx->decode_sync_buffer[sample_size-1] = input[ipos++]; - - processed_step = aptx_decode(ctx, ctx->decode_sync_buffer, sample_size, output + opos, output_size - opos, &written_step); - - opos += written_step; - - if (ctx->decode_dropped > 0 && processed_step == sample_size) { - ctx->decode_dropped += processed_step; - ctx->decode_sync_packets++; - if (ctx->decode_sync_packets >= (LATENCY_SAMPLES+3)/4) { - *dropped += ctx->decode_dropped; - ctx->decode_dropped = 0; - ctx->decode_sync_packets = 0; - } - } - - if (processed_step < sample_size) { - aptx_reset_decode_sync(ctx); - *synced = 0; - ctx->decode_dropped++; - ctx->decode_sync_packets = 0; - for (i = 0; i < sample_size-1; i++) - ctx->decode_sync_buffer[i] = ctx->decode_sync_buffer[i+1]; - } else { - if (ctx->decode_dropped == 0) - *synced = 1; - ctx->decode_sync_buffer_len = 0; - } - } - - /* If all unprocessed data are now available only in input buffer, do not use internal cache */ - if (ctx->decode_sync_buffer_len == sample_size-1 && ipos == sample_size) { - ipos = 0; - ctx->decode_sync_buffer_len = 0; - } - - /* Main decode loop, decode as much as possible samples, if decoding fails restart it on next byte */ - while (ipos + sample_size <= input_size && (opos + 3*NB_CHANNELS*4 <= output_size || ctx->decode_skip_leading > 0 || ctx->decode_dropped > 0)) { - input_size_step = (((output_size - opos) / (3*NB_CHANNELS*4)) + ctx->decode_skip_leading) * sample_size; - if (input_size_step > ((input_size - ipos) / sample_size) * sample_size) - input_size_step = ((input_size - ipos) / sample_size) * sample_size; - if (input_size_step > ((LATENCY_SAMPLES+3)/4 - ctx->decode_sync_packets) * sample_size && ctx->decode_dropped > 0) - input_size_step = ((LATENCY_SAMPLES+3)/4 - ctx->decode_sync_packets) * sample_size; - - processed_step = aptx_decode(ctx, input + ipos, input_size_step, output + opos, output_size - opos, &written_step); - - ipos += processed_step; - opos += written_step; - - if (ctx->decode_dropped > 0 && processed_step / sample_size > 0) { - ctx->decode_dropped += processed_step; - ctx->decode_sync_packets += processed_step / sample_size; - if (ctx->decode_sync_packets >= (LATENCY_SAMPLES+3)/4) { - *dropped += ctx->decode_dropped; - ctx->decode_dropped = 0; - ctx->decode_sync_packets = 0; - } - } - - if (processed_step < input_size_step) { - aptx_reset_decode_sync(ctx); - *synced = 0; - ipos++; - ctx->decode_dropped++; - ctx->decode_sync_packets = 0; - } else if (ctx->decode_dropped == 0) { - *synced = 1; - } - } - - /* If number of unprocessed bytes is less then sample size store them to internal cache */ - if (ipos + sample_size > input_size) { - while (ipos < input_size) - ctx->decode_sync_buffer[ctx->decode_sync_buffer_len++] = input[ipos++]; - } - - *written = opos; - return ipos; + *written = 0; + return 0; } size_t aptx_decode_sync_finish(struct aptx_context *ctx) { - const uint8_t dropped = ctx->decode_sync_buffer_len; aptx_reset(ctx); - return dropped; + return 0; }