Libav
dcadsp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 Gildas Bazin
3  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 
24 #include "libavutil/attributes.h"
25 #include "libavutil/intreadwrite.h"
26 
27 #include "dcadsp.h"
28 #include "dcamath.h"
29 
31  const int32_t vq_num[DCA_SUBBANDS],
32  const int8_t hf_vq[1024][32], intptr_t vq_offset,
33  int32_t scale[DCA_SUBBANDS][2],
34  intptr_t start, intptr_t end)
35 {
36  int i, j;
37 
38  for (j = start; j < end; j++) {
39  const int8_t *ptr = &hf_vq[vq_num[j]][vq_offset];
40  for (i = 0; i < 8; i++)
41  dst[j][i] = ptr[i] * scale[j][0] + 8 >> 4;
42  }
43 }
44 
45 static inline void dca_lfe_fir(float *out, const float *in, const float *coefs,
46  int decifactor)
47 {
48  float *out2 = out + 2 * decifactor - 1;
49  int num_coeffs = 256 / decifactor;
50  int j, k;
51 
52  /* One decimated sample generates 2*decifactor interpolated ones */
53  for (k = 0; k < decifactor; k++) {
54  float v0 = 0.0;
55  float v1 = 0.0;
56  for (j = 0; j < num_coeffs; j++, coefs++) {
57  v0 += in[-j] * *coefs;
58  v1 += in[j + 1 - num_coeffs] * *coefs;
59  }
60  *out++ = v0;
61  *out2-- = v1;
62  }
63 }
64 
65 static void dca_qmf_32_subbands(float samples_in[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], int sb_act,
66  SynthFilterContext *synth, FFTContext *imdct,
67  float synth_buf_ptr[512],
68  int *synth_buf_offset, float synth_buf2[32],
69  const float window[512], float *samples_out,
70  float raXin[32], float scale)
71 {
72  int i;
73  int subindex;
74 
75  for (i = sb_act; i < 32; i++)
76  raXin[i] = 0.0;
77 
78  /* Reconstructed channel sample index */
79  for (subindex = 0; subindex < 8; subindex++) {
80  /* Load in one sample from each subband and clear inactive subbands */
81  for (i = 0; i < sb_act; i++) {
82  unsigned sign = (i - 1) & 2;
83  uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
84  AV_WN32A(&raXin[i], v);
85  }
86 
87  synth->synth_filter_float(imdct, synth_buf_ptr, synth_buf_offset,
88  synth_buf2, window, samples_out, raXin,
89  scale);
90  samples_out += 32;
91  }
92 }
93 
94 static void dequantize_c(int32_t *samples, uint32_t step_size, uint32_t scale)
95 {
96  int64_t step = (int64_t)step_size * scale;
97  int shift, i;
98  int32_t step_scale;
99 
100  if (step > (1 << 23))
101  shift = av_log2(step >> 23) + 1;
102  else
103  shift = 0;
104  step_scale = (int32_t)(step >> shift);
105 
106  for (i = 0; i < SAMPLES_PER_SUBBAND; i++)
107  samples[i] = dca_clip23(dca_norm((int64_t)samples[i] * step_scale, 22 - shift));
108 }
109 
110 static void dca_lfe_fir0_c(float *out, const float *in, const float *coefs)
111 {
112  dca_lfe_fir(out, in, coefs, 32);
113 }
114 
115 static void dca_lfe_fir1_c(float *out, const float *in, const float *coefs)
116 {
117  dca_lfe_fir(out, in, coefs, 64);
118 }
119 
121 {
122  s->lfe_fir[0] = dca_lfe_fir0_c;
123  s->lfe_fir[1] = dca_lfe_fir1_c;
125  s->decode_hf = decode_hf_c;
127 
128  if (ARCH_AARCH64)
130  if (ARCH_ARM)
132  if (ARCH_X86)
134 }
static void dequantize_c(int32_t *samples, uint32_t step_size, uint32_t scale)
Definition: dcadsp.c:94
void(* lfe_fir[2])(float *out, const float *in, const float *coefs)
Definition: dcadsp.h:31
av_cold void ff_dcadsp_init(DCADSPContext *s)
Definition: dcadsp.c:120
#define AV_WN32A(p, v)
Definition: intreadwrite.h:469
Macro definitions for various function/variable attributes.
#define AV_RN32A(p)
Definition: intreadwrite.h:457
void(* synth_filter_float)(FFTContext *imdct, float *synth_buf_ptr, int *synth_buf_offset, float synth_buf2[32], const float window[512], float out[32], const float in[32], float scale)
Definition: synth_filter.h:27
#define av_cold
Definition: attributes.h:66
av_cold void ff_dcadsp_init_arm(DCADSPContext *s)
void(* decode_hf)(int32_t dst[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], const int32_t vq_num[DCA_SUBBANDS], const int8_t hf_vq[1024][32], intptr_t vq_offset, int32_t scale[DCA_SUBBANDS][2], intptr_t start, intptr_t end)
Definition: dcadsp.h:38
#define ARCH_X86
Definition: config.h:33
static int32_t dca_norm(int64_t a, int bits)
Definition: dcamath.h:28
static void dca_lfe_fir(float *out, const float *in, const float *coefs, int decifactor)
Definition: dcadsp.c:45
Definition: fft.h:73
#define ARCH_ARM
Definition: config.h:14
int32_t
void(* qmf_32_subbands)(float samples_in[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], int sb_act, SynthFilterContext *synth, FFTContext *imdct, float synth_buf_ptr[512], int *synth_buf_offset, float synth_buf2[32], const float window[512], float *samples_out, float raXin[32], float scale)
Definition: dcadsp.h:32
static void dca_qmf_32_subbands(float samples_in[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], int sb_act, SynthFilterContext *synth, FFTContext *imdct, float synth_buf_ptr[512], int *synth_buf_offset, float synth_buf2[32], const float window[512], float *samples_out, float raXin[32], float scale)
Definition: dcadsp.c:65
static void dca_lfe_fir0_c(float *out, const float *in, const float *coefs)
Definition: dcadsp.c:110
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)\", 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 dca_lfe_fir1_c(float *out, const float *in, const float *coefs)
Definition: dcadsp.c:115
static int step
Definition: avplay.c:247
av_cold void ff_dcadsp_init_aarch64(DCADSPContext *s)
Definition: dcadsp_init.c:44
void(* dequantize)(int32_t *samples, uint32_t step_size, uint32_t scale)
Definition: dcadsp.h:43
static void decode_hf_c(int32_t dst[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], const int32_t vq_num[DCA_SUBBANDS], const int8_t hf_vq[1024][32], intptr_t vq_offset, int32_t scale[DCA_SUBBANDS][2], intptr_t start, intptr_t end)
Definition: dcadsp.c:30
#define DCA_SUBBANDS
Definition: dcadsp.h:26
void ff_dcadsp_init_x86(DCADSPContext *s)
Definition: dcadsp_init.c:29
#define av_log2
Definition: intmath.h:85
#define ARCH_AARCH64
Definition: config.h:12
FILE * out
Definition: movenc.c:54
static int dca_clip23(int a)
Definition: dcamath.h:23
#define SAMPLES_PER_SUBBAND
Definition: dcadsp.h:27