Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 233 lines (187 sloc) 7.629 kB
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
1 /*
2 * RealAudio 2.0 (28.8K)
3 * Copyright (c) 2003 the ffmpeg project
4 *
2912e87 @mansr Replace FFmpeg with Libav in licence headers
mansr authored
5 * This file is part of Libav.
b78e719 @DonDiego Change license headers to say 'FFmpeg' instead of 'this program/this …
DonDiego authored
6 *
2912e87 @mansr Replace FFmpeg with Libav in licence headers
mansr authored
7 * Libav is free software; you can redistribute it and/or
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e719 @DonDiego Change license headers to say 'FFmpeg' instead of 'this program/this …
DonDiego authored
10 * version 2.1 of the License, or (at your option) any later version.
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
11 *
2912e87 @mansr Replace FFmpeg with Libav in licence headers
mansr authored
12 * Libav is distributed in the hope that it will be useful,
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
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
2912e87 @mansr Replace FFmpeg with Libav in licence headers
mansr authored
18 * License along with Libav; if not, write to the Free Software
5509bff @DonDiego Update licensing information: The FSF changed postal address.
DonDiego authored
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
20 */
21
22 #include "avcodec.h"
a40b2c2 Rewrite unpack() using the bitstream reader
Vitor Sessak authored
23 #define ALT_BITSTREAM_READER_LE
9106a69 Rename bitstream.h to get_bits.h.
Stefano Sabatini authored
24 #include "get_bits.h"
9085af0 @axic moved the tables into header files (and applied the 'static' patch). …
axic authored
25 #include "ra288.h"
1be0fc2 Avoid duplicating compute_lpc_coefs() function in both the RA288 and …
Vitor Sessak authored
26 #include "lpc.h"
08c4339 Use ff_dot_productf() in ra288.c
Vitor Sessak authored
27 #include "celp_math.h"
66d4c62 Do not reimplement ff_celp_lp_synthesis_filterf().
Vitor Sessak authored
28 #include "celp_filters.h"
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
29 #include "dsputil.h"
115329f @DonDiego COSMETICS: Remove all trailing whitespace.
DonDiego authored
30
0b37ccc @mansr ra288: convert VLAs to fixed size
mansr authored
31 #define MAX_BACKWARD_FILTER_ORDER 36
32 #define MAX_BACKWARD_FILTER_LEN 40
33 #define MAX_BACKWARD_FILTER_NONREC 35
34
fa6be04 @justinruggles ra288: use a more descriptive calculation for output data size
justinruggles authored
35 #define RA288_BLOCK_SIZE 5
36 #define RA288_BLOCKS_PER_FRAME 32
37
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
38 typedef struct {
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
39 AVFrame frame;
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
40 DSPContext dsp;
41 DECLARE_ALIGNED(16, float, sp_lpc)[FFALIGN(36, 8)]; ///< LPC coefficients for speech data (spec: A)
42 DECLARE_ALIGNED(16, float, gain_lpc)[FFALIGN(10, 8)]; ///< LPC coefficients for gain (spec: GB)
eec7ade Reindent the whole file
Vitor Sessak authored
43
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
44 /** speech data history (spec: SB).
45 * Its first 70 coefficients are updated only at backward filtering.
46 */
47 float sp_hist[111];
272d258 Rename st{1,2}{a,b} context variables to more meaningful names: {sp,g…
Vitor Sessak authored
48
9c10ab6 Cosmetics: align spec references
Vitor Sessak authored
49 /// speech part of the gain autocorrelation (spec: REXP)
272d258 Rename st{1,2}{a,b} context variables to more meaningful names: {sp,g…
Vitor Sessak authored
50 float sp_rec[37];
51
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
52 /** log-gain history (spec: SBLG).
53 * Its first 28 coefficients are updated only at backward filtering.
54 */
55 float gain_hist[38];
272d258 Rename st{1,2}{a,b} context variables to more meaningful names: {sp,g…
Vitor Sessak authored
56
9c10ab6 Cosmetics: align spec references
Vitor Sessak authored
57 /// recursive part of the gain autocorrelation (spec: REXPLG)
272d258 Rename st{1,2}{a,b} context variables to more meaningful names: {sp,g…
Vitor Sessak authored
58 float gain_rec[11];
029e1c0 Give the context structure of ra288 a better name: s/Real288_internal…
Vitor Sessak authored
59 } RA288Context;
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
60
fd76c37 Modify all codecs to report their supported input and output sample f…
Peter Ross authored
61 static av_cold int ra288_decode_init(AVCodecContext *avctx)
62 {
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
63 RA288Context *ractx = avctx->priv_data;
5d6e4c1 Replace deprecated symbols SAMPLE_FMT_* with AV_SAMPLE_FMT_*, and enum
Stefano Sabatini authored
64 avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
65 dsputil_init(&ractx->dsp, avctx);
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
66
67 avcodec_get_frame_defaults(&ractx->frame);
68 avctx->coded_frame = &ractx->frame;
69
fd76c37 Modify all codecs to report their supported input and output sample f…
Peter Ross authored
70 return 0;
71 }
72
e60daa3 Cosmetics: move convolve() together with the other DSP functions
Vitor Sessak authored
73 static void convolve(float *tgt, const float *src, int len, int n)
74 {
75 for (; n >= 0; n--)
08c4339 Use ff_dot_productf() in ra288.c
Vitor Sessak authored
76 tgt[n] = ff_dot_productf(src, src - n, len);
e60daa3 Cosmetics: move convolve() together with the other DSP functions
Vitor Sessak authored
77
78 }
79
952a980 Give the context variables of ra288 a better name: s/glob/ractx/
Vitor Sessak authored
80 static void decode(RA288Context *ractx, float gain, int cb_coef)
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
81 {
66d4c62 Do not reimplement ff_celp_lp_synthesis_filterf().
Vitor Sessak authored
82 int i;
aa64ee3 Do not declare as double a var that only stores a float
Vitor Sessak authored
83 double sumsum;
84 float sum, buffer[5];
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
85 float *block = ractx->sp_hist + 70 + 36; // current block
86 float *gain_block = ractx->gain_hist + 28;
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
87
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
88 memmove(ractx->sp_hist + 70, ractx->sp_hist + 75, 36*sizeof(*block));
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
89
b26d320 Add a few comments pointing to the G.728 specification
Vitor Sessak authored
90 /* block 46 of G.728 spec */
e3751aa Flip (by making buf[i] -> buf[size-i-1]) two buffers: {sp,gain}_block…
Vitor Sessak authored
91 sum = 32.;
92 for (i=0; i < 10; i++)
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
93 sum -= gain_block[9-i] * ractx->gain_lpc[i];
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
94
b26d320 Add a few comments pointing to the G.728 specification
Vitor Sessak authored
95 /* block 47 of G.728 spec */
3819081 Another av_clipf() usage
Vitor Sessak authored
96 sum = av_clipf(sum, 0, 60);
eec7ade Reindent the whole file
Vitor Sessak authored
97
b26d320 Add a few comments pointing to the G.728 specification
Vitor Sessak authored
98 /* block 48 of G.728 spec */
a987a12 Simplify: move division by constant off the loop
Vitor Sessak authored
99 /* exp(sum * 0.1151292546497) == pow(10.0,sum/20) */
64e4af2 Do instead of divising a float by a constant, multiply by its inverse
Vitor Sessak authored
100 sumsum = exp(sum * 0.1151292546497) * gain * (1.0/(1<<23));
eec7ade Reindent the whole file
Vitor Sessak authored
101
4e33ed3 Cosmetics: rename loop counter vars to i,j
Vitor Sessak authored
102 for (i=0; i < 5; i++)
a987a12 Simplify: move division by constant off the loop
Vitor Sessak authored
103 buffer[i] = codetable[cb_coef][i] * sumsum;
eec7ade Reindent the whole file
Vitor Sessak authored
104
08c4339 Use ff_dot_productf() in ra288.c
Vitor Sessak authored
105 sum = ff_dot_productf(buffer, buffer, 5) * ((1<<24)/5.);
0e3510a Revert r14218. FFMAX is a macro, so
Vitor Sessak authored
106
107 sum = FFMAX(sum, 1);
eec7ade Reindent the whole file
Vitor Sessak authored
108
109 /* shift and store */
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
110 memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block));
eec7ade Reindent the whole file
Vitor Sessak authored
111
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
112 gain_block[9] = 10 * log10(sum) - 32;
eec7ade Reindent the whole file
Vitor Sessak authored
113
66d4c62 Do not reimplement ff_celp_lp_synthesis_filterf().
Vitor Sessak authored
114 ff_celp_lp_synthesis_filterf(block, ractx->sp_lpc, buffer, 5, 36);
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
115 }
116
475d0e1 Add comments to do_hybrid_window()
Vitor Sessak authored
117 /**
36b3e36 @DonDiego misc spelling/wording/grammar fixes
DonDiego authored
118 * Hybrid window filtering, see blocks 36 and 49 of the G.728 specification.
475d0e1 Add comments to do_hybrid_window()
Vitor Sessak authored
119 *
36b3e36 @DonDiego misc spelling/wording/grammar fixes
DonDiego authored
120 * @param order filter order
121 * @param n input length
122 * @param non_rec number of non-recursive samples
123 * @param out filter output
111734d Simplify: use a single history buffer for gain and a single one for
Vitor Sessak authored
124 * @param hist pointer to the input history of the filter
a53b545 Cosmetics: grammar nits
Vitor Sessak authored
125 * @param out pointer to the non-recursive part of the output
475d0e1 Add comments to do_hybrid_window()
Vitor Sessak authored
126 * @param out2 pointer to the recursive part of the output
127 * @param window pointer to the windowing function table
128 */
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
129 static void do_hybrid_window(RA288Context *ractx,
130 int order, int n, int non_rec, float *out,
9547cad Cosmetics: line breaks
Vitor Sessak authored
131 float *hist, float *out2, const float *window)
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
132 {
4ca7e74 Do not declare a counter as unsigned when it is not needed
Vitor Sessak authored
133 int i;
0b37ccc @mansr ra288: convert VLAs to fixed size
mansr authored
134 float buffer1[MAX_BACKWARD_FILTER_ORDER + 1];
135 float buffer2[MAX_BACKWARD_FILTER_ORDER + 1];
9cb70ce @justinruggles ra288: fix formatting of LOCAL_ALIGNED_16
justinruggles authored
136 LOCAL_ALIGNED_16(float, work, [FFALIGN(MAX_BACKWARD_FILTER_ORDER +
137 MAX_BACKWARD_FILTER_LEN +
138 MAX_BACKWARD_FILTER_NONREC, 8)]);
eec7ade Reindent the whole file
Vitor Sessak authored
139
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
140 ractx->dsp.vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 8));
115329f @DonDiego COSMETICS: Remove all trailing whitespace.
DonDiego authored
141
6888b4f Rename prodsum() function to convolve()
Vitor Sessak authored
142 convolve(buffer1, work + order , n , order);
143 convolve(buffer2, work + order + n, non_rec, order);
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
144
4e33ed3 Cosmetics: rename loop counter vars to i,j
Vitor Sessak authored
145 for (i=0; i <= order; i++) {
146 out2[i] = out2[i] * 0.5625 + buffer1[i];
147 out [i] = out2[i] + buffer2[i];
eec7ade Reindent the whole file
Vitor Sessak authored
148 }
427981c Rename co() function to the much more descriptive name of
Vitor Sessak authored
149
36b3e36 @DonDiego misc spelling/wording/grammar fixes
DonDiego authored
150 /* Multiply by the white noise correcting factor (WNCF). */
427981c Rename co() function to the much more descriptive name of
Vitor Sessak authored
151 *out *= 257./256.;
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
152 }
153
2477d60 Rename update() function to backward_filter() and add a doxy comment
Vitor Sessak authored
154 /**
36b3e36 @DonDiego misc spelling/wording/grammar fixes
DonDiego authored
155 * Backward synthesis filter, find the LPC coefficients from past speech data.
2477d60 Rename update() function to backward_filter() and add a doxy comment
Vitor Sessak authored
156 */
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
157 static void backward_filter(RA288Context *ractx,
158 float *hist, float *rec, const float *window,
d552d04 Simplify: avoid duplication backward_filter()
Vitor Sessak authored
159 float *lpc, const float *tab,
160 int order, int n, int non_rec, int move_size)
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
161 {
0b37ccc @mansr ra288: convert VLAs to fixed size
mansr authored
162 float temp[MAX_BACKWARD_FILTER_ORDER+1];
aed39f6 Remove RA288Context.output buffer. This buffer is just RA288Context.sb
Vitor Sessak authored
163
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
164 do_hybrid_window(ractx, order, n, non_rec, temp, hist, rec, window);
4452836 Move function to avoid forward declaration
Vitor Sessak authored
165
d552d04 Simplify: avoid duplication backward_filter()
Vitor Sessak authored
166 if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
167 ractx->dsp.vector_fmul(lpc, lpc, tab, FFALIGN(order, 8));
4452836 Move function to avoid forward declaration
Vitor Sessak authored
168
d552d04 Simplify: avoid duplication backward_filter()
Vitor Sessak authored
169 memmove(hist, hist + n, move_size*sizeof(*hist));
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
170 }
171
f38deb4 Remove useless wrapper around ra288_decode_frame()
Vitor Sessak authored
172 static int ra288_decode_frame(AVCodecContext * avctx, void *data,
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
173 int *got_frame_ptr, AVPacket *avpkt)
860208a finally works now
Nick Kurshev authored
174 {
7a00bba Implement avcodec_decode_video2(), _audio3() and _subtitle2() which t…
Thilo Borgmann authored
175 const uint8_t *buf = avpkt->data;
176 int buf_size = avpkt->size;
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
177 float *out;
178 int i, ret;
952a980 Give the context variables of ra288 a better name: s/glob/ractx/
Vitor Sessak authored
179 RA288Context *ractx = avctx->priv_data;
6091357 Remove unpack() function, read the bitstream as needed
Vitor Sessak authored
180 GetBitContext gb;
eec7ade Reindent the whole file
Vitor Sessak authored
181
f38deb4 Remove useless wrapper around ra288_decode_frame()
Vitor Sessak authored
182 if (buf_size < avctx->block_align) {
183 av_log(avctx, AV_LOG_ERROR,
184 "Error! Input buffer is too small [%d<%d]\n",
185 buf_size, avctx->block_align);
2467d8d @justinruggles ra288: return error if input buffer is too small
justinruggles authored
186 return AVERROR_INVALIDDATA;
f38deb4 Remove useless wrapper around ra288_decode_frame()
Vitor Sessak authored
187 }
188
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
189 /* get output buffer */
190 ractx->frame.nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
191 if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) {
192 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
193 return ret;
8f8f5ae @justinruggles ra288: log an error message when output buffer is too small.
justinruggles authored
194 }
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
195 out = (float *)ractx->frame.data[0];
8089c65 Check *data_size in decode_frame()
Vitor Sessak authored
196
f38deb4 Remove useless wrapper around ra288_decode_frame()
Vitor Sessak authored
197 init_get_bits(&gb, buf, avctx->block_align * 8);
eec7ade Reindent the whole file
Vitor Sessak authored
198
fa6be04 @justinruggles ra288: use a more descriptive calculation for output data size
justinruggles authored
199 for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) {
12ea267 Simplify
Vitor Sessak authored
200 float gain = amptable[get_bits(&gb, 3)];
4e33ed3 Cosmetics: rename loop counter vars to i,j
Vitor Sessak authored
201 int cb_coef = get_bits(&gb, 6 + (i&1));
045e21c Cosmetics: new line
Vitor Sessak authored
202
952a980 Give the context variables of ra288 a better name: s/glob/ractx/
Vitor Sessak authored
203 decode(ractx, gain, cb_coef);
eec7ade Reindent the whole file
Vitor Sessak authored
204
03e5d61 @justinruggles ra288: use memcpy() to copy decoded samples to output
justinruggles authored
205 memcpy(out, &ractx->sp_hist[70 + 36], RA288_BLOCK_SIZE * sizeof(*out));
206 out += RA288_BLOCK_SIZE;
eec7ade Reindent the whole file
Vitor Sessak authored
207
d552d04 Simplify: avoid duplication backward_filter()
Vitor Sessak authored
208 if ((i & 7) == 3) {
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
209 backward_filter(ractx, ractx->sp_hist, ractx->sp_rec, syn_window,
d552d04 Simplify: avoid duplication backward_filter()
Vitor Sessak authored
210 ractx->sp_lpc, syn_bw_tab, 36, 40, 35, 70);
211
0131e70 @justinruggles ra288: utilize DSPContext.vector_fmul()
justinruggles authored
212 backward_filter(ractx, ractx->gain_hist, ractx->gain_rec, gain_window,
d552d04 Simplify: avoid duplication backward_filter()
Vitor Sessak authored
213 ractx->gain_lpc, gain_bw_tab, 10, 8, 20, 28);
214 }
eec7ade Reindent the whole file
Vitor Sessak authored
215 }
216
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
217 *got_frame_ptr = 1;
218 *(AVFrame *)data = ractx->frame;
219
e0f7e32 @merbanan Cook compatibe decoder, patch by Benjamin Larsson
merbanan authored
220 return avctx->block_align;
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
221 }
222
8671488 @DonDiego Use explicit struct initializers for AVCodec declarations.
DonDiego authored
223 AVCodec ff_ra_288_decoder = {
224 .name = "real_288",
225 .type = AVMEDIA_TYPE_AUDIO,
226 .id = CODEC_ID_RA_288,
227 .priv_data_size = sizeof(RA288Context),
228 .init = ra288_decode_init,
229 .decode = ra288_decode_frame,
0eea212 @justinruggles Add avcodec_decode_audio4().
justinruggles authored
230 .capabilities = CODEC_CAP_DR1,
8671488 @DonDiego Use explicit struct initializers for AVCodec declarations.
DonDiego authored
231 .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
b8414bb RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, …
Nick Kurshev authored
232 };
Something went wrong with that request. Please try again.