2 * RealAudio 2.0 (28.8K)
3 * Copyright (c) 2003 The FFmpeg Project
5 * This file is part of FFmpeg.
7 * FFmpeg 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.
12 * FFmpeg 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/channel_layout.h"
23 #include "libavutil/float_dsp.h"
24 #include "libavutil/internal.h"
27 #define BITSTREAM_READER_LE
31 #include "celp_filters.h"
33 #define MAX_BACKWARD_FILTER_ORDER 36
34 #define MAX_BACKWARD_FILTER_LEN 40
35 #define MAX_BACKWARD_FILTER_NONREC 35
37 #define RA288_BLOCK_SIZE 5
38 #define RA288_BLOCKS_PER_FRAME 32
41 AVFloatDSPContext
*fdsp
;
42 DECLARE_ALIGNED(32, float, sp_lpc
)[FFALIGN(36, 16)]; ///< LPC coefficients for speech data (spec: A)
43 DECLARE_ALIGNED(32, float, gain_lpc
)[FFALIGN(10, 16)]; ///< LPC coefficients for gain (spec: GB)
45 /** speech data history (spec: SB).
46 * Its first 70 coefficients are updated only at backward filtering.
50 /// speech part of the gain autocorrelation (spec: REXP)
53 /** log-gain history (spec: SBLG).
54 * Its first 28 coefficients are updated only at backward filtering.
58 /// recursive part of the gain autocorrelation (spec: REXPLG)
62 static av_cold
int ra288_decode_close(AVCodecContext
*avctx
)
64 RA288Context
*ractx
= avctx
->priv_data
;
66 av_freep(&ractx
->fdsp
);
71 static av_cold
int ra288_decode_init(AVCodecContext
*avctx
)
73 RA288Context
*ractx
= avctx
->priv_data
;
76 avctx
->channel_layout
= AV_CH_LAYOUT_MONO
;
77 avctx
->sample_fmt
= AV_SAMPLE_FMT_FLT
;
79 if (avctx
->block_align
<= 0) {
80 av_log(avctx
, AV_LOG_ERROR
, "unsupported block align\n");
81 return AVERROR_PATCHWELCOME
;
84 ractx
->fdsp
= avpriv_float_dsp_alloc(avctx
->flags
& CODEC_FLAG_BITEXACT
);
86 return AVERROR(ENOMEM
);
91 static void convolve(float *tgt
, const float *src
, int len
, int n
)
94 tgt
[n
] = avpriv_scalarproduct_float_c(src
, src
- n
, len
);
98 static void decode(RA288Context
*ractx
, float gain
, int cb_coef
)
102 float sum
, buffer
[5];
103 float *block
= ractx
->sp_hist
+ 70 + 36; // current block
104 float *gain_block
= ractx
->gain_hist
+ 28;
106 memmove(ractx
->sp_hist
+ 70, ractx
->sp_hist
+ 75, 36*sizeof(*block
));
108 /* block 46 of G.728 spec */
110 for (i
=0; i
< 10; i
++)
111 sum
-= gain_block
[9-i
] * ractx
->gain_lpc
[i
];
113 /* block 47 of G.728 spec */
114 sum
= av_clipf(sum
, 0, 60);
116 /* block 48 of G.728 spec */
117 /* exp(sum * 0.1151292546497) == pow(10.0,sum/20) */
118 sumsum
= exp(sum
* 0.1151292546497) * gain
* (1.0/(1<<23));
120 for (i
=0; i
< 5; i
++)
121 buffer
[i
] = codetable
[cb_coef
][i
] * sumsum
;
123 sum
= avpriv_scalarproduct_float_c(buffer
, buffer
, 5);
125 sum
= FFMAX(sum
, 5.0 / (1<<24));
127 /* shift and store */
128 memmove(gain_block
, gain_block
+ 1, 9 * sizeof(*gain_block
));
130 gain_block
[9] = 10 * log10(sum
) + (10*log10(((1<<24)/5.)) - 32);
132 ff_celp_lp_synthesis_filterf(block
, ractx
->sp_lpc
, buffer
, 5, 36);
136 * Hybrid window filtering, see blocks 36 and 49 of the G.728 specification.
138 * @param order filter order
139 * @param n input length
140 * @param non_rec number of non-recursive samples
141 * @param out filter output
142 * @param hist pointer to the input history of the filter
143 * @param out pointer to the non-recursive part of the output
144 * @param out2 pointer to the recursive part of the output
145 * @param window pointer to the windowing function table
147 static void do_hybrid_window(RA288Context
*ractx
,
148 int order
, int n
, int non_rec
, float *out
,
149 float *hist
, float *out2
, const float *window
)
152 float buffer1
[MAX_BACKWARD_FILTER_ORDER
+ 1];
153 float buffer2
[MAX_BACKWARD_FILTER_ORDER
+ 1];
154 LOCAL_ALIGNED(32, float, work
, [FFALIGN(MAX_BACKWARD_FILTER_ORDER
+
155 MAX_BACKWARD_FILTER_LEN
+
156 MAX_BACKWARD_FILTER_NONREC
, 16)]);
158 av_assert2(order
>=0);
160 ractx
->fdsp
->vector_fmul(work
, window
, hist
, FFALIGN(order
+ n
+ non_rec
, 16));
162 convolve(buffer1
, work
+ order
, n
, order
);
163 convolve(buffer2
, work
+ order
+ n
, non_rec
, order
);
165 for (i
=0; i
<= order
; i
++) {
166 out2
[i
] = out2
[i
] * 0.5625 + buffer1
[i
];
167 out
[i
] = out2
[i
] + buffer2
[i
];
170 /* Multiply by the white noise correcting factor (WNCF). */
171 *out
*= 257.0 / 256.0;
175 * Backward synthesis filter, find the LPC coefficients from past speech data.
177 static void backward_filter(RA288Context
*ractx
,
178 float *hist
, float *rec
, const float *window
,
179 float *lpc
, const float *tab
,
180 int order
, int n
, int non_rec
, int move_size
)
182 float temp
[MAX_BACKWARD_FILTER_ORDER
+1];
184 do_hybrid_window(ractx
, order
, n
, non_rec
, temp
, hist
, rec
, window
);
186 if (!compute_lpc_coefs(temp
, order
, lpc
, 0, 1, 1))
187 ractx
->fdsp
->vector_fmul(lpc
, lpc
, tab
, FFALIGN(order
, 16));
189 memmove(hist
, hist
+ n
, move_size
*sizeof(*hist
));
192 static int ra288_decode_frame(AVCodecContext
* avctx
, void *data
,
193 int *got_frame_ptr
, AVPacket
*avpkt
)
195 AVFrame
*frame
= data
;
196 const uint8_t *buf
= avpkt
->data
;
197 int buf_size
= avpkt
->size
;
200 RA288Context
*ractx
= avctx
->priv_data
;
203 if (buf_size
< avctx
->block_align
) {
204 av_log(avctx
, AV_LOG_ERROR
,
205 "Error! Input buffer is too small [%d<%d]\n",
206 buf_size
, avctx
->block_align
);
207 return AVERROR_INVALIDDATA
;
210 /* get output buffer */
211 frame
->nb_samples
= RA288_BLOCK_SIZE
* RA288_BLOCKS_PER_FRAME
;
212 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
214 out
= (float *)frame
->data
[0];
216 init_get_bits8(&gb
, buf
, avctx
->block_align
);
218 for (i
=0; i
< RA288_BLOCKS_PER_FRAME
; i
++) {
219 float gain
= amptable
[get_bits(&gb
, 3)];
220 int cb_coef
= get_bits(&gb
, 6 + (i
&1));
222 decode(ractx
, gain
, cb_coef
);
224 memcpy(out
, &ractx
->sp_hist
[70 + 36], RA288_BLOCK_SIZE
* sizeof(*out
));
225 out
+= RA288_BLOCK_SIZE
;
228 backward_filter(ractx
, ractx
->sp_hist
, ractx
->sp_rec
, syn_window
,
229 ractx
->sp_lpc
, syn_bw_tab
, 36, 40, 35, 70);
231 backward_filter(ractx
, ractx
->gain_hist
, ractx
->gain_rec
, gain_window
,
232 ractx
->gain_lpc
, gain_bw_tab
, 10, 8, 20, 28);
238 return avctx
->block_align
;
241 AVCodec ff_ra_288_decoder
= {
243 .long_name
= NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
244 .type
= AVMEDIA_TYPE_AUDIO
,
245 .id
= AV_CODEC_ID_RA_288
,
246 .priv_data_size
= sizeof(RA288Context
),
247 .init
= ra288_decode_init
,
248 .decode
= ra288_decode_frame
,
249 .close
= ra288_decode_close
,
250 .capabilities
= CODEC_CAP_DR1
,