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