FFmpeg
sbcdsp.c
Go to the documentation of this file.
1 /*
2  * Bluetooth low-complexity, subband codec (SBC)
3  *
4  * Copyright (C) 2017 Aurelien Jacobs <aurel@gnuage.org>
5  * Copyright (C) 2012-2013 Intel Corporation
6  * Copyright (C) 2008-2010 Nokia Corporation
7  * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
8  * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
9  * Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
10  *
11  * This file is part of FFmpeg.
12  *
13  * FFmpeg is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * FFmpeg is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with FFmpeg; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26  */
27 
28 /**
29  * @file
30  * SBC basic "building bricks"
31  */
32 
33 #include <stdint.h>
34 #include <limits.h>
35 #include <string.h>
36 #include "libavutil/common.h"
37 #include "libavutil/intmath.h"
38 #include "libavutil/intreadwrite.h"
39 #include "sbc.h"
40 #include "sbcdsp.h"
41 #include "sbcdsp_data.h"
42 
43 /*
44  * A reference C code of analysis filter with SIMD-friendly tables
45  * reordering and code layout. This code can be used to develop platform
46  * specific SIMD optimizations. Also it may be used as some kind of test
47  * for compiler autovectorization capabilities (who knows, if the compiler
48  * is very good at this stuff, hand optimized assembly may be not strictly
49  * needed for some platform).
50  *
51  * Note: It is also possible to make a simple variant of analysis filter,
52  * which needs only a single constants table without taking care about
53  * even/odd cases. This simple variant of filter can be implemented without
54  * input data permutation. The only thing that would be lost is the
55  * possibility to use pairwise SIMD multiplications. But for some simple
56  * CPU cores without SIMD extensions it can be useful. If anybody is
57  * interested in implementing such variant of a filter, sourcecode from
58  * bluez versions 4.26/4.27 can be used as a reference and the history of
59  * the changes in git repository done around that time may be worth checking.
60  */
61 
62 static av_always_inline void sbc_analyze_simd(const int16_t *in, int32_t *out,
63  const int16_t *consts,
64  unsigned subbands)
65 {
66  int32_t t1[8];
67  int16_t t2[8];
68  int i, j, hop = 0;
69 
70  /* rounding coefficient */
71  for (i = 0; i < subbands; i++)
72  t1[i] = 1 << (SBC_PROTO_FIXED_SCALE - 1);
73 
74  /* low pass polyphase filter */
75  for (hop = 0; hop < 10*subbands; hop += 2*subbands)
76  for (i = 0; i < 2*subbands; i++)
77  t1[i >> 1] += in[hop + i] * consts[hop + i];
78 
79  /* scaling */
80  for (i = 0; i < subbands; i++)
81  t2[i] = t1[i] >> SBC_PROTO_FIXED_SCALE;
82 
83  memset(t1, 0, sizeof(t1));
84 
85  /* do the cos transform */
86  for (i = 0; i < subbands/2; i++)
87  for (j = 0; j < 2*subbands; j++)
88  t1[j>>1] += t2[i * 2 + (j&1)] * consts[10*subbands + i*2*subbands + j];
89 
90  for (i = 0; i < subbands; i++)
91  out[i] = t1[i] >> (SBC_COS_TABLE_FIXED_SCALE - SCALE_OUT_BITS);
92 }
93 
94 static void sbc_analyze_4_simd(const int16_t *in, int32_t *out,
95  const int16_t *consts)
96 {
97  sbc_analyze_simd(in, out, consts, 4);
98 }
99 
100 static void sbc_analyze_8_simd(const int16_t *in, int32_t *out,
101  const int16_t *consts)
102 {
103  sbc_analyze_simd(in, out, consts, 8);
104 }
105 
106 static inline void sbc_analyze_4b_4s_simd(SBCDSPContext *s,
107  int16_t *x, int32_t *out, int out_stride)
108 {
109  /* Analyze blocks */
110  s->sbc_analyze_4(x + 12, out, ff_sbcdsp_analysis_consts_fixed4_simd_odd);
111  out += out_stride;
112  s->sbc_analyze_4(x + 8, out, ff_sbcdsp_analysis_consts_fixed4_simd_even);
113  out += out_stride;
114  s->sbc_analyze_4(x + 4, out, ff_sbcdsp_analysis_consts_fixed4_simd_odd);
115  out += out_stride;
116  s->sbc_analyze_4(x + 0, out, ff_sbcdsp_analysis_consts_fixed4_simd_even);
117 }
118 
119 static inline void sbc_analyze_4b_8s_simd(SBCDSPContext *s,
120  int16_t *x, int32_t *out, int out_stride)
121 {
122  /* Analyze blocks */
123  s->sbc_analyze_8(x + 24, out, ff_sbcdsp_analysis_consts_fixed8_simd_odd);
124  out += out_stride;
125  s->sbc_analyze_8(x + 16, out, ff_sbcdsp_analysis_consts_fixed8_simd_even);
126  out += out_stride;
127  s->sbc_analyze_8(x + 8, out, ff_sbcdsp_analysis_consts_fixed8_simd_odd);
128  out += out_stride;
129  s->sbc_analyze_8(x + 0, out, ff_sbcdsp_analysis_consts_fixed8_simd_even);
130 }
131 
132 static inline void sbc_analyze_1b_8s_simd_even(SBCDSPContext *s,
133  int16_t *x, int32_t *out,
134  int out_stride);
135 
136 static inline void sbc_analyze_1b_8s_simd_odd(SBCDSPContext *s,
137  int16_t *x, int32_t *out,
138  int out_stride)
139 {
140  s->sbc_analyze_8(x, out, ff_sbcdsp_analysis_consts_fixed8_simd_odd);
141  s->sbc_analyze_8s = sbc_analyze_1b_8s_simd_even;
142 }
143 
144 static inline void sbc_analyze_1b_8s_simd_even(SBCDSPContext *s,
145  int16_t *x, int32_t *out,
146  int out_stride)
147 {
148  s->sbc_analyze_8(x, out, ff_sbcdsp_analysis_consts_fixed8_simd_even);
149  s->sbc_analyze_8s = sbc_analyze_1b_8s_simd_odd;
150 }
151 
152 /*
153  * Input data processing functions. The data is endian converted if needed,
154  * channels are deintrleaved and audio samples are reordered for use in
155  * SIMD-friendly analysis filter function. The results are put into "X"
156  * array, getting appended to the previous data (or it is better to say
157  * prepended, as the buffer is filled from top to bottom). Old data is
158  * discarded when neededed, but availability of (10 * nrof_subbands)
159  * contiguous samples is always guaranteed for the input to the analysis
160  * filter. This is achieved by copying a sufficient part of old data
161  * to the top of the buffer on buffer wraparound.
162  */
163 
164 static int sbc_enc_process_input_4s(int position, const uint8_t *pcm,
165  int16_t X[2][SBC_X_BUFFER_SIZE],
166  int nsamples, int nchannels)
167 {
168  int c;
169 
170  /* handle X buffer wraparound */
171  if (position < nsamples) {
172  for (c = 0; c < nchannels; c++)
173  memcpy(&X[c][SBC_X_BUFFER_SIZE - 40], &X[c][position],
174  36 * sizeof(int16_t));
175  position = SBC_X_BUFFER_SIZE - 40;
176  }
177 
178  /* copy/permutate audio samples */
179  for (; nsamples >= 8; nsamples -= 8, pcm += 16 * nchannels) {
180  position -= 8;
181  for (c = 0; c < nchannels; c++) {
182  int16_t *x = &X[c][position];
183  x[0] = AV_RN16(pcm + 14*nchannels + 2*c);
184  x[1] = AV_RN16(pcm + 6*nchannels + 2*c);
185  x[2] = AV_RN16(pcm + 12*nchannels + 2*c);
186  x[3] = AV_RN16(pcm + 8*nchannels + 2*c);
187  x[4] = AV_RN16(pcm + 0*nchannels + 2*c);
188  x[5] = AV_RN16(pcm + 4*nchannels + 2*c);
189  x[6] = AV_RN16(pcm + 2*nchannels + 2*c);
190  x[7] = AV_RN16(pcm + 10*nchannels + 2*c);
191  }
192  }
193 
194  return position;
195 }
196 
197 static int sbc_enc_process_input_8s(int position, const uint8_t *pcm,
198  int16_t X[2][SBC_X_BUFFER_SIZE],
199  int nsamples, int nchannels)
200 {
201  int c;
202 
203  /* handle X buffer wraparound */
204  if (position < nsamples) {
205  for (c = 0; c < nchannels; c++)
206  memcpy(&X[c][SBC_X_BUFFER_SIZE - 72], &X[c][position],
207  72 * sizeof(int16_t));
208  position = SBC_X_BUFFER_SIZE - 72;
209  }
210 
211  if (position % 16 == 8) {
212  position -= 8;
213  nsamples -= 8;
214  for (c = 0; c < nchannels; c++) {
215  int16_t *x = &X[c][position];
216  x[0] = AV_RN16(pcm + 14*nchannels + 2*c);
217  x[2] = AV_RN16(pcm + 12*nchannels + 2*c);
218  x[3] = AV_RN16(pcm + 0*nchannels + 2*c);
219  x[4] = AV_RN16(pcm + 10*nchannels + 2*c);
220  x[5] = AV_RN16(pcm + 2*nchannels + 2*c);
221  x[6] = AV_RN16(pcm + 8*nchannels + 2*c);
222  x[7] = AV_RN16(pcm + 4*nchannels + 2*c);
223  x[8] = AV_RN16(pcm + 6*nchannels + 2*c);
224  }
225  pcm += 16 * nchannels;
226  }
227 
228  /* copy/permutate audio samples */
229  for (; nsamples >= 16; nsamples -= 16, pcm += 32 * nchannels) {
230  position -= 16;
231  for (c = 0; c < nchannels; c++) {
232  int16_t *x = &X[c][position];
233  x[0] = AV_RN16(pcm + 30*nchannels + 2*c);
234  x[1] = AV_RN16(pcm + 14*nchannels + 2*c);
235  x[2] = AV_RN16(pcm + 28*nchannels + 2*c);
236  x[3] = AV_RN16(pcm + 16*nchannels + 2*c);
237  x[4] = AV_RN16(pcm + 26*nchannels + 2*c);
238  x[5] = AV_RN16(pcm + 18*nchannels + 2*c);
239  x[6] = AV_RN16(pcm + 24*nchannels + 2*c);
240  x[7] = AV_RN16(pcm + 20*nchannels + 2*c);
241  x[8] = AV_RN16(pcm + 22*nchannels + 2*c);
242  x[9] = AV_RN16(pcm + 6*nchannels + 2*c);
243  x[10] = AV_RN16(pcm + 12*nchannels + 2*c);
244  x[11] = AV_RN16(pcm + 0*nchannels + 2*c);
245  x[12] = AV_RN16(pcm + 10*nchannels + 2*c);
246  x[13] = AV_RN16(pcm + 2*nchannels + 2*c);
247  x[14] = AV_RN16(pcm + 8*nchannels + 2*c);
248  x[15] = AV_RN16(pcm + 4*nchannels + 2*c);
249  }
250  }
251 
252  if (nsamples == 8) {
253  position -= 8;
254  for (c = 0; c < nchannels; c++) {
255  int16_t *x = &X[c][position];
256  x[-7] = AV_RN16(pcm + 14*nchannels + 2*c);
257  x[1] = AV_RN16(pcm + 6*nchannels + 2*c);
258  x[2] = AV_RN16(pcm + 12*nchannels + 2*c);
259  x[3] = AV_RN16(pcm + 0*nchannels + 2*c);
260  x[4] = AV_RN16(pcm + 10*nchannels + 2*c);
261  x[5] = AV_RN16(pcm + 2*nchannels + 2*c);
262  x[6] = AV_RN16(pcm + 8*nchannels + 2*c);
263  x[7] = AV_RN16(pcm + 4*nchannels + 2*c);
264  }
265  }
266 
267  return position;
268 }
269 
270 static void sbc_calc_scalefactors(int32_t sb_sample_f[16][2][8],
271  uint32_t scale_factor[2][8],
272  int blocks, int channels, int subbands)
273 {
274  int ch, sb, blk;
275  for (ch = 0; ch < channels; ch++) {
276  for (sb = 0; sb < subbands; sb++) {
277  uint32_t x = 1 << SCALE_OUT_BITS;
278  for (blk = 0; blk < blocks; blk++) {
279  int32_t tmp = FFABS(sb_sample_f[blk][ch][sb]);
280  if (tmp != 0)
281  x |= tmp - 1;
282  }
283  scale_factor[ch][sb] = (31 - SCALE_OUT_BITS) - ff_clz(x);
284  }
285  }
286 }
287 
288 static int sbc_calc_scalefactors_j(int32_t sb_sample_f[16][2][8],
289  uint32_t scale_factor[2][8],
290  int blocks, int subbands)
291 {
292  int blk, joint = 0;
293  int32_t tmp0, tmp1;
294  uint32_t x, y;
295 
296  /* last subband does not use joint stereo */
297  int sb = subbands - 1;
298  x = 1 << SCALE_OUT_BITS;
299  y = 1 << SCALE_OUT_BITS;
300  for (blk = 0; blk < blocks; blk++) {
301  tmp0 = FFABS(sb_sample_f[blk][0][sb]);
302  tmp1 = FFABS(sb_sample_f[blk][1][sb]);
303  if (tmp0 != 0)
304  x |= tmp0 - 1;
305  if (tmp1 != 0)
306  y |= tmp1 - 1;
307  }
308  scale_factor[0][sb] = (31 - SCALE_OUT_BITS) - ff_clz(x);
309  scale_factor[1][sb] = (31 - SCALE_OUT_BITS) - ff_clz(y);
310 
311  /* the rest of subbands can use joint stereo */
312  while (--sb >= 0) {
313  int32_t sb_sample_j[16][2];
314  x = 1 << SCALE_OUT_BITS;
315  y = 1 << SCALE_OUT_BITS;
316  for (blk = 0; blk < blocks; blk++) {
317  tmp0 = sb_sample_f[blk][0][sb];
318  tmp1 = sb_sample_f[blk][1][sb];
319  sb_sample_j[blk][0] = (tmp0 >> 1) + (tmp1 >> 1);
320  sb_sample_j[blk][1] = (tmp0 >> 1) - (tmp1 >> 1);
321  tmp0 = FFABS(tmp0);
322  tmp1 = FFABS(tmp1);
323  if (tmp0 != 0)
324  x |= tmp0 - 1;
325  if (tmp1 != 0)
326  y |= tmp1 - 1;
327  }
328  scale_factor[0][sb] = (31 - SCALE_OUT_BITS) -
329  ff_clz(x);
330  scale_factor[1][sb] = (31 - SCALE_OUT_BITS) -
331  ff_clz(y);
332  x = 1 << SCALE_OUT_BITS;
333  y = 1 << SCALE_OUT_BITS;
334  for (blk = 0; blk < blocks; blk++) {
335  tmp0 = FFABS(sb_sample_j[blk][0]);
336  tmp1 = FFABS(sb_sample_j[blk][1]);
337  if (tmp0 != 0)
338  x |= tmp0 - 1;
339  if (tmp1 != 0)
340  y |= tmp1 - 1;
341  }
342  x = (31 - SCALE_OUT_BITS) - ff_clz(x);
343  y = (31 - SCALE_OUT_BITS) - ff_clz(y);
344 
345  /* decide whether to use joint stereo for this subband */
346  if ((scale_factor[0][sb] + scale_factor[1][sb]) > x + y) {
347  joint |= 1 << (subbands - 1 - sb);
348  scale_factor[0][sb] = x;
349  scale_factor[1][sb] = y;
350  for (blk = 0; blk < blocks; blk++) {
351  sb_sample_f[blk][0][sb] = sb_sample_j[blk][0];
352  sb_sample_f[blk][1][sb] = sb_sample_j[blk][1];
353  }
354  }
355  }
356 
357  /* bitmask with the information about subbands using joint stereo */
358  return joint;
359 }
360 
361 /*
362  * Detect CPU features and setup function pointers
363  */
364 av_cold void ff_sbcdsp_init(SBCDSPContext *s)
365 {
366  /* Default implementation for analyze functions */
367  s->sbc_analyze_4 = sbc_analyze_4_simd;
368  s->sbc_analyze_8 = sbc_analyze_8_simd;
369  s->sbc_analyze_4s = sbc_analyze_4b_4s_simd;
370  if (s->increment == 1)
371  s->sbc_analyze_8s = sbc_analyze_1b_8s_simd_odd;
372  else
373  s->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
374 
375  /* Default implementation for input reordering / deinterleaving */
376  s->sbc_enc_process_input_4s = sbc_enc_process_input_4s;
377  s->sbc_enc_process_input_8s = sbc_enc_process_input_8s;
378 
379  /* Default implementation for scale factors calculation */
380  s->sbc_calc_scalefactors = sbc_calc_scalefactors;
381  s->sbc_calc_scalefactors_j = sbc_calc_scalefactors_j;
382 
383  if (ARCH_ARM)
385  if (ARCH_X86)
387 }
const int16_t ff_sbcdsp_analysis_consts_fixed4_simd_odd[40+16]
Definition: sbcdsp_data.c:92
#define SBC_COS_TABLE_FIXED_SCALE
Definition: sbcdsp_data.h:38
#define SBC_X_BUFFER_SIZE
Definition: sbcdsp.h:39
static void sbc_analyze_8_simd(const int16_t *in, int32_t *out, const int16_t *consts)
Definition: sbcdsp.c:100
static int sbc_enc_process_input_4s(int position, const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE], int nsamples, int nchannels)
Definition: sbcdsp.c:164
channels
Definition: aptx.c:30
Definition: vf_addroi.c:26
const int16_t ff_sbcdsp_analysis_consts_fixed8_simd_even[80+64]
Definition: sbcdsp_data.c:137
#define blk(i)
Definition: sha.c:185
static void sbc_analyze_4b_4s_simd(SBCDSPContext *s, int16_t *x, int32_t *out, int out_stride)
Definition: sbcdsp.c:106
miscellaneous SBC tables
SBC basic "building bricks".
static void sbc_analyze_4b_8s_simd(SBCDSPContext *s, int16_t *x, int32_t *out, int out_stride)
Definition: sbcdsp.c:119
uint8_t
#define av_cold
Definition: attributes.h:82
static void sbc_analyze_1b_8s_simd_odd(SBCDSPContext *s, int16_t *x, int32_t *out, int out_stride)
Definition: sbcdsp.c:136
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
#define SBC_PROTO_FIXED_SCALE
Definition: sbcdsp_data.h:37
void ff_sbcdsp_init_x86(SBCDSPContext *s)
Definition: sbcdsp_init.c:42
static void sbc_analyze_4_simd(const int16_t *in, int32_t *out, const int16_t *consts)
Definition: sbcdsp.c:94
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_cold void ff_sbcdsp_init_arm(SBCDSPContext *s)
#define t1
Definition: regdef.h:29
av_cold void ff_sbcdsp_init(SBCDSPContext *s)
Definition: sbcdsp.c:364
#define ff_clz
Definition: intmath.h:142
int32_t
static int sbc_calc_scalefactors_j(int32_t sb_sample_f[16][2][8], uint32_t scale_factor[2][8], int blocks, int subbands)
Definition: sbcdsp.c:288
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
#define s(width, name)
Definition: cbs_vp9.c:257
const int16_t ff_sbcdsp_analysis_consts_fixed4_simd_even[40+16]
Definition: sbcdsp_data.c:47
static av_always_inline void sbc_analyze_simd(const int16_t *in, int32_t *out, const int16_t *consts, unsigned subbands)
Definition: sbcdsp.c:62
#define AV_RN16(p)
Definition: intreadwrite.h:360
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static void sbc_analyze_1b_8s_simd_even(SBCDSPContext *s, int16_t *x, int32_t *out, int out_stride)
Definition: sbcdsp.c:144
const int16_t ff_sbcdsp_analysis_consts_fixed8_simd_odd[80+64]
Definition: sbcdsp_data.c:234
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
common internal and external API header
SBC common definitions for the encoder and decoder.
static void sbc_calc_scalefactors(int32_t sb_sample_f[16][2][8], uint32_t scale_factor[2][8], int blocks, int channels, int subbands)
Definition: sbcdsp.c:270
FILE * out
Definition: movenc.c:54
#define av_always_inline
Definition: attributes.h:39
subbands
Definition: aptx.c:36
#define SCALE_OUT_BITS
Definition: sbcdsp.h:38
#define t2
Definition: regdef.h:30
static int sbc_enc_process_input_8s(int position, const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE], int nsamples, int nchannels)
Definition: sbcdsp.c:197
static uint8_t tmp[11]
Definition: aes_ctr.c:26