2 * Audio Processing Technology codec for Bluetooth (aptX)
4 * Copyright (C) 2017 Aurelien Jacobs <aurel@gnuage.org>
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "config_components.h"
25 #include "libavutil/channel_layout.h"
27 #include "audio_frame_queue.h"
28 #include "codec_internal.h"
32 typedef struct AptXEncContext
{
38 * Half-band QMF analysis filter realized with a polyphase FIR filter.
39 * Split into 2 subbands and downsample by 2.
40 * So for each pair of samples that goes in, one sample goes out,
41 * split into 2 separate subbands.
44 static void aptx_qmf_polyphase_analysis(FilterSignal signal
[NB_FILTERS
],
45 const int32_t coeffs
[NB_FILTERS
][FILTER_TAPS
],
47 int32_t samples
[NB_FILTERS
],
48 int32_t *low_subband_output
,
49 int32_t *high_subband_output
)
51 int32_t subbands
[NB_FILTERS
];
54 for (i
= 0; i
< NB_FILTERS
; i
++) {
55 aptx_qmf_filter_signal_push(&signal
[i
], samples
[NB_FILTERS
-1-i
]);
56 subbands
[i
] = aptx_qmf_convolution(&signal
[i
], coeffs
[i
], shift
);
59 *low_subband_output
= av_clip_intp2(subbands
[0] + subbands
[1], 23);
60 *high_subband_output
= av_clip_intp2(subbands
[0] - subbands
[1], 23);
64 * Two stage QMF analysis tree.
65 * Split 4 input samples into 4 subbands and downsample by 4.
66 * So for each group of 4 samples that goes in, one sample goes out,
67 * split into 4 separate subbands.
69 static void aptx_qmf_tree_analysis(QMFAnalysis
*qmf
,
71 int32_t subband_samples
[4])
73 int32_t intermediate_samples
[4];
76 /* Split 4 input samples into 2 intermediate subbands downsampled to 2 samples */
77 for (i
= 0; i
< 2; i
++)
78 aptx_qmf_polyphase_analysis(qmf
->outer_filter_signal
,
79 aptx_qmf_outer_coeffs
, 23,
81 &intermediate_samples
[0+i
],
82 &intermediate_samples
[2+i
]);
84 /* Split 2 intermediate subband samples into 4 final subbands downsampled to 1 sample */
85 for (i
= 0; i
< 2; i
++)
86 aptx_qmf_polyphase_analysis(qmf
->inner_filter_signal
[i
],
87 aptx_qmf_inner_coeffs
, 23,
88 &intermediate_samples
[2*i
],
89 &subband_samples
[2*i
+0],
90 &subband_samples
[2*i
+1]);
94 static int32_t aptx_bin_search(int32_t value
, int32_t factor
,
95 const int32_t *intervals
, int32_t nb_intervals
)
100 for (i
= nb_intervals
>> 1; i
> 0; i
>>= 1)
101 if (MUL64(factor
, intervals
[idx
+ i
]) <= ((int64_t)value
<< 24))
107 static void aptx_quantize_difference(Quantize
*quantize
,
108 int32_t sample_difference
,
110 int32_t quantization_factor
,
113 const int32_t *intervals
= tables
->quantize_intervals
;
114 int32_t quantized_sample
, dithered_sample
, parity_change
;
115 int32_t d
, mean
, interval
, inv
, sample_difference_abs
;
118 sample_difference_abs
= FFABS(sample_difference
);
119 sample_difference_abs
= FFMIN(sample_difference_abs
, (1 << 23) - 1);
121 quantized_sample
= aptx_bin_search(sample_difference_abs
>> 4,
123 intervals
, tables
->tables_size
);
125 d
= rshift32_clip24(MULH(dither
, dither
), 7) - (1 << 23);
126 d
= rshift64(MUL64(d
, tables
->quantize_dither_factors
[quantized_sample
]), 23);
128 intervals
+= quantized_sample
;
129 mean
= (intervals
[1] + intervals
[0]) / 2;
130 interval
= (intervals
[1] - intervals
[0]) * (-(sample_difference
< 0) | 1);
132 dithered_sample
= rshift64_clip24(MUL64(dither
, interval
) + ((int64_t)av_clip_intp2(mean
+ d
, 23) << 32), 32);
133 error
= ((int64_t)sample_difference_abs
<< 20) - MUL64(dithered_sample
, quantization_factor
);
134 quantize
->error
= FFABS(rshift64(error
, 23));
136 parity_change
= quantized_sample
;
142 inv
= -(sample_difference
< 0);
143 quantize
->quantized_sample
= quantized_sample
^ inv
;
144 quantize
->quantized_sample_parity_change
= parity_change
^ inv
;
147 static void aptx_encode_channel(Channel
*channel
, int32_t samples
[4], int hd
)
149 int32_t subband_samples
[4];
151 aptx_qmf_tree_analysis(&channel
->qmf
, samples
, subband_samples
);
152 ff_aptx_generate_dither(channel
);
153 for (subband
= 0; subband
< NB_SUBBANDS
; subband
++) {
154 int32_t diff
= av_clip_intp2(subband_samples
[subband
] - channel
->prediction
[subband
].predicted_sample
, 23);
155 aptx_quantize_difference(&channel
->quantize
[subband
], diff
,
156 channel
->dither
[subband
],
157 channel
->invert_quantize
[subband
].quantization_factor
,
158 &ff_aptx_quant_tables
[hd
][subband
]);
162 static void aptx_insert_sync(Channel channels
[NB_CHANNELS
], int32_t *idx
)
164 if (aptx_check_parity(channels
, idx
)) {
167 static const int map
[] = { 1, 2, 0, 3 };
168 Quantize
*min
= &channels
[NB_CHANNELS
-1].quantize
[map
[0]];
169 for (c
= &channels
[NB_CHANNELS
-1]; c
>= channels
; c
--)
170 for (i
= 0; i
< NB_SUBBANDS
; i
++)
171 if (c
->quantize
[map
[i
]].error
< min
->error
)
172 min
= &c
->quantize
[map
[i
]];
174 /* Forcing the desired parity is done by offsetting by 1 the quantized
175 * sample from the subband featuring the smallest quantization error. */
176 min
->quantized_sample
= min
->quantized_sample_parity_change
;
180 static uint16_t aptx_pack_codeword(Channel
*channel
)
182 int32_t parity
= aptx_quantized_parity(channel
);
183 return (((channel
->quantize
[3].quantized_sample
& 0x06) | parity
) << 13)
184 | (((channel
->quantize
[2].quantized_sample
& 0x03) ) << 11)
185 | (((channel
->quantize
[1].quantized_sample
& 0x0F) ) << 7)
186 | (((channel
->quantize
[0].quantized_sample
& 0x7F) ) << 0);
189 static uint32_t aptxhd_pack_codeword(Channel
*channel
)
191 int32_t parity
= aptx_quantized_parity(channel
);
192 return (((channel
->quantize
[3].quantized_sample
& 0x01E) | parity
) << 19)
193 | (((channel
->quantize
[2].quantized_sample
& 0x00F) ) << 15)
194 | (((channel
->quantize
[1].quantized_sample
& 0x03F) ) << 9)
195 | (((channel
->quantize
[0].quantized_sample
& 0x1FF) ) << 0);
198 static void aptx_encode_samples(AptXContext
*ctx
,
199 int32_t samples
[NB_CHANNELS
][4],
203 for (channel
= 0; channel
< NB_CHANNELS
; channel
++)
204 aptx_encode_channel(&ctx
->channels
[channel
], samples
[channel
], ctx
->hd
);
206 aptx_insert_sync(ctx
->channels
, &ctx
->sync_idx
);
208 for (channel
= 0; channel
< NB_CHANNELS
; channel
++) {
209 ff_aptx_invert_quantize_and_prediction(&ctx
->channels
[channel
], ctx
->hd
);
211 AV_WB24(output
+ 3*channel
,
212 aptxhd_pack_codeword(&ctx
->channels
[channel
]));
214 AV_WB16(output
+ 2*channel
,
215 aptx_pack_codeword(&ctx
->channels
[channel
]));
219 static int aptx_encode_frame(AVCodecContext
*avctx
, AVPacket
*avpkt
,
220 const AVFrame
*frame
, int *got_packet_ptr
)
222 AptXEncContext
*const s0
= avctx
->priv_data
;
223 AptXContext
*const s
= &s0
->common
;
224 int pos
, ipos
, channel
, sample
, output_size
, ret
;
226 if ((ret
= ff_af_queue_add(&s0
->afq
, frame
)) < 0)
229 output_size
= s
->block_size
* frame
->nb_samples
/4;
230 if ((ret
= ff_get_encode_buffer(avctx
, avpkt
, output_size
, 0)) < 0)
233 for (pos
= 0, ipos
= 0; pos
< output_size
; pos
+= s
->block_size
, ipos
+= 4) {
234 int32_t samples
[NB_CHANNELS
][4];
236 for (channel
= 0; channel
< NB_CHANNELS
; channel
++)
237 for (sample
= 0; sample
< 4; sample
++)
238 samples
[channel
][sample
] = (int32_t)AV_RN32A(&frame
->data
[channel
][4*(ipos
+sample
)]) >> 8;
240 aptx_encode_samples(s
, samples
, avpkt
->data
+ pos
);
243 ff_af_queue_remove(&s0
->afq
, frame
->nb_samples
, &avpkt
->pts
, &avpkt
->duration
);
248 static av_cold
int aptx_close(AVCodecContext
*avctx
)
250 AptXEncContext
*const s
= avctx
->priv_data
;
251 ff_af_queue_close(&s
->afq
);
255 static av_cold
int aptx_encode_init(AVCodecContext
*avctx
)
257 AptXEncContext
*const s
= avctx
->priv_data
;
259 ff_af_queue_init(avctx
, &s
->afq
);
261 if (!avctx
->frame_size
|| avctx
->frame_size
% 4)
262 avctx
->frame_size
= 1024;
263 avctx
->internal
->pad_samples
= 4;
265 return ff_aptx_init(avctx
);
268 #if CONFIG_APTX_ENCODER
269 const FFCodec ff_aptx_encoder
= {
271 CODEC_LONG_NAME("aptX (Audio Processing Technology for Bluetooth)"),
272 .p
.type
= AVMEDIA_TYPE_AUDIO
,
273 .p
.id
= AV_CODEC_ID_APTX
,
274 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
,
275 .priv_data_size
= sizeof(AptXEncContext
),
276 .init
= aptx_encode_init
,
277 FF_CODEC_ENCODE_CB(aptx_encode_frame
),
279 .p
.ch_layouts
= (const AVChannelLayout
[]) { AV_CHANNEL_LAYOUT_STEREO
, { 0 } },
280 .p
.sample_fmts
= (const enum AVSampleFormat
[]) { AV_SAMPLE_FMT_S32P
,
281 AV_SAMPLE_FMT_NONE
},
282 .p
.supported_samplerates
= (const int[]) {8000, 16000, 24000, 32000, 44100, 48000, 0},
286 #if CONFIG_APTX_HD_ENCODER
287 const FFCodec ff_aptx_hd_encoder
= {
289 CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"),
290 .p
.type
= AVMEDIA_TYPE_AUDIO
,
291 .p
.id
= AV_CODEC_ID_APTX_HD
,
292 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
,
293 .priv_data_size
= sizeof(AptXEncContext
),
294 .init
= aptx_encode_init
,
295 FF_CODEC_ENCODE_CB(aptx_encode_frame
),
297 .p
.ch_layouts
= (const AVChannelLayout
[]) { AV_CHANNEL_LAYOUT_STEREO
, { 0 } },
298 .p
.sample_fmts
= (const enum AVSampleFormat
[]) { AV_SAMPLE_FMT_S32P
,
299 AV_SAMPLE_FMT_NONE
},
300 .p
.supported_samplerates
= (const int[]) {8000, 16000, 24000, 32000, 44100, 48000, 0},