1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Audio Processing Technology codec for Bluetooth (aptX) 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (C) 2017 Aurelien Jacobs <aurel@gnuage.org> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#ifndef AVCODEC_APTX_H 24cabdff1aSopenharmony_ci#define AVCODEC_APTX_H 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 27cabdff1aSopenharmony_ci#include "avcodec.h" 28cabdff1aSopenharmony_ci#include "mathops.h" 29cabdff1aSopenharmony_ci#include "audio_frame_queue.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_cienum channels { 33cabdff1aSopenharmony_ci LEFT, 34cabdff1aSopenharmony_ci RIGHT, 35cabdff1aSopenharmony_ci NB_CHANNELS 36cabdff1aSopenharmony_ci}; 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_cienum subbands { 39cabdff1aSopenharmony_ci LF, // Low Frequency (0-5.5 kHz) 40cabdff1aSopenharmony_ci MLF, // Medium-Low Frequency (5.5-11kHz) 41cabdff1aSopenharmony_ci MHF, // Medium-High Frequency (11-16.5kHz) 42cabdff1aSopenharmony_ci HF, // High Frequency (16.5-22kHz) 43cabdff1aSopenharmony_ci NB_SUBBANDS 44cabdff1aSopenharmony_ci}; 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_ci#define NB_FILTERS 2 47cabdff1aSopenharmony_ci#define FILTER_TAPS 16 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_citypedef struct { 50cabdff1aSopenharmony_ci int pos; 51cabdff1aSopenharmony_ci int32_t buffer[2*FILTER_TAPS]; 52cabdff1aSopenharmony_ci} FilterSignal; 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_citypedef struct { 55cabdff1aSopenharmony_ci FilterSignal outer_filter_signal[NB_FILTERS]; 56cabdff1aSopenharmony_ci FilterSignal inner_filter_signal[NB_FILTERS][NB_FILTERS]; 57cabdff1aSopenharmony_ci} QMFAnalysis; 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_citypedef struct { 60cabdff1aSopenharmony_ci int32_t quantized_sample; 61cabdff1aSopenharmony_ci int32_t quantized_sample_parity_change; 62cabdff1aSopenharmony_ci int32_t error; 63cabdff1aSopenharmony_ci} Quantize; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_citypedef struct { 66cabdff1aSopenharmony_ci int32_t quantization_factor; 67cabdff1aSopenharmony_ci int32_t factor_select; 68cabdff1aSopenharmony_ci int32_t reconstructed_difference; 69cabdff1aSopenharmony_ci} InvertQuantize; 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_citypedef struct { 72cabdff1aSopenharmony_ci int32_t prev_sign[2]; 73cabdff1aSopenharmony_ci int32_t s_weight[2]; 74cabdff1aSopenharmony_ci int32_t d_weight[24]; 75cabdff1aSopenharmony_ci int32_t pos; 76cabdff1aSopenharmony_ci int32_t reconstructed_differences[48]; 77cabdff1aSopenharmony_ci int32_t previous_reconstructed_sample; 78cabdff1aSopenharmony_ci int32_t predicted_difference; 79cabdff1aSopenharmony_ci int32_t predicted_sample; 80cabdff1aSopenharmony_ci} Prediction; 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_citypedef struct { 83cabdff1aSopenharmony_ci int32_t codeword_history; 84cabdff1aSopenharmony_ci int32_t dither_parity; 85cabdff1aSopenharmony_ci int32_t dither[NB_SUBBANDS]; 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci QMFAnalysis qmf; 88cabdff1aSopenharmony_ci Quantize quantize[NB_SUBBANDS]; 89cabdff1aSopenharmony_ci InvertQuantize invert_quantize[NB_SUBBANDS]; 90cabdff1aSopenharmony_ci Prediction prediction[NB_SUBBANDS]; 91cabdff1aSopenharmony_ci} Channel; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_citypedef struct { 94cabdff1aSopenharmony_ci int hd; 95cabdff1aSopenharmony_ci int block_size; 96cabdff1aSopenharmony_ci int32_t sync_idx; 97cabdff1aSopenharmony_ci Channel channels[NB_CHANNELS]; 98cabdff1aSopenharmony_ci AudioFrameQueue afq; 99cabdff1aSopenharmony_ci} AptXContext; 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_citypedef const struct { 102cabdff1aSopenharmony_ci const int32_t *quantize_intervals; 103cabdff1aSopenharmony_ci const int32_t *invert_quantize_dither_factors; 104cabdff1aSopenharmony_ci const int32_t *quantize_dither_factors; 105cabdff1aSopenharmony_ci const int16_t *quantize_factor_select_offset; 106cabdff1aSopenharmony_ci int tables_size; 107cabdff1aSopenharmony_ci int32_t factor_max; 108cabdff1aSopenharmony_ci int32_t prediction_order; 109cabdff1aSopenharmony_ci} ConstTables; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ciextern ConstTables ff_aptx_quant_tables[2][NB_SUBBANDS]; 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci/* Rounded right shift with optionnal clipping */ 114cabdff1aSopenharmony_ci#define RSHIFT_SIZE(size) \ 115cabdff1aSopenharmony_ciav_always_inline \ 116cabdff1aSopenharmony_cistatic int##size##_t rshift##size(int##size##_t value, int shift) \ 117cabdff1aSopenharmony_ci{ \ 118cabdff1aSopenharmony_ci int##size##_t rounding = (int##size##_t)1 << (shift - 1); \ 119cabdff1aSopenharmony_ci int##size##_t mask = ((int##size##_t)1 << (shift + 1)) - 1; \ 120cabdff1aSopenharmony_ci return ((value + rounding) >> shift) - ((value & mask) == rounding); \ 121cabdff1aSopenharmony_ci} \ 122cabdff1aSopenharmony_ciav_always_inline \ 123cabdff1aSopenharmony_cistatic int##size##_t rshift##size##_clip24(int##size##_t value, int shift) \ 124cabdff1aSopenharmony_ci{ \ 125cabdff1aSopenharmony_ci return av_clip_intp2(rshift##size(value, shift), 23); \ 126cabdff1aSopenharmony_ci} 127cabdff1aSopenharmony_ciRSHIFT_SIZE(32) 128cabdff1aSopenharmony_ciRSHIFT_SIZE(64) 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci/* 131cabdff1aSopenharmony_ci * Convolution filter coefficients for the outer QMF of the QMF tree. 132cabdff1aSopenharmony_ci * The 2 sets are a mirror of each other. 133cabdff1aSopenharmony_ci */ 134cabdff1aSopenharmony_cistatic const int32_t aptx_qmf_outer_coeffs[NB_FILTERS][FILTER_TAPS] = { 135cabdff1aSopenharmony_ci { 136cabdff1aSopenharmony_ci 730, -413, -9611, 43626, -121026, 269973, -585547, 2801966, 137cabdff1aSopenharmony_ci 697128, -160481, 27611, 8478, -10043, 3511, 688, -897, 138cabdff1aSopenharmony_ci }, 139cabdff1aSopenharmony_ci { 140cabdff1aSopenharmony_ci -897, 688, 3511, -10043, 8478, 27611, -160481, 697128, 141cabdff1aSopenharmony_ci 2801966, -585547, 269973, -121026, 43626, -9611, -413, 730, 142cabdff1aSopenharmony_ci }, 143cabdff1aSopenharmony_ci}; 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci/* 146cabdff1aSopenharmony_ci * Convolution filter coefficients for the inner QMF of the QMF tree. 147cabdff1aSopenharmony_ci * The 2 sets are a mirror of each other. 148cabdff1aSopenharmony_ci */ 149cabdff1aSopenharmony_cistatic const int32_t aptx_qmf_inner_coeffs[NB_FILTERS][FILTER_TAPS] = { 150cabdff1aSopenharmony_ci { 151cabdff1aSopenharmony_ci 1033, -584, -13592, 61697, -171156, 381799, -828088, 3962579, 152cabdff1aSopenharmony_ci 985888, -226954, 39048, 11990, -14203, 4966, 973, -1268, 153cabdff1aSopenharmony_ci }, 154cabdff1aSopenharmony_ci { 155cabdff1aSopenharmony_ci -1268, 973, 4966, -14203, 11990, 39048, -226954, 985888, 156cabdff1aSopenharmony_ci 3962579, -828088, 381799, -171156, 61697, -13592, -584, 1033, 157cabdff1aSopenharmony_ci }, 158cabdff1aSopenharmony_ci}; 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci/* 161cabdff1aSopenharmony_ci * Push one sample into a circular signal buffer. 162cabdff1aSopenharmony_ci */ 163cabdff1aSopenharmony_ciav_always_inline 164cabdff1aSopenharmony_cistatic void aptx_qmf_filter_signal_push(FilterSignal *signal, int32_t sample) 165cabdff1aSopenharmony_ci{ 166cabdff1aSopenharmony_ci signal->buffer[signal->pos ] = sample; 167cabdff1aSopenharmony_ci signal->buffer[signal->pos+FILTER_TAPS] = sample; 168cabdff1aSopenharmony_ci signal->pos = (signal->pos + 1) & (FILTER_TAPS - 1); 169cabdff1aSopenharmony_ci} 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci/* 172cabdff1aSopenharmony_ci * Compute the convolution of the signal with the coefficients, and reduce 173cabdff1aSopenharmony_ci * to 24 bits by applying the specified right shifting. 174cabdff1aSopenharmony_ci */ 175cabdff1aSopenharmony_ciav_always_inline 176cabdff1aSopenharmony_cistatic int32_t aptx_qmf_convolution(FilterSignal *signal, 177cabdff1aSopenharmony_ci const int32_t coeffs[FILTER_TAPS], 178cabdff1aSopenharmony_ci int shift) 179cabdff1aSopenharmony_ci{ 180cabdff1aSopenharmony_ci int32_t *sig = &signal->buffer[signal->pos]; 181cabdff1aSopenharmony_ci int64_t e = 0; 182cabdff1aSopenharmony_ci int i; 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_ci for (i = 0; i < FILTER_TAPS; i++) 185cabdff1aSopenharmony_ci e += MUL64(sig[i], coeffs[i]); 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci return rshift64_clip24(e, shift); 188cabdff1aSopenharmony_ci} 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_cistatic inline int32_t aptx_quantized_parity(Channel *channel) 191cabdff1aSopenharmony_ci{ 192cabdff1aSopenharmony_ci int32_t parity = channel->dither_parity; 193cabdff1aSopenharmony_ci int subband; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci for (subband = 0; subband < NB_SUBBANDS; subband++) 196cabdff1aSopenharmony_ci parity ^= channel->quantize[subband].quantized_sample; 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci return parity & 1; 199cabdff1aSopenharmony_ci} 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci/* For each sample, ensure that the parity of all subbands of all channels 202cabdff1aSopenharmony_ci * is 0 except once every 8 samples where the parity is forced to 1. */ 203cabdff1aSopenharmony_cistatic inline int aptx_check_parity(Channel channels[NB_CHANNELS], int32_t *idx) 204cabdff1aSopenharmony_ci{ 205cabdff1aSopenharmony_ci int32_t parity = aptx_quantized_parity(&channels[LEFT]) 206cabdff1aSopenharmony_ci ^ aptx_quantized_parity(&channels[RIGHT]); 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci int eighth = *idx == 7; 209cabdff1aSopenharmony_ci *idx = (*idx + 1) & 7; 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci return parity ^ eighth; 212cabdff1aSopenharmony_ci} 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_civoid ff_aptx_invert_quantize_and_prediction(Channel *channel, int hd); 215cabdff1aSopenharmony_civoid ff_aptx_generate_dither(Channel *channel); 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ciint ff_aptx_init(AVCodecContext *avctx); 218cabdff1aSopenharmony_ci 219cabdff1aSopenharmony_ci#endif /* AVCODEC_APTX_H */ 220