some updates
[iv.d.git] / dopus / dopus.d
blobd7e140116a0dcfb81c90c6322c7864ff51b96795
1 /*
2 * Opus decoder/demuxer
3 * Copyright (c) 2012 Andrew D'Addesio
4 * Copyright (c) 2013-2014 Mozilla Corporation
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
22 module iv.dopus.dopus /*is aliced*/;
23 private:
24 import iv.alice;
26 //import iv.cmdcon;
27 nothrow @nogc {
29 //void conlog(Args...) (Args args) {}
32 alias FFTSample = float;
34 struct FFTComplex {
35 FFTSample re, im;
38 alias int8_t = byte;
39 alias uint8_t = ubyte;
40 alias int16_t = short;
41 alias uint16_t = ushort;
42 alias int32_t = int;
43 alias uint32_t = uint;
44 alias int64_t = long;
45 alias uint64_t = ulong;
47 enum AV_NOPTS_VALUE = cast(int64_t)0x8000000000000000UL;
50 T FFABS(T) (in T a) { pragma(inline, true); return (a < 0 ? -a : a); }
52 T FFMAX(T) (in T a, in T b) { pragma(inline, true); return (a > b ? a : b); }
53 T FFMIN(T) (in T a, in T b) { pragma(inline, true); return (a < b ? a : b); }
55 T FFMIN3(T) (in T a, in T b, in T c) { pragma(inline, true); return (a < b ? (a < c ? a : c) : (b < c ? b : c)); }
57 //T FFALIGN(T) (T x, T a) { pragma(inline, true); return (((x)+(a)-1)&~((a)-1)); }
58 //T FFALIGN(T) (T x, T a) { pragma(inline, true); return x; }
61 double ff_exp10 (double x) {
62 import std.math : exp2;
63 enum M_LOG2_10 = 3.32192809488736234787; /* log_2 10 */
64 return exp2(M_LOG2_10 * x);
68 static immutable ubyte[256] ff_log2_tab = [
69 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
70 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
71 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
72 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
73 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
74 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
75 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
76 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
79 alias av_log2 = ff_log2;
80 alias ff_log2 = ff_log2_c;
82 int ff_log2_c (uint v) nothrow @trusted @nogc {
83 int n = 0;
84 if (v & 0xffff0000) {
85 v >>= 16;
86 n += 16;
88 if (v & 0xff00) {
89 v >>= 8;
90 n += 8;
92 n += ff_log2_tab[v];
93 return n;
97 /**
98 * Clear high bits from an unsigned integer starting with specific bit position
99 * @param a value to clip
100 * @param p bit position to clip at
101 * @return clipped value
103 uint av_mod_uintp2 (uint a, uint p) pure nothrow @safe @nogc { pragma(inline, true); return a & ((1 << p) - 1); }
105 /* a*inverse[b]>>32 == a/b for all 0<=a<=16909558 && 2<=b<=256
106 * for a>16909558, is an overestimate by less than 1 part in 1<<24 */
107 static immutable uint[257] ff_inverse = [
108 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757,
109 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154,
110 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709,
111 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333,
112 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367,
113 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283,
114 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315,
115 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085,
116 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498,
117 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675,
118 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441,
119 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183,
120 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712,
121 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400,
122 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163,
123 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641,
124 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573,
125 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737,
126 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493,
127 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373,
128 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368,
129 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671,
130 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767,
131 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740,
132 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751,
133 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635,
134 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593,
135 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944,
136 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933,
137 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575,
138 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532,
139 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010,
140 16777216
144 static immutable ubyte[256] ff_sqrt_tab = [
145 0, 16, 23, 28, 32, 36, 40, 43, 46, 48, 51, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90,
146 91, 92, 94, 95, 96, 98, 99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
147 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,151,152,153,154,155,156,156,
148 157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,179,179,180,181,
149 182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202,
150 203,204,204,205,205,206,207,207,208,208,209,210,210,211,212,212,213,213,214,215,215,216,216,217,218,218,219,219,220,220,221,222,
151 222,223,223,224,224,225,226,226,227,227,228,228,229,230,230,231,231,232,232,233,233,234,235,235,236,236,237,237,238,238,239,239,
152 240,240,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,255
155 uint FASTDIV() (uint a, uint b) { pragma(inline, true); return (cast(uint)(((cast(ulong)a) * ff_inverse[b]) >> 32)); }
157 uint ff_sqrt (uint a) nothrow @safe @nogc {
158 uint b;
159 alias av_log2_16bit = av_log2;
161 if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4;
162 else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2;
163 //#if !CONFIG_SMALL
164 else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1;
165 else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8];
166 //#endif
167 else {
168 int s = av_log2_16bit(a >> 16) >> 1;
169 uint c = a >> (s + 2);
170 b = ff_sqrt_tab[c >> (s + 8)];
171 b = FASTDIV(c,b) + (b << s);
173 return b - (a < b * b);
177 * Clip a signed integer value into the amin-amax range.
178 * @param a value to clip
179 * @param amin minimum value of the clip range
180 * @param amax maximum value of the clip range
181 * @return clipped value
183 int av_clip (int a, int amin, int amax) pure nothrow @safe @nogc {
184 pragma(inline, true);
185 //if (a < amin) return amin; else if (a > amax) return amax; else return a;
186 return (a < amin ? amin : a > amax ? amax : a);
190 * Clip a signed integer to an unsigned power of two range.
191 * @param a value to clip
192 * @param p bit position to clip at
193 * @return clipped value
195 uint av_clip_uintp2 (int a, int p) pure nothrow @safe @nogc {
196 pragma(inline, true);
197 //if (a & ~((1<<p) - 1)) return -a >> 31 & ((1<<p) - 1); else return a;
198 return (a & ~((1<<p) - 1) ? -a >> 31 & ((1<<p) - 1) : a);
202 * Clip a signed integer value into the -32768,32767 range.
203 * @param a value to clip
204 * @return clipped value
206 short av_clip_int16 (int a) pure nothrow @safe @nogc {
207 pragma(inline, true);
208 return cast(short)((a+0x8000U) & ~0xFFFF ? (a>>31) ^ 0x7FFF : a);
212 * Clip a float value into the amin-amax range.
213 * @param a value to clip
214 * @param amin minimum value of the clip range
215 * @param amax maximum value of the clip range
216 * @return clipped value
218 float av_clipf (float a, float amin, float amax) pure nothrow @safe @nogc {
219 pragma(inline, true);
220 return (a < amin ? amin : a > amax ? amax : a);
224 // ////////////////////////////////////////////////////////////////////////// //
225 // dsp part
226 void vector_fmul_window (float* dst, const(float)* src0, const(float)* src1, const(float)* win, int len) {
227 int i, j;
228 dst += len;
229 win += len;
230 src0 += len;
231 for (i = -len, j = len-1; i < 0; ++i, --j) {
232 float s0 = src0[i];
233 float s1 = src1[j];
234 float wi = win[i];
235 float wj = win[j];
236 dst[i] = s0*wj-s1*wi;
237 dst[j] = s0*wi+s1*wj;
241 static void vector_fmac_scalar (float* dst, const(float)* src, float mul, int len) {
242 for (int i = 0; i < len; i++) dst[i] += src[i]*mul;
245 static void vector_fmul_scalar (float* dst, const(float)* src, float mul, int len) {
246 for (int i = 0; i < len; ++i) dst[i] = src[i]*mul;
250 enum {
251 EOK = 0,
252 EINVAL,
253 ENOMEM,
256 int AVERROR (int v) { return -v; }
258 enum AVERROR_INVALIDDATA = -EINVAL;
259 enum AVERROR_PATCHWELCOME = -EINVAL;
260 enum AVERROR_BUG = -EINVAL;
262 void av_free(T) (T* p) {
263 if (p !is null) {
264 import core.stdc.stdlib : free;
265 free(p);
270 void av_freep(T) (T** p) {
271 if (p !is null) {
272 if (*p !is null) {
273 import core.stdc.stdlib : free;
274 free(*p);
275 *p = null;
281 T* av_mallocz(T) (usize cnt=1) {
282 if (cnt == 0) return null;
283 import core.stdc.stdlib : calloc;
284 return cast(T*)calloc(cnt, T.sizeof);
287 alias av_malloc_array = av_mallocz;
288 alias av_mallocz_array = av_mallocz;
289 alias av_malloc = av_mallocz;
292 int av_reallocp_array(T) (T** ptr, usize cnt) {
293 import core.stdc.stdlib : free, realloc;
294 if (ptr is null) return -1;
295 if (cnt == 0) {
296 if (*ptr) free(*ptr);
297 *ptr = null;
298 } else {
299 auto np = realloc(*ptr, T.sizeof*cnt);
300 if (np is null) return -1;
301 *ptr = cast(T*)np;
303 return 0;
309 * Allocates a buffer, reusing the given one if large enough.
310 * Contrary to av_fast_realloc the current buffer contents might not be preserved and on error
311 * the old buffer is freed, thus no special handling to avoid memleaks is necessary.
313 void av_fast_malloc (void** ptr, int* size, uint min_size) {
314 static T FFMAX(T) (in T a, in T b) { pragma(inline, true); return (a > b ? a : b); }
315 void **p = ptr;
316 if (min_size < *size) return;
317 *size= FFMAX(17*min_size/16+32, min_size);
318 av_free(*p);
319 *p = av_malloc!ubyte(*size);
320 if (!*p) *size = 0;
324 struct AVAudioFifo {
325 //int fmt; // 8
326 uint chans;
327 float* buf;
328 uint rdpos;
329 uint used;
330 uint alloced;
333 int av_audio_fifo_size (AVAudioFifo* af) {
334 //{ import core.stdc.stdio : printf; printf("fifosize=%u\n", (af.used-af.rdpos)/af.chans); }
335 return (af !is null ? (af.used-af.rdpos)/af.chans : -1);
338 int av_audio_fifo_read (AVAudioFifo* af, void** data, int nb_samples) {
339 if (af is null) return -1;
340 //{ import core.stdc.stdio : printf; printf("fiforead=%u\n", nb_samples); }
341 auto dp = cast(float**)data;
342 int total;
343 while (nb_samples > 0) {
344 if (af.used-af.rdpos < af.chans) break;
345 foreach (immutable chn; 0..af.chans) *dp[chn]++ = af.buf[af.rdpos++];
346 ++total;
347 --nb_samples;
349 return total;
352 int av_audio_fifo_drain (AVAudioFifo* af, int nb_samples) {
353 if (af is null) return -1;
354 //{ import core.stdc.stdio : printf; printf("fifodrain=%u\n", nb_samples); }
355 while (nb_samples > 0) {
356 if (af.used-af.rdpos < af.chans) break;
357 af.rdpos += af.chans;
358 --nb_samples;
360 return 0;
363 int av_audio_fifo_write (AVAudioFifo* af, void** data, int nb_samples) {
364 import core.stdc.string : memmove;
365 { import core.stdc.stdio : printf; printf("fifowrite=%u\n", nb_samples); }
366 assert(0);
367 if (af is null || nb_samples < 0) return -1;
368 if (nb_samples == 0) return 0;
369 if (af.rdpos >= af.used) af.rdpos = af.used = 0;
370 if (af.rdpos > 0) {
371 memmove(af.buf, af.buf+af.rdpos, (af.used-af.rdpos)*float.sizeof);
372 af.used -= af.rdpos;
373 af.rdpos = 0;
375 if (af.used+nb_samples*af.chans > af.alloced) {
376 import core.stdc.stdlib : realloc;
377 uint newsz = af.used+nb_samples*af.chans;
378 auto nb = cast(float*)realloc(af.buf, newsz*float.sizeof);
379 if (nb is null) return -1;
380 af.buf = nb;
381 af.alloced = newsz;
383 auto dp = cast(float**)data;
384 int total;
385 while (nb_samples > 0) {
386 if (af.alloced-af.used < af.chans) assert(0);
387 foreach (immutable chn; 0..af.chans) af.buf[af.used++] = *dp[chn]++;
388 ++total;
389 --nb_samples;
391 return total;
394 AVAudioFifo* av_audio_fifo_alloc (int samplefmt, int channels, int nb_samples) {
395 if (samplefmt != 8) assert(0);
396 if (channels < 1 || channels > 255) assert(0);
397 if (nb_samples < 0) nb_samples = 0;
398 if (nb_samples > int.max/32) nb_samples = int.max/32;
399 AVAudioFifo* av = av_mallocz!AVAudioFifo(1);
400 if (av is null) return null;
401 av.chans = channels;
402 av.alloced = channels*nb_samples;
403 av.buf = av_mallocz!float(av.alloced);
404 if (av.buf is null) {
405 av_free(av);
406 return null;
408 av.rdpos = 0;
409 av.used = 0;
410 return av;
413 int av_audio_fifo_free (AVAudioFifo* af) {
414 if (af !is null) {
415 if (af.buf !is null) av_free(af.buf);
416 *af = AVAudioFifo.init;
417 av_free(af);
419 return 0;
423 struct AudioChannelMap {
424 int file_idx, stream_idx, channel_idx; // input
425 int ofile_idx, ostream_idx; // output
429 enum AV_CH_FRONT_LEFT = 0x00000001;
430 enum AV_CH_FRONT_RIGHT = 0x00000002;
431 enum AV_CH_FRONT_CENTER = 0x00000004;
432 enum AV_CH_LOW_FREQUENCY = 0x00000008;
433 enum AV_CH_BACK_LEFT = 0x00000010;
434 enum AV_CH_BACK_RIGHT = 0x00000020;
435 enum AV_CH_FRONT_LEFT_OF_CENTER = 0x00000040;
436 enum AV_CH_FRONT_RIGHT_OF_CENTER = 0x00000080;
437 enum AV_CH_BACK_CENTER = 0x00000100;
438 enum AV_CH_SIDE_LEFT = 0x00000200;
439 enum AV_CH_SIDE_RIGHT = 0x00000400;
440 enum AV_CH_TOP_CENTER = 0x00000800;
441 enum AV_CH_TOP_FRONT_LEFT = 0x00001000;
442 enum AV_CH_TOP_FRONT_CENTER = 0x00002000;
443 enum AV_CH_TOP_FRONT_RIGHT = 0x00004000;
444 enum AV_CH_TOP_BACK_LEFT = 0x00008000;
445 enum AV_CH_TOP_BACK_CENTER = 0x00010000;
446 enum AV_CH_TOP_BACK_RIGHT = 0x00020000;
447 enum AV_CH_STEREO_LEFT = 0x20000000; ///< Stereo downmix.
448 enum AV_CH_STEREO_RIGHT = 0x40000000; ///< See AV_CH_STEREO_LEFT.
449 enum AV_CH_WIDE_LEFT = 0x0000000080000000UL;
450 enum AV_CH_WIDE_RIGHT = 0x0000000100000000UL;
451 enum AV_CH_SURROUND_DIRECT_LEFT = 0x0000000200000000UL;
452 enum AV_CH_SURROUND_DIRECT_RIGHT = 0x0000000400000000UL;
453 enum AV_CH_LOW_FREQUENCY_2 = 0x0000000800000000UL;
455 /** Channel mask value used for AVCodecContext.request_channel_layout
456 to indicate that the user requests the channel order of the decoder output
457 to be the native codec channel order. */
458 enum AV_CH_LAYOUT_NATIVE = 0x8000000000000000UL;
461 * @}
462 * @defgroup channel_mask_c Audio channel layouts
463 * @{
464 * */
465 enum AV_CH_LAYOUT_MONO = (AV_CH_FRONT_CENTER);
466 enum AV_CH_LAYOUT_STEREO = (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT);
467 enum AV_CH_LAYOUT_2POINT1 = (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY);
468 enum AV_CH_LAYOUT_2_1 = (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER);
469 enum AV_CH_LAYOUT_SURROUND = (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER);
470 enum AV_CH_LAYOUT_3POINT1 = (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY);
471 enum AV_CH_LAYOUT_4POINT0 = (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER);
472 enum AV_CH_LAYOUT_4POINT1 = (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY);
473 enum AV_CH_LAYOUT_2_2 = (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT);
474 enum AV_CH_LAYOUT_QUAD = (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT);
475 enum AV_CH_LAYOUT_5POINT0 = (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT);
476 enum AV_CH_LAYOUT_5POINT1 = (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY);
477 enum AV_CH_LAYOUT_5POINT0_BACK = (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT);
478 enum AV_CH_LAYOUT_5POINT1_BACK = (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY);
479 enum AV_CH_LAYOUT_6POINT0 = (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER);
480 enum AV_CH_LAYOUT_6POINT0_FRONT = (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER);
481 enum AV_CH_LAYOUT_HEXAGONAL = (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER);
482 enum AV_CH_LAYOUT_6POINT1 = (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER);
483 enum AV_CH_LAYOUT_6POINT1_BACK = (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER);
484 enum AV_CH_LAYOUT_6POINT1_FRONT = (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY);
485 enum AV_CH_LAYOUT_7POINT0 = (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT);
486 enum AV_CH_LAYOUT_7POINT0_FRONT = (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER);
487 enum AV_CH_LAYOUT_7POINT1 = (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT);
488 enum AV_CH_LAYOUT_7POINT1_WIDE = (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER);
489 enum AV_CH_LAYOUT_7POINT1_WIDE_BACK = (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER);
490 enum AV_CH_LAYOUT_OCTAGONAL = (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT);
491 enum AV_CH_LAYOUT_HEXADECAGONAL = (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT);
492 enum AV_CH_LAYOUT_STEREO_DOWNMIX = (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT);
495 struct AVFrame {
497 * number of audio samples (per channel) described by this frame
499 int nb_samples;
501 * For video, size in bytes of each picture line.
502 * For audio, size in bytes of each plane.
504 * For audio, only linesize[0] may be set. For planar audio, each channel
505 * plane must be the same size.
507 * For video the linesizes should be multiples of the CPUs alignment
508 * preference, this is 16 or 32 for modern desktop CPUs.
509 * Some code requires such alignment other code can be slower without
510 * correct alignment, for yet other it makes no difference.
512 * @note The linesize may be larger than the size of usable data -- there
513 * may be extra padding present for performance reasons.
515 int[1/*AV_NUM_DATA_POINTERS*/] linesize;
517 * pointers to the data planes/channels.
519 * For video, this should simply point to data[].
521 * For planar audio, each channel has a separate data pointer, and
522 * linesize[0] contains the size of each channel buffer.
523 * For packed audio, there is just one data pointer, and linesize[0]
524 * contains the total size of the buffer for all channels.
526 * Note: Both data and extended_data should always be set in a valid frame,
527 * but for planar audio with more channels that can fit in data,
528 * extended_data must be used in order to access all channels.
530 ubyte** extended_data;
532 AudioChannelMap* audio_channel_maps; /* one info entry per -map_channel */
533 int nb_audio_channel_maps; /* number of (valid) -map_channel settings */
537 int ff_get_buffer (AVFrame* frame, int flags) {
538 return 0;
542 struct AVCtx {
543 int sample_fmt;
544 int sample_rate;
545 int channels;
546 ubyte* extradata;
547 uint extradata_size;
548 int delay;
549 ulong channel_layout;
550 //void* priv;
551 int preskip;
552 // oggopus_private
553 int need_comments;
554 int64_t cur_dts;
558 ushort AV_RL16 (const(void*) b) {
559 version(LittleEndian) {
560 return *cast(const(ushort)*)b;
561 } else {
562 static assert(0, "boo!");
567 struct AVPacket {
569 * A reference to the reference-counted buffer where the packet data is
570 * stored.
571 * May be NULL, then the packet data is not reference-counted.
573 //AVBufferRef *buf;
575 * Presentation timestamp in AVStream.time_base units; the time at which
576 * the decompressed packet will be presented to the user.
577 * Can be AV_NOPTS_VALUE if it is not stored in the file.
578 * pts MUST be larger or equal to dts as presentation cannot happen before
579 * decompression, unless one wants to view hex dumps. Some formats misuse
580 * the terms dts and pts/cts to mean something different. Such timestamps
581 * must be converted to true pts/dts before they are stored in AVPacket.
583 long pts;
585 * Decompression timestamp in AVStream.time_base units; the time at which
586 * the packet is decompressed.
587 * Can be AV_NOPTS_VALUE if it is not stored in the file.
589 long dts;
590 ubyte *data;
591 int size;
592 int stream_index;
594 * A combination of AV_PKT_FLAG values
596 int flags;
598 * Additional packet data that can be provided by the container.
599 * Packet can contain several types of side information.
601 //AVPacketSideData *side_data;
602 int side_data_elems;
605 * Duration of this packet in AVStream.time_base units, 0 if unknown.
606 * Equals next_pts - this_pts in presentation order.
608 long duration;
610 long pos; ///< byte position in stream, -1 if unknown
614 //__gshared Exception eobserr;
615 //shared static this () { eobserr = new Exception("out of bits in stream"); }
617 struct GetBitContext {
618 nothrow @nogc:
619 private:
620 const(ubyte)* buffer;
621 uint pos;
622 uint bytestotal;
623 ubyte curv;
624 ubyte bleft;
626 public:
627 int init_get_bits8 (const(void)* buf, uint bytelen) nothrow @trusted @nogc {
628 if (bytelen >= int.max/16) assert(0, "too big");
629 buffer = cast(const(ubyte)*)buf;
630 bytestotal = bytelen;
631 bleft = 0;
632 pos = 0;
633 return 0;
636 T get_bits(T=uint) (uint n) @trusted if (__traits(isIntegral, T)) {
637 if (n == 0 || n > 8) assert(0, "invalid number of bits requested");
638 T res = 0;
639 foreach_reverse (immutable shift; 0..n) {
640 if (bleft == 0) {
641 if (pos < bytestotal) {
642 curv = buffer[pos++];
643 } else {
644 curv = 0;
645 //throw eobserr;
647 bleft = 8;
649 if (curv&0x80) res |= (1U<<shift);
650 curv <<= 1;
651 --bleft;
653 return res;
658 static immutable uint64_t[9] ff_vorbis_channel_layouts = [
659 AV_CH_LAYOUT_MONO,
660 AV_CH_LAYOUT_STEREO,
661 2/*AV_CH_LAYOUT_SURROUND*/,
662 3/*AV_CH_LAYOUT_QUAD*/,
663 4/*AV_CH_LAYOUT_5POINT0_BACK*/,
664 5/*AV_CH_LAYOUT_5POINT1_BACK*/,
665 6/*AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER*/,
666 7/*AV_CH_LAYOUT_7POINT1*/,
670 static immutable uint8_t[8][8] ff_vorbis_channel_layout_offsets = [
671 [ 0 ],
672 [ 0, 1 ],
673 [ 0, 2, 1 ],
674 [ 0, 1, 2, 3 ],
675 [ 0, 2, 1, 3, 4 ],
676 [ 0, 2, 1, 5, 3, 4 ],
677 [ 0, 2, 1, 6, 5, 3, 4 ],
678 [ 0, 2, 1, 7, 5, 6, 3, 4 ],
682 enum M_SQRT1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
683 enum M_SQRT2 = 1.41421356237309504880; /* sqrt(2) */
686 enum MAX_FRAME_SIZE = 1275;
687 enum MAX_FRAMES = 48;
688 enum MAX_PACKET_DUR = 5760;
690 enum CELT_SHORT_BLOCKSIZE = 120;
691 enum CELT_OVERLAP = CELT_SHORT_BLOCKSIZE;
692 enum CELT_MAX_LOG_BLOCKS = 3;
693 enum CELT_MAX_FRAME_SIZE = (CELT_SHORT_BLOCKSIZE * (1 << CELT_MAX_LOG_BLOCKS));
694 enum CELT_MAX_BANDS = 21;
695 enum CELT_VECTORS = 11;
696 enum CELT_ALLOC_STEPS = 6;
697 enum CELT_FINE_OFFSET = 21;
698 enum CELT_MAX_FINE_BITS = 8;
699 enum CELT_NORM_SCALE = 16384;
700 enum CELT_QTHETA_OFFSET = 4;
701 enum CELT_QTHETA_OFFSET_TWOPHASE = 16;
702 enum CELT_DEEMPH_COEFF = 0.85000610f;
703 enum CELT_POSTFILTER_MINPERIOD = 15;
704 enum CELT_ENERGY_SILENCE = (-28.0f);
706 enum SILK_HISTORY = 322;
707 enum SILK_MAX_LPC = 16;
709 /* signed 16x16 . 32 multiply */
710 int MUL16() (int ra, int rb) { return ra*rb; }
711 long MUL64(T0, T1) (T0 a, T1 b) { return cast(int64_t)a * cast(int64_t)b; }
712 long ROUND_MULL() (int a, int b, int s) { return (((MUL64(a, b) >> ((s) - 1)) + 1) >> 1); }
713 int ROUND_MUL16() (int a, int b) { return ((MUL16(a, b) + 16384) >> 15); }
715 int opus_ilog (uint i) nothrow @trusted @nogc { pragma(inline, true); return av_log2(i)+!!i; }
717 int MULH() (int a, int b) { return cast(int)(MUL64(a, b) >> 32); }
718 long MULL(T0, T1, T2) (T0 a, T1 b, T2 s) { return (MUL64(a, b) >> (s)); }
721 enum OPUS_TS_HEADER = 0x7FE0; // 0x3ff (11 bits)
722 enum OPUS_TS_MASK = 0xFFE0; // top 11 bits
724 static immutable uint8_t[38] opus_default_extradata = [
725 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
726 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
730 alias OpusMode = int;
731 enum /*OpusMode*/:int {
732 OPUS_MODE_SILK,
733 OPUS_MODE_HYBRID,
734 OPUS_MODE_CELT
737 alias OpusBandwidth = int;
738 enum /*OpusBandwidth*/: int {
739 OPUS_BANDWIDTH_NARROWBAND,
740 OPUS_BANDWIDTH_MEDIUMBAND,
741 OPUS_BANDWIDTH_WIDEBAND,
742 OPUS_BANDWIDTH_SUPERWIDEBAND,
743 OPUS_BANDWIDTH_FULLBAND
746 struct RawBitsContext {
747 const(uint8_t)* position;
748 uint bytes;
749 uint cachelen;
750 uint cacheval;
753 struct OpusRangeCoder {
754 GetBitContext gb;
755 RawBitsContext rb;
756 uint range;
757 uint value;
758 uint total_read_bits;
761 struct OpusPacket {
762 int packet_size; /**< packet size */
763 int data_size; /**< size of the useful data -- packet size - padding */
764 int code; /**< packet code: specifies the frame layout */
765 int stereo; /**< whether this packet is mono or stereo */
766 int vbr; /**< vbr flag */
767 int config; /**< configuration: tells the audio mode,
768 ** bandwidth, and frame duration */
769 int frame_count; /**< frame count */
770 int[MAX_FRAMES] frame_offset; /**< frame offsets */
771 int[MAX_FRAMES] frame_size; /**< frame sizes */
772 int frame_duration; /**< frame duration, in samples @ 48kHz */
773 OpusMode mode; /**< mode */
774 OpusBandwidth bandwidth; /**< bandwidth */
777 struct OpusStreamContext {
778 //AVCodecContext *avctx;
779 //AVCtx* avctx;
780 int output_channels;
782 OpusRangeCoder rc;
783 OpusRangeCoder redundancy_rc;
784 SilkContext *silk;
785 CeltContext *celt;
786 //AVFloatDSPContext *fdsp;
788 float[960][2] silk_buf;
789 float*[2] silk_output;
790 //DECLARE_ALIGNED(32, float, celt_buf)[2][960];
791 float[960][2] celt_buf;
792 float*[2] celt_output;
794 float[960][2] redundancy_buf;
795 float*[2] redundancy_output;
797 /* data buffers for the final output data */
798 float*[2] out_;
799 int out_size;
801 float *out_dummy;
802 int out_dummy_allocated_size;
804 //SwrContext *swr;
805 OpusResampler flr;
806 AVAudioFifo *celt_delay;
807 int silk_samplerate;
808 /* number of samples we still want to get from the resampler */
809 int delayed_samples;
811 OpusPacket packet;
813 int redundancy_idx;
816 // a mapping between an opus stream and an output channel
817 struct ChannelMap {
818 int stream_idx;
819 int channel_idx;
821 // when a single decoded channel is mapped to multiple output channels, we
822 // write to the first output directly and copy from it to the others
823 // this field is set to 1 for those copied output channels
824 int copy;
825 // this is the index of the output channel to copy from
826 int copy_idx;
828 // this channel is silent
829 int silence;
832 struct OpusContext {
833 OpusStreamContext *streams;
835 int in_channels;
837 /* current output buffers for each streams */
838 float **out_;
839 int *out_size;
840 /* Buffers for synchronizing the streams when they have different resampling delays */
841 AVAudioFifo **sync_buffers;
842 /* number of decoded samples for each stream */
843 int *decoded_samples;
845 int nb_streams;
846 int nb_stereo_streams;
848 //AVFloatDSPContext *fdsp;
849 int16_t gain_i;
850 float gain;
852 ChannelMap *channel_maps;
855 /*static av_always_inline*/ void opus_rc_normalize(OpusRangeCoder *rc)
857 while (rc.range <= 1<<23) {
858 ubyte b = cast(ubyte)rc.gb.get_bits(8)^0xFF;
859 //conwritefln!"b=0x%02x"(b);
860 //rc.value = ((rc.value << 8) | (rc.gb.get_bits(8) ^ 0xFF)) & ((1u << 31) - 1);
861 rc.value = ((rc.value << 8) | b) & ((1u << 31) - 1);
862 rc.range <<= 8;
863 rc.total_read_bits += 8;
867 /*If the range is too small, rescale it and input some bits.*/
868 while(_this->rng<=EC_CODE_BOT){
869 int sym;
870 _this->nbits_total+=EC_SYM_BITS;
871 _this->rng<<=EC_SYM_BITS;
872 /*Use up the remaining bits from our last symbol.*/
873 sym=_this->rem;
874 /*Read the next value from the input.*/
875 _this->rem=ec_read_byte(_this);
876 /*Take the rest of the bits we need from this new symbol.*/
877 sym=(sym<<EC_SYM_BITS|_this->rem)>>(EC_SYM_BITS-EC_CODE_EXTRA);
879 sym=(sym<<8|_this->rem)>>1;
881 /*And subtract them from val, capped to be less than EC_CODE_TOP.*/
882 _this->val=((_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym))&(EC_CODE_TOP-1);
887 /*static av_always_inline*/ void opus_rc_update(OpusRangeCoder *rc, uint scale,
888 uint low, uint high,
889 uint total)
891 rc.value -= scale * (total - high);
892 rc.range = low ? scale * (high - low)
893 : rc.range - scale * (total - high);
894 opus_rc_normalize(rc);
897 /*static av_always_inline*/ uint opus_rc_getsymbol(OpusRangeCoder *rc, const(uint16_t)*cdf)
899 uint k, scale, total, symbol, low, high;
901 total = *cdf++;
903 scale = rc.range / total;
904 symbol = rc.value / scale + 1;
905 symbol = total - FFMIN(symbol, total);
907 for (k = 0; cdf[k] <= symbol; k++) {}
908 high = cdf[k];
909 low = k ? cdf[k-1] : 0;
911 opus_rc_update(rc, scale, low, high, total);
913 return k;
916 /*static av_always_inline*/ uint opus_rc_p2model(OpusRangeCoder *rc, uint bits)
918 uint k, scale;
919 scale = rc.range >> bits; // in this case, scale = symbol
921 if (rc.value >= scale) {
922 rc.value -= scale;
923 rc.range -= scale;
924 k = 0;
925 } else {
926 rc.range = scale;
927 k = 1;
929 opus_rc_normalize(rc);
930 return k;
934 * CELT: estimate bits of entropy that have thus far been consumed for the
935 * current CELT frame, to integer and fractional (1/8th bit) precision
937 /*static av_always_inline*/ uint opus_rc_tell(const OpusRangeCoder *rc)
939 return rc.total_read_bits - av_log2(rc.range) - 1;
942 /*static av_always_inline*/ uint opus_rc_tell_frac(const OpusRangeCoder *rc)
944 uint i, total_bits, rcbuffer, range;
946 total_bits = rc.total_read_bits << 3;
947 rcbuffer = av_log2(rc.range) + 1;
948 range = rc.range >> (rcbuffer-16);
950 for (i = 0; i < 3; i++) {
951 int bit;
952 range = range * range >> 15;
953 bit = range >> 16;
954 rcbuffer = rcbuffer << 1 | bit;
955 range >>= bit;
958 return total_bits - rcbuffer;
962 * CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise
964 /*static av_always_inline*/ uint opus_getrawbits(OpusRangeCoder *rc, uint count)
966 uint value = 0;
968 while (rc.rb.bytes && rc.rb.cachelen < count) {
969 rc.rb.cacheval |= *--rc.rb.position << rc.rb.cachelen;
970 rc.rb.cachelen += 8;
971 rc.rb.bytes--;
974 value = av_mod_uintp2(rc.rb.cacheval, count);
975 rc.rb.cacheval >>= count;
976 rc.rb.cachelen -= count;
977 rc.total_read_bits += count;
979 return value;
983 * CELT: read a uniform distribution
985 /*static av_always_inline*/ uint opus_rc_unimodel(OpusRangeCoder *rc, uint size)
987 uint bits, k, scale, total;
989 bits = opus_ilog(size - 1);
990 total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size;
992 scale = rc.range / total;
993 k = rc.value / scale + 1;
994 k = total - FFMIN(k, total);
995 opus_rc_update(rc, scale, k, k + 1, total);
997 if (bits > 8) {
998 k = k << (bits - 8) | opus_getrawbits(rc, bits - 8);
999 return FFMIN(k, size - 1);
1000 } else
1001 return k;
1004 /*static av_always_inline*/ int opus_rc_laplace(OpusRangeCoder *rc, uint symbol, int decay)
1006 /* extends the range coder to model a Laplace distribution */
1007 int value = 0;
1008 uint scale, low = 0, center;
1010 scale = rc.range >> 15;
1011 center = rc.value / scale + 1;
1012 center = (1 << 15) - FFMIN(center, 1 << 15);
1014 if (center >= symbol) {
1015 value++;
1016 low = symbol;
1017 symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15);
1019 while (symbol > 1 && center >= low + 2 * symbol) {
1020 value++;
1021 symbol *= 2;
1022 low += symbol;
1023 symbol = (((symbol - 2) * decay) >> 15) + 1;
1026 if (symbol <= 1) {
1027 int distance = (center - low) >> 1;
1028 value += distance;
1029 low += 2 * distance;
1032 if (center < low + symbol)
1033 value *= -1;
1034 else
1035 low += symbol;
1038 opus_rc_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768);
1040 return value;
1043 /*static av_always_inline*/ uint opus_rc_stepmodel(OpusRangeCoder *rc, int k0)
1045 /* Use a probability of 3 up to itheta=8192 and then use 1 after */
1046 uint k, scale, symbol, total = (k0+1)*3 + k0;
1047 scale = rc.range / total;
1048 symbol = rc.value / scale + 1;
1049 symbol = total - FFMIN(symbol, total);
1051 k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2;
1053 opus_rc_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1),
1054 (k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total);
1055 return k;
1058 /*static av_always_inline*/ uint opus_rc_trimodel(OpusRangeCoder *rc, int qn)
1060 uint k, scale, symbol, total, low, center;
1062 total = ((qn>>1) + 1) * ((qn>>1) + 1);
1063 scale = rc.range / total;
1064 center = rc.value / scale + 1;
1065 center = total - FFMIN(center, total);
1067 if (center < total >> 1) {
1068 k = (ff_sqrt(8 * center + 1) - 1) >> 1;
1069 low = k * (k + 1) >> 1;
1070 symbol = k + 1;
1071 } else {
1072 k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1;
1073 low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
1074 symbol = qn + 1 - k;
1077 opus_rc_update(rc, scale, low, low + symbol, total);
1079 return k;
1083 static immutable uint16_t[32] opus_frame_duration = [
1084 480, 960, 1920, 2880,
1085 480, 960, 1920, 2880,
1086 480, 960, 1920, 2880,
1087 480, 960,
1088 480, 960,
1089 120, 240, 480, 960,
1090 120, 240, 480, 960,
1091 120, 240, 480, 960,
1092 120, 240, 480, 960,
1096 * Read a 1- or 2-byte frame length
1098 int xiph_lacing_16bit (const(uint8_t)** ptr, const(uint8_t)* end) {
1099 int val;
1100 if (*ptr >= end) return AVERROR_INVALIDDATA;
1101 val = *(*ptr)++;
1102 if (val >= 252) {
1103 if (*ptr >= end) return AVERROR_INVALIDDATA;
1104 val += 4 * *(*ptr)++;
1106 return val;
1110 * Read a multi-byte length (used for code 3 packet padding size)
1112 int xiph_lacing_full (const(uint8_t)** ptr, const(uint8_t)* end) {
1113 int val = 0;
1114 int next;
1115 for (;;) {
1116 if (*ptr >= end || val > int.max-254) return AVERROR_INVALIDDATA;
1117 next = *(*ptr)++;
1118 val += next;
1119 if (next < 255) break; else --val;
1121 return val;
1125 * Parse Opus packet info from raw packet data
1127 int ff_opus_parse_packet (OpusPacket* pkt, const(uint8_t)* buf, int buf_size, bool self_delimiting) {
1128 import core.stdc.string : memset;
1130 const(uint8_t)* ptr = buf;
1131 const(uint8_t)* end = buf+buf_size;
1132 int padding = 0;
1133 int frame_bytes, i;
1134 //conwriteln("frame packet size=", buf_size);
1136 if (buf_size < 1) goto fail;
1138 // TOC byte
1139 i = *ptr++;
1140 pkt.code = (i )&0x3;
1141 pkt.stereo = (i>>2)&0x1;
1142 pkt.config = (i>>3)&0x1F;
1144 // code 2 and code 3 packets have at least 1 byte after the TOC
1145 if (pkt.code >= 2 && buf_size < 2) goto fail;
1147 //conwriteln("packet code: ", pkt.code);
1148 final switch (pkt.code) {
1149 case 0:
1150 // 1 frame
1151 pkt.frame_count = 1;
1152 pkt.vbr = 0;
1154 if (self_delimiting) {
1155 int len = xiph_lacing_16bit(&ptr, end);
1156 if (len < 0 || len > end-ptr) goto fail;
1157 end = ptr+len;
1158 buf_size = cast(int)(end-buf);
1161 frame_bytes = cast(int)(end-ptr);
1162 if (frame_bytes > MAX_FRAME_SIZE) goto fail;
1163 pkt.frame_offset[0] = cast(int)(ptr-buf);
1164 pkt.frame_size[0] = frame_bytes;
1165 break;
1166 case 1:
1167 // 2 frames, equal size
1168 pkt.frame_count = 2;
1169 pkt.vbr = 0;
1171 if (self_delimiting) {
1172 int len = xiph_lacing_16bit(&ptr, end);
1173 if (len < 0 || 2 * len > end-ptr) goto fail;
1174 end = ptr+2*len;
1175 buf_size = cast(int)(end-buf);
1178 frame_bytes = cast(int)(end-ptr);
1179 if ((frame_bytes&1) != 0 || (frame_bytes>>1) > MAX_FRAME_SIZE) goto fail;
1180 pkt.frame_offset[0] = cast(int)(ptr-buf);
1181 pkt.frame_size[0] = frame_bytes>>1;
1182 pkt.frame_offset[1] = pkt.frame_offset[0]+pkt.frame_size[0];
1183 pkt.frame_size[1] = frame_bytes>>1;
1184 break;
1185 case 2:
1186 // 2 frames, different sizes
1187 pkt.frame_count = 2;
1188 pkt.vbr = 1;
1190 // read 1st frame size
1191 frame_bytes = xiph_lacing_16bit(&ptr, end);
1192 if (frame_bytes < 0) goto fail;
1194 if (self_delimiting) {
1195 int len = xiph_lacing_16bit(&ptr, end);
1196 if (len < 0 || len+frame_bytes > end-ptr) goto fail;
1197 end = ptr+frame_bytes+len;
1198 buf_size = cast(int)(end-buf);
1201 pkt.frame_offset[0] = cast(int)(ptr-buf);
1202 pkt.frame_size[0] = frame_bytes;
1204 // calculate 2nd frame size
1205 frame_bytes = cast(int)(end-ptr-pkt.frame_size[0]);
1206 if (frame_bytes < 0 || frame_bytes > MAX_FRAME_SIZE) goto fail;
1207 pkt.frame_offset[1] = pkt.frame_offset[0]+pkt.frame_size[0];
1208 pkt.frame_size[1] = frame_bytes;
1209 break;
1210 case 3:
1211 // 1 to 48 frames, can be different sizes
1212 i = *ptr++;
1213 pkt.frame_count = (i )&0x3F;
1214 padding = (i>>6)&0x01;
1215 pkt.vbr = (i>>7)&0x01;
1216 //conwriteln(" frc=", pkt.frame_count, "; padding=", padding, "; vbr=", pkt.vbr);
1218 if (pkt.frame_count == 0 || pkt.frame_count > MAX_FRAMES) goto fail;
1220 // read padding size
1221 if (padding) {
1222 padding = xiph_lacing_full(&ptr, end);
1223 if (padding < 0) goto fail;
1224 //conwriteln(" real padding=", padding);
1227 // read frame sizes
1228 if (pkt.vbr) {
1229 // for VBR, all frames except the final one have their size coded in the bitstream. the last frame size is implicit
1230 int total_bytes = 0;
1231 for (i = 0; i < pkt.frame_count-1; i++) {
1232 frame_bytes = xiph_lacing_16bit(&ptr, end);
1233 if (frame_bytes < 0) goto fail;
1234 pkt.frame_size[i] = frame_bytes;
1235 total_bytes += frame_bytes;
1238 if (self_delimiting) {
1239 int len = xiph_lacing_16bit(&ptr, end);
1240 if (len < 0 || len+total_bytes+padding > end-ptr) goto fail;
1241 end = ptr+total_bytes+len+padding;
1242 buf_size = cast(int)(end-buf);
1245 frame_bytes = cast(int)(end-ptr-padding);
1246 if (total_bytes > frame_bytes) goto fail;
1247 pkt.frame_offset[0] = cast(int)(ptr-buf);
1248 for (i = 1; i < pkt.frame_count; i++) pkt.frame_offset[i] = pkt.frame_offset[i-1]+pkt.frame_size[i-1];
1249 pkt.frame_size[pkt.frame_count-1] = frame_bytes-total_bytes;
1250 } else {
1251 // for CBR, the remaining packet bytes are divided evenly between the frames
1252 if (self_delimiting) {
1253 frame_bytes = xiph_lacing_16bit(&ptr, end);
1254 //conwriteln("frame_bytes=", frame_bytes);
1255 if (frame_bytes < 0 || pkt.frame_count*frame_bytes+padding > end-ptr) goto fail;
1256 end = ptr+pkt.frame_count*frame_bytes+padding;
1257 buf_size = cast(int)(end-buf);
1258 } else {
1259 frame_bytes = cast(int)(end-ptr-padding);
1260 //conwriteln("frame_bytes=", frame_bytes);
1261 if (frame_bytes % pkt.frame_count || frame_bytes/pkt.frame_count > MAX_FRAME_SIZE) goto fail;
1262 frame_bytes /= pkt.frame_count;
1265 pkt.frame_offset[0] = cast(int)(ptr-buf);
1266 pkt.frame_size[0] = frame_bytes;
1267 for (i = 1; i < pkt.frame_count; i++) {
1268 pkt.frame_offset[i] = pkt.frame_offset[i-1]+pkt.frame_size[i-1];
1269 pkt.frame_size[i] = frame_bytes;
1272 break;
1275 pkt.packet_size = buf_size;
1276 pkt.data_size = pkt.packet_size-padding;
1278 // total packet duration cannot be larger than 120ms
1279 pkt.frame_duration = opus_frame_duration[pkt.config];
1280 if (pkt.frame_duration*pkt.frame_count > MAX_PACKET_DUR) goto fail;
1282 // set mode and bandwidth
1283 if (pkt.config < 12) {
1284 pkt.mode = OPUS_MODE_SILK;
1285 pkt.bandwidth = pkt.config>>2;
1286 //conwriteln("SILK: ", pkt.bandwidth);
1287 } else if (pkt.config < 16) {
1288 pkt.mode = OPUS_MODE_HYBRID;
1289 pkt.bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND+(pkt.config >= 14 ? 1 : 0);
1290 //conwriteln("HYB: ", pkt.bandwidth);
1291 } else {
1292 pkt.mode = OPUS_MODE_CELT;
1293 pkt.bandwidth = (pkt.config-16)>>2;
1294 // skip medium band
1295 if (pkt.bandwidth) ++pkt.bandwidth;
1296 //conwriteln("CELT: ", pkt.bandwidth);
1299 return 0;
1301 fail:
1302 memset(pkt, 0, (*pkt).sizeof);
1303 return AVERROR_INVALIDDATA;
1306 static int channel_reorder_vorbis(int nb_channels, int channel_idx)
1308 return ff_vorbis_channel_layout_offsets[nb_channels - 1][channel_idx];
1311 static int channel_reorder_unknown(int nb_channels, int channel_idx)
1313 return channel_idx;
1317 int ff_opus_parse_extradata (AVCtx* avctx, OpusContext* s, short cmtgain) {
1318 static immutable ubyte[2] default_channel_map = [ 0, 1 ];
1320 int function (int, int) nothrow @nogc channel_reorder = &channel_reorder_unknown;
1322 const(uint8_t)* extradata, channel_map;
1323 int extradata_size;
1324 int ver, channels, map_type, streams, stereo_streams, i, j;
1325 uint64_t layout;
1327 if (!avctx.extradata) {
1328 if (avctx.channels > 2) {
1329 //conlog("Multichannel configuration without extradata.");
1330 return AVERROR(EINVAL);
1332 extradata = opus_default_extradata.ptr;
1333 extradata_size = cast(uint)opus_default_extradata.length;
1334 } else {
1335 extradata = avctx.extradata;
1336 extradata_size = avctx.extradata_size;
1339 if (extradata_size < 19) {
1340 //conlog("Invalid extradata size: ", extradata_size);
1341 return AVERROR_INVALIDDATA;
1344 ver = extradata[8];
1345 if (ver > 15) {
1346 //conlog("Extradata version ", ver);
1347 return AVERROR_PATCHWELCOME;
1350 avctx.delay = AV_RL16(extradata + 10);
1352 channels = avctx.extradata ? extradata[9] : (avctx.channels == 1) ? 1 : 2;
1353 if (!channels) {
1354 //conlog("Zero channel count specified in the extradata");
1355 return AVERROR_INVALIDDATA;
1358 int ii = AV_RL16(extradata + 16);
1359 ii += cmtgain;
1360 if (ii < short.min) ii = short.min; else if (ii > short.max) ii = short.max;
1362 s.gain_i = cast(short)ii;
1363 if (s.gain_i) s.gain = ff_exp10(s.gain_i / (20.0 * 256));
1365 map_type = extradata[18];
1366 if (!map_type) {
1367 if (channels > 2) {
1368 //conlog("Channel mapping 0 is only specified for up to 2 channels");
1369 return AVERROR_INVALIDDATA;
1371 layout = (channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
1372 streams = 1;
1373 stereo_streams = channels - 1;
1374 channel_map = default_channel_map.ptr;
1375 } else if (map_type == 1 || map_type == 2 || map_type == 255) {
1376 if (extradata_size < 21 + channels) {
1377 //conlog("Invalid extradata size: ", extradata_size);
1378 return AVERROR_INVALIDDATA;
1381 streams = extradata[19];
1382 stereo_streams = extradata[20];
1383 if (!streams || stereo_streams > streams || streams + stereo_streams > 255) {
1384 //conlog("Invalid stream/stereo stream count: ", streams, "/", stereo_streams);
1385 return AVERROR_INVALIDDATA;
1388 if (map_type == 1) {
1389 if (channels > 8) {
1390 //conlog("Channel mapping 1 is only specified for up to 8 channels");
1391 return AVERROR_INVALIDDATA;
1393 layout = ff_vorbis_channel_layouts[channels - 1];
1394 //!channel_reorder = channel_reorder_vorbis;
1395 } else if (map_type == 2) {
1396 int ambisonic_order = ff_sqrt(channels) - 1;
1397 if (channels != (ambisonic_order + 1) * (ambisonic_order + 1)) {
1398 //conlog("Channel mapping 2 is only specified for channel counts which can be written as (n + 1)^2 for nonnegative integer n");
1399 return AVERROR_INVALIDDATA;
1401 layout = 0;
1402 } else {
1403 layout = 0;
1406 channel_map = extradata + 21;
1407 } else {
1408 //conlog("Mapping type ", map_type);
1409 return AVERROR_PATCHWELCOME;
1412 s.channel_maps = av_mallocz_array!(typeof(s.channel_maps[0]))(channels);
1413 if (s.channel_maps is null) return AVERROR(ENOMEM);
1415 for (i = 0; i < channels; i++) {
1416 ChannelMap* map = &s.channel_maps[i];
1417 uint8_t idx = channel_map[channel_reorder(channels, i)];
1419 if (idx == 255) {
1420 map.silence = 1;
1421 continue;
1422 } else if (idx >= streams + stereo_streams) {
1423 //conlog("Invalid channel map for output channel ", i, ": ", idx);
1424 return AVERROR_INVALIDDATA;
1427 // check that we did not see this index yet
1428 map.copy = 0;
1429 for (j = 0; j < i; j++) {
1430 if (channel_map[channel_reorder(channels, j)] == idx) {
1431 map.copy = 1;
1432 map.copy_idx = j;
1433 break;
1437 if (idx < 2*stereo_streams) {
1438 map.stream_idx = idx/2;
1439 map.channel_idx = idx&1;
1440 } else {
1441 map.stream_idx = idx-stereo_streams;
1442 map.channel_idx = 0;
1446 avctx.channels = channels;
1447 avctx.channel_layout = layout;
1448 s.nb_streams = streams;
1449 s.nb_stereo_streams = stereo_streams;
1451 return 0;
1455 struct IMDCT15Context {
1456 int fft_n;
1457 int len2;
1458 int len4;
1460 FFTComplex* tmp;
1462 FFTComplex* twiddle_exptab;
1464 FFTComplex*[6] exptab;
1467 * Calculate the middle half of the iMDCT
1469 void function (IMDCT15Context* s, float* dst, const(float)* src, ptrdiff_t src_stride, float scale) nothrow @nogc imdct_half;
1473 // minimal iMDCT size to make SIMD opts easier
1474 enum CELT_MIN_IMDCT_SIZE = 120;
1476 // complex c = a * b
1477 enum CMUL3(string cre, string cim, string are, string aim, string bre, string bim) =
1478 ""~cre~" = "~are~" * "~bre~" - "~aim~" * "~bim~";\n"~
1479 ""~cim~" = "~are~" * "~bim~" + "~aim~" * "~bre~";\n";
1481 enum CMUL(string c, string a, string b) = CMUL3!("("~c~").re", "("~c~").im", "("~a~").re", "("~a~").im", "("~b~").re", "("~b~").im");
1483 // complex c = a * b
1484 // d = a * conjugate(b)
1485 enum CMUL2(string c, string d, string a, string b) =
1486 "{\n"~
1487 "float are = ("~a~").re;\n"~
1488 "float aim = ("~a~").im;\n"~
1489 "float bre = ("~b~").re;\n"~
1490 "float bim = ("~b~").im;\n"~
1491 "float rr = are * bre;\n"~
1492 "float ri = are * bim;\n"~
1493 "float ir = aim * bre;\n"~
1494 "float ii = aim * bim;\n"~
1495 "("~c~").re = rr - ii;\n"~
1496 "("~c~").im = ri + ir;\n"~
1497 "("~d~").re = rr + ii;\n"~
1498 "("~d~").im = -ri + ir;\n"~
1499 "}\n";
1501 /*av_cold*/ void ff_imdct15_uninit (IMDCT15Context** ps) {
1502 IMDCT15Context* s = *ps;
1503 if (s is null) return;
1504 for (int i = 0; i < /*FF_ARRAY_ELEMS*/cast(int)s.exptab.length; ++i) av_freep(&s.exptab[i]);
1505 av_freep(&s.twiddle_exptab);
1506 av_freep(&s.tmp);
1507 av_freep(ps);
1510 //static void imdct15_half (IMDCT15Context* s, float* dst, const(float)* src, ptrdiff_t stride, float scale);
1512 /*av_cold*/ int ff_imdct15_init (IMDCT15Context** ps, int N) {
1513 import std.math : cos, sin, PI;
1515 IMDCT15Context* s;
1516 int len2 = 15*(1<<N);
1517 int len = 2*len2;
1518 int i, j;
1520 if (len2 > CELT_MAX_FRAME_SIZE || len2 < CELT_MIN_IMDCT_SIZE) return AVERROR(EINVAL);
1522 s = av_mallocz!IMDCT15Context();
1523 if (!s) return AVERROR(ENOMEM);
1525 s.fft_n = N - 1;
1526 s.len4 = len2 / 2;
1527 s.len2 = len2;
1529 s.tmp = av_malloc_array!(typeof(*s.tmp))(len);
1530 if (!s.tmp) goto fail;
1532 s.twiddle_exptab = av_malloc_array!(typeof(*s.twiddle_exptab))(s.len4);
1533 if (!s.twiddle_exptab) goto fail;
1535 for (i = 0; i < s.len4; i++) {
1536 s.twiddle_exptab[i].re = cos(2 * PI * (i + 0.125 + s.len4) / len);
1537 s.twiddle_exptab[i].im = sin(2 * PI * (i + 0.125 + s.len4) / len);
1540 for (i = 0; i < /*FF_ARRAY_ELEMS*/cast(int)s.exptab.length; i++) {
1541 int NN = 15 * (1 << i);
1542 s.exptab[i] = av_malloc!(typeof(*s.exptab[i]))(FFMAX(NN, 19));
1543 if (!s.exptab[i]) goto fail;
1544 for (j = 0; j < NN; j++) {
1545 s.exptab[i][j].re = cos(2 * PI * j / NN);
1546 s.exptab[i][j].im = sin(2 * PI * j / NN);
1550 // wrap around to simplify fft15
1551 for (j = 15; j < 19; j++) s.exptab[0][j] = s.exptab[0][j - 15];
1553 s.imdct_half = &imdct15_half;
1555 //if (ARCH_AARCH64) ff_imdct15_init_aarch64(s);
1557 *ps = s;
1559 return 0;
1561 fail:
1562 ff_imdct15_uninit(&s);
1563 return AVERROR(ENOMEM);
1567 private void fft5(FFTComplex* out_, const(FFTComplex)* in_, ptrdiff_t stride) {
1568 // [0] = exp(2 * i * pi / 5), [1] = exp(2 * i * pi * 2 / 5)
1569 static immutable FFTComplex[2] fact = [ { 0.30901699437494745, 0.95105651629515353 },
1570 { -0.80901699437494734, 0.58778525229247325 } ];
1572 FFTComplex[4][4] z;
1574 mixin(CMUL2!("z[0][0]", "z[0][3]", "in_[1 * stride]", "fact[0]"));
1575 mixin(CMUL2!("z[0][1]", "z[0][2]", "in_[1 * stride]", "fact[1]"));
1576 mixin(CMUL2!("z[1][0]", "z[1][3]", "in_[2 * stride]", "fact[0]"));
1577 mixin(CMUL2!("z[1][1]", "z[1][2]", "in_[2 * stride]", "fact[1]"));
1578 mixin(CMUL2!("z[2][0]", "z[2][3]", "in_[3 * stride]", "fact[0]"));
1579 mixin(CMUL2!("z[2][1]", "z[2][2]", "in_[3 * stride]", "fact[1]"));
1580 mixin(CMUL2!("z[3][0]", "z[3][3]", "in_[4 * stride]", "fact[0]"));
1581 mixin(CMUL2!("z[3][1]", "z[3][2]", "in_[4 * stride]", "fact[1]"));
1583 out_[0].re = in_[0].re + in_[stride].re + in_[2 * stride].re + in_[3 * stride].re + in_[4 * stride].re;
1584 out_[0].im = in_[0].im + in_[stride].im + in_[2 * stride].im + in_[3 * stride].im + in_[4 * stride].im;
1586 out_[1].re = in_[0].re + z[0][0].re + z[1][1].re + z[2][2].re + z[3][3].re;
1587 out_[1].im = in_[0].im + z[0][0].im + z[1][1].im + z[2][2].im + z[3][3].im;
1589 out_[2].re = in_[0].re + z[0][1].re + z[1][3].re + z[2][0].re + z[3][2].re;
1590 out_[2].im = in_[0].im + z[0][1].im + z[1][3].im + z[2][0].im + z[3][2].im;
1592 out_[3].re = in_[0].re + z[0][2].re + z[1][0].re + z[2][3].re + z[3][1].re;
1593 out_[3].im = in_[0].im + z[0][2].im + z[1][0].im + z[2][3].im + z[3][1].im;
1595 out_[4].re = in_[0].re + z[0][3].re + z[1][2].re + z[2][1].re + z[3][0].re;
1596 out_[4].im = in_[0].im + z[0][3].im + z[1][2].im + z[2][1].im + z[3][0].im;
1599 private void fft15 (IMDCT15Context* s, FFTComplex* out_, const(FFTComplex)* in_, ptrdiff_t stride) {
1600 const(FFTComplex)* exptab = s.exptab[0];
1601 FFTComplex[5] tmp;
1602 FFTComplex[5] tmp1;
1603 FFTComplex[5] tmp2;
1604 int k;
1606 fft5(tmp.ptr, in_, stride * 3);
1607 fft5(tmp1.ptr, in_ + stride, stride * 3);
1608 fft5(tmp2.ptr, in_ + 2 * stride, stride * 3);
1610 for (k = 0; k < 5; k++) {
1611 FFTComplex t1, t2;
1613 mixin(CMUL!("t1", "tmp1[k]", "exptab[k]"));
1614 mixin(CMUL!("t2", "tmp2[k]", "exptab[2 * k]"));
1615 out_[k].re = tmp[k].re + t1.re + t2.re;
1616 out_[k].im = tmp[k].im + t1.im + t2.im;
1618 mixin(CMUL!("t1", "tmp1[k]", "exptab[k + 5]"));
1619 mixin(CMUL!("t2", "tmp2[k]", "exptab[2 * (k + 5)]"));
1620 out_[k + 5].re = tmp[k].re + t1.re + t2.re;
1621 out_[k + 5].im = tmp[k].im + t1.im + t2.im;
1623 mixin(CMUL!("t1", "tmp1[k]", "exptab[k + 10]"));
1624 mixin(CMUL!("t2", "tmp2[k]", "exptab[2 * k + 5]"));
1625 out_[k + 10].re = tmp[k].re + t1.re + t2.re;
1626 out_[k + 10].im = tmp[k].im + t1.im + t2.im;
1631 * FFT of the length 15 * (2^N)
1633 private void fft_calc (IMDCT15Context* s, FFTComplex* out_, const(FFTComplex)* in_, int N, ptrdiff_t stride) {
1634 if (N) {
1635 const(FFTComplex)* exptab = s.exptab[N];
1636 const int len2 = 15 * (1 << (N - 1));
1637 int k;
1639 fft_calc(s, out_, in_, N - 1, stride * 2);
1640 fft_calc(s, out_ + len2, in_ + stride, N - 1, stride * 2);
1642 for (k = 0; k < len2; k++) {
1643 FFTComplex t;
1645 mixin(CMUL!("t", "out_[len2 + k]", "exptab[k]"));
1647 out_[len2 + k].re = out_[k].re - t.re;
1648 out_[len2 + k].im = out_[k].im - t.im;
1650 out_[k].re += t.re;
1651 out_[k].im += t.im;
1653 } else {
1654 fft15(s, out_, in_, stride);
1658 private void imdct15_half (IMDCT15Context* s, float* dst, const(float)* src, ptrdiff_t stride, float scale) {
1659 FFTComplex *z = cast(FFTComplex *)dst;
1660 const int len8 = s.len4 / 2;
1661 const(float)* in1 = src;
1662 const(float)* in2 = src + (s.len2 - 1) * stride;
1663 int i;
1665 for (i = 0; i < s.len4; i++) {
1666 FFTComplex tmp = { *in2, *in1 };
1667 mixin(CMUL!("s.tmp[i]", "tmp", "s.twiddle_exptab[i]"));
1668 in1 += 2 * stride;
1669 in2 -= 2 * stride;
1672 fft_calc(s, z, s.tmp, s.fft_n, 1);
1674 for (i = 0; i < len8; i++) {
1675 float r0, i0, r1, i1;
1677 mixin(CMUL3!("r0", "i1", "z[len8 - i - 1].im", "z[len8 - i - 1].re", "s.twiddle_exptab[len8 - i - 1].im", "s.twiddle_exptab[len8 - i - 1].re"));
1678 mixin(CMUL3!("r1", "i0", "z[len8 + i].im", "z[len8 + i].re", "s.twiddle_exptab[len8 + i].im", "s.twiddle_exptab[len8 + i].re"));
1679 z[len8 - i - 1].re = scale * r0;
1680 z[len8 - i - 1].im = scale * i0;
1681 z[len8 + i].re = scale * r1;
1682 z[len8 + i].im = scale * i1;
1686 alias CeltSpread = int;
1687 enum /*CeltSpread*/:int {
1688 CELT_SPREAD_NONE,
1689 CELT_SPREAD_LIGHT,
1690 CELT_SPREAD_NORMAL,
1691 CELT_SPREAD_AGGRESSIVE
1694 struct CeltFrame {
1695 float[CELT_MAX_BANDS] energy;
1696 float[CELT_MAX_BANDS][2] prev_energy;
1698 uint8_t[CELT_MAX_BANDS] collapse_masks;
1700 /* buffer for mdct output + postfilter */
1701 //DECLARE_ALIGNED(32, float, buf)[2048];
1702 float[2048] buf;
1704 /* postfilter parameters */
1705 int pf_period_new;
1706 float[3] pf_gains_new;
1707 int pf_period;
1708 float[3] pf_gains;
1709 int pf_period_old;
1710 float[3] pf_gains_old;
1712 float deemph_coeff;
1715 struct CeltContext {
1716 // constant values that do not change during context lifetime
1717 //AVCodecContext *avctx;
1718 IMDCT15Context*[4] imdct;
1719 //AVFloatDSPContext* dsp;
1720 int output_channels;
1722 // values that have inter-frame effect and must be reset on flush
1723 CeltFrame[2] frame;
1724 uint32_t seed;
1725 int flushed;
1727 // values that only affect a single frame
1728 int coded_channels;
1729 int framebits;
1730 int duration;
1732 /* number of iMDCT blocks in the frame */
1733 int blocks;
1734 /* size of each block */
1735 int blocksize;
1737 int startband;
1738 int endband;
1739 int codedbands;
1741 int anticollapse_bit;
1743 int intensitystereo;
1744 int dualstereo;
1745 CeltSpread spread;
1747 int remaining;
1748 int remaining2;
1749 int[CELT_MAX_BANDS] fine_bits;
1750 int[CELT_MAX_BANDS] fine_priority;
1751 int[CELT_MAX_BANDS] pulses;
1752 int[CELT_MAX_BANDS] tf_change;
1754 //DECLARE_ALIGNED(32, float, coeffs)[2][CELT_MAX_FRAME_SIZE];
1755 //DECLARE_ALIGNED(32, float, scratch)[22 * 8]; // MAX(celt_freq_range) * 1<<CELT_MAX_LOG_BLOCKS
1756 float[CELT_MAX_FRAME_SIZE][2] coeffs;
1757 float[22 * 8] scratch;
1760 static immutable uint16_t[4] celt_model_tapset = [ 4, 2, 3, 4 ];
1762 static immutable uint16_t[5] celt_model_spread = [ 32, 7, 9, 30, 32 ];
1764 static immutable uint16_t[12] celt_model_alloc_trim = [
1765 128, 2, 4, 9, 19, 41, 87, 109, 119, 124, 126, 128
1768 static immutable uint16_t[4] celt_model_energy_small = [ 4, 2, 3, 4 ];
1770 static immutable uint8_t[22] celt_freq_bands = [ /* in steps of 200Hz */
1771 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
1774 static immutable uint8_t[21] celt_freq_range = [
1775 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 6, 6, 8, 12, 18, 22
1778 static immutable uint8_t[21] celt_log_freq_range = [
1779 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36
1782 static immutable int8_t[2][2][2][4] celt_tf_select = [
1783 [ [ [ 0, -1 ], [ 0, -1 ] ], [ [ 0, -1 ], [ 0, -1 ] ] ],
1784 [ [ [ 0, -1 ], [ 0, -2 ] ], [ [ 1, 0 ], [ 1, -1 ] ] ],
1785 [ [ [ 0, -2 ], [ 0, -3 ] ], [ [ 2, 0 ], [ 1, -1 ] ] ],
1786 [ [ [ 0, -2 ], [ 0, -3 ] ], [ [ 3, 0 ], [ 1, -1 ] ] ]
1789 static immutable float[25] celt_mean_energy = [
1790 6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f,
1791 4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f,
1792 4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f,
1793 4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f,
1794 3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f
1797 static immutable float[4] celt_alpha_coef = [
1798 29440.0f/32768.0f, 26112.0f/32768.0f, 21248.0f/32768.0f, 16384.0f/32768.0f
1801 static immutable float[4] celt_beta_coef = [ /* TODO: precompute 1 minus this if the code ends up neater */
1802 30147.0f/32768.0f, 22282.0f/32768.0f, 12124.0f/32768.0f, 6554.0f/32768.0f
1805 static immutable uint8_t[42][2][4] celt_coarse_energy_dist = [
1807 [ // 120-sample inter
1808 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128,
1809 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40,
1810 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11
1811 ], [ // 120-sample intra
1812 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132,
1813 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66,
1814 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50
1816 ], [
1817 [ // 240-sample inter
1818 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74,
1819 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18,
1820 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9
1821 ], [ // 240-sample intra
1822 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91,
1823 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60,
1824 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45
1826 ], [
1827 [ // 480-sample inter
1828 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38,
1829 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16,
1830 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10
1831 ], [ // 480-sample intra
1832 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73,
1833 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55,
1834 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42
1836 ], [
1837 [ // 960-sample inter
1838 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36,
1839 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25,
1840 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15
1841 ], [ // 960-sample intra
1842 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72,
1843 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52,
1844 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40
1849 static immutable uint8_t[21][11] celt_static_alloc = [ /* 1/32 bit/sample */
1850 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1851 [ 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0 ],
1852 [ 110, 100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0 ],
1853 [ 118, 110, 103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0 ],
1854 [ 126, 119, 112, 104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0 ],
1855 [ 134, 127, 120, 114, 103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1 ],
1856 [ 144, 137, 130, 124, 113, 107, 101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1 ],
1857 [ 152, 145, 138, 132, 123, 117, 111, 105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1 ],
1858 [ 162, 155, 148, 142, 133, 127, 121, 115, 108, 102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1 ],
1859 [ 172, 165, 158, 152, 143, 137, 131, 125, 118, 112, 106, 100, 94, 87, 81, 75, 69, 63, 56, 45, 20 ],
1860 [ 200, 200, 200, 200, 200, 200, 200, 200, 198, 193, 188, 183, 178, 173, 168, 163, 158, 153, 148, 129, 104 ]
1863 static immutable uint8_t[21][2][4] celt_static_caps = [
1864 [ // 120-sample
1865 [224, 224, 224, 224, 224, 224, 224, 224, 160, 160,
1866 160, 160, 185, 185, 185, 178, 178, 168, 134, 61, 37],
1867 [224, 224, 224, 224, 224, 224, 224, 224, 240, 240,
1868 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40],
1869 ], [ // 240-sample
1870 [160, 160, 160, 160, 160, 160, 160, 160, 185, 185,
1871 185, 185, 193, 193, 193, 183, 183, 172, 138, 64, 38],
1872 [240, 240, 240, 240, 240, 240, 240, 240, 207, 207,
1873 207, 207, 204, 204, 204, 193, 193, 180, 143, 66, 40],
1874 ], [ // 480-sample
1875 [185, 185, 185, 185, 185, 185, 185, 185, 193, 193,
1876 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39],
1877 [207, 207, 207, 207, 207, 207, 207, 207, 204, 204,
1878 204, 204, 201, 201, 201, 188, 188, 176, 141, 66, 40],
1879 ], [ // 960-sample
1880 [193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
1881 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39],
1882 [204, 204, 204, 204, 204, 204, 204, 204, 201, 201,
1883 201, 201, 198, 198, 198, 187, 187, 175, 140, 66, 40]
1887 static immutable uint8_t[392] celt_cache_bits = [
1888 40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1889 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1890 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,
1891 31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,
1892 51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,
1893 66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,
1894 64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,
1895 94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,
1896 124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,
1897 97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,
1898 142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,
1899 28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,
1900 153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,
1901 229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,
1902 166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,
1903 86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,
1904 25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,
1905 185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,
1906 110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,
1907 74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,
1908 163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,
1909 228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,
1910 90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,
1911 87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,
1912 106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,
1913 224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,
1914 182, 234
1917 static immutable int16_t[105] celt_cache_index = [
1918 -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,
1919 82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,
1920 41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,
1921 41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,
1922 318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,
1923 305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,
1924 240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,
1927 static immutable uint8_t[24] celt_log2_frac = [
1928 0, 8, 13, 16, 19, 21, 23, 24, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 37
1931 static immutable uint8_t[16] celt_bit_interleave = [
1932 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3
1935 static immutable uint8_t[16] celt_bit_deinterleave = [
1936 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
1937 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
1940 static immutable uint8_t[30] celt_hadamard_ordery = [
1941 1, 0,
1942 3, 0, 2, 1,
1943 7, 0, 4, 3, 6, 1, 5, 2,
1944 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5
1947 static immutable uint16_t[8] celt_qn_exp2 = [
1948 16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048
1951 static immutable uint32_t[1272] celt_pvq_u = [
1952 /* N = 0, K = 0...176 */
1953 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1954 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1955 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1956 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1957 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1958 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1959 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1960 /* N = 1, K = 1...176 */
1961 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1962 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1963 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1964 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1965 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1966 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1967 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1968 /* N = 2, K = 2...176 */
1969 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,
1970 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
1971 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113,
1972 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143,
1973 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
1974 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203,
1975 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233,
1976 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263,
1977 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293,
1978 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323,
1979 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351,
1980 /* N = 3, K = 3...176 */
1981 13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613,
1982 685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861,
1983 1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785,
1984 3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385,
1985 6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661,
1986 9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961,
1987 13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745,
1988 17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013,
1989 21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765,
1990 26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001,
1991 31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721,
1992 37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925,
1993 43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613,
1994 50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785,
1995 57461, 58141, 58825, 59513, 60205, 60901, 61601,
1996 /* N = 4, K = 4...176 */
1997 63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017,
1998 7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775,
1999 30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153,
2000 82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193,
2001 161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575,
2002 267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217,
2003 410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951,
2004 597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609,
2005 833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023,
2006 1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407,
2007 1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759,
2008 1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175,
2009 2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751,
2010 2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583,
2011 3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767,
2012 3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399,
2013 4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575,
2014 5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391,
2015 6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943,
2016 7085049, 7207551,
2017 /* N = 5, K = 5...176 */
2018 321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041,
2019 50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401,
2020 330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241,
2021 1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241,
2022 2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801,
2023 4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849,
2024 8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849,
2025 13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809,
2026 20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881,
2027 29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641,
2028 40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081,
2029 55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609,
2030 73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049,
2031 95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641,
2032 122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041,
2033 155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321,
2034 193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969,
2035 238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889,
2036 290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401,
2037 351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241,
2038 420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561,
2039 500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929,
2040 590359041, 604167209, 618216201, 632508801,
2041 /* N = 6, K = 6...96 (technically V(109,5) fits in 32 bits, but that can't be
2042 achieved by splitting an Opus band) */
2043 1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047,
2044 335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409,
2045 2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793,
2046 11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455,
2047 29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189,
2048 64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651,
2049 128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185,
2050 235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647,
2051 402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229,
2052 655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283,
2053 1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135,
2054 1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187,
2055 2011371957, 2120032959,
2056 /* N = 7, K = 7...54 (technically V(60,6) fits in 32 bits, but that can't be
2057 achieved by splitting an Opus band) */
2058 8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777,
2059 1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233,
2060 19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013,
2061 88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805,
2062 292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433,
2063 793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821,
2064 1667010073, 1870535785, 2094367717,
2065 /* N = 8, K = 8...37 (technically V(40,7) fits in 32 bits, but that can't be
2066 achieved by splitting an Opus band) */
2067 48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767,
2068 9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017,
2069 104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351,
2070 638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615,
2071 2229491905,
2072 /* N = 9, K = 9...28 (technically V(29,8) fits in 32 bits, but that can't be
2073 achieved by splitting an Opus band) */
2074 265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777,
2075 39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145,
2076 628496897, 872893441, 1196924561, 1621925137, 2173806145,
2077 /* N = 10, K = 10...24 */
2078 1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073,
2079 254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629,
2080 3375210671,
2081 /* N = 11, K = 11...19 (technically V(20,10) fits in 32 bits, but that can't be
2082 achieved by splitting an Opus band) */
2083 8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585,
2084 948062325, 1616336765,
2085 /* N = 12, K = 12...18 */
2086 45046719, 103274625, 224298231, 464387817, 921406335, 1759885185,
2087 3248227095,
2088 /* N = 13, K = 13...16 */
2089 251595969, 579168825, 1267854873, 2653649025,
2090 /* N = 14, K = 14 */
2091 1409933619
2094 //DECLARE_ALIGNED(32, static immutable float, celt_window)[120] = [
2095 static immutable float[120] celt_window = [
2096 6.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f,
2097 0.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f,
2098 0.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f,
2099 0.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f,
2100 0.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f,
2101 0.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f,
2102 0.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f,
2103 0.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f,
2104 0.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f,
2105 0.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f,
2106 0.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f,
2107 0.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f,
2108 0.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f,
2109 0.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f,
2110 0.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f,
2111 0.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f,
2112 0.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f,
2113 0.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f,
2114 0.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f,
2115 0.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f,
2116 0.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f,
2117 0.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f,
2118 0.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f,
2119 0.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.0000000f,
2122 /* square of the window, used for the postfilter */
2123 static immutable float[120] ff_celt_window2 = [
2124 4.5275357e-09f, 3.66647e-07f, 2.82777e-06f, 1.08557e-05f, 2.96371e-05f, 6.60594e-05f,
2125 0.000128686f, 0.000227727f, 0.000374999f, 0.000583881f, 0.000869266f, 0.0012475f,
2126 0.0017363f, 0.00235471f, 0.00312299f, 0.00406253f, 0.00519576f, 0.00654601f,
2127 0.00813743f, 0.00999482f, 0.0121435f, 0.0146093f, 0.017418f, 0.0205957f, 0.0241684f,
2128 0.0281615f, 0.0326003f, 0.0375092f, 0.0429118f, 0.0488308f, 0.0552873f, 0.0623012f,
2129 0.0698908f, 0.0780723f, 0.0868601f, 0.0962664f, 0.106301f, 0.11697f, 0.12828f,
2130 0.140231f, 0.152822f, 0.166049f, 0.179905f, 0.194379f, 0.209457f, 0.225123f, 0.241356f,
2131 0.258133f, 0.275428f, 0.293212f, 0.311453f, 0.330116f, 0.349163f, 0.368556f, 0.388253f,
2132 0.40821f, 0.428382f, 0.448723f, 0.469185f, 0.48972f, 0.51028f, 0.530815f, 0.551277f,
2133 0.571618f, 0.59179f, 0.611747f, 0.631444f, 0.650837f, 0.669884f, 0.688547f, 0.706788f,
2134 0.724572f, 0.741867f, 0.758644f, 0.774877f, 0.790543f, 0.805621f, 0.820095f, 0.833951f,
2135 0.847178f, 0.859769f, 0.87172f, 0.88303f, 0.893699f, 0.903734f, 0.91314f, 0.921928f,
2136 0.930109f, 0.937699f, 0.944713f, 0.951169f, 0.957088f, 0.962491f, 0.9674f, 0.971838f,
2137 0.975832f, 0.979404f, 0.982582f, 0.985391f, 0.987857f, 0.990005f, 0.991863f, 0.993454f,
2138 0.994804f, 0.995937f, 0.996877f, 0.997645f, 0.998264f, 0.998753f, 0.999131f, 0.999416f,
2139 0.999625f, 0.999772f, 0.999871f, 0.999934f, 0.99997f, 0.999989f, 0.999997f, 0.99999964f, 1.0f,
2142 static immutable uint32_t*[15] celt_pvq_u_row = [
2143 celt_pvq_u.ptr + 0, celt_pvq_u.ptr + 176, celt_pvq_u.ptr + 351,
2144 celt_pvq_u.ptr + 525, celt_pvq_u.ptr + 698, celt_pvq_u.ptr + 870,
2145 celt_pvq_u.ptr + 1041, celt_pvq_u.ptr + 1131, celt_pvq_u.ptr + 1178,
2146 celt_pvq_u.ptr + 1207, celt_pvq_u.ptr + 1226, celt_pvq_u.ptr + 1240,
2147 celt_pvq_u.ptr + 1248, celt_pvq_u.ptr + 1254, celt_pvq_u.ptr + 1257
2150 /*static inline*/ int16_t celt_cos(int16_t x)
2152 x = cast(short)((MUL16(x, x) + 4096) >> 13);
2153 x = cast(short)((32767-x) + ROUND_MUL16(x, (-7651 + ROUND_MUL16(x, (8277 + ROUND_MUL16(-626, x))))));
2154 return cast(short)(1+x);
2157 /*static inline*/ int celt_log2tan(int isin, int icos)
2159 int lc, ls;
2160 lc = opus_ilog(icos);
2161 ls = opus_ilog(isin);
2162 icos <<= 15 - lc;
2163 isin <<= 15 - ls;
2164 return (ls << 11) - (lc << 11) +
2165 ROUND_MUL16(isin, ROUND_MUL16(isin, -2597) + 7932) -
2166 ROUND_MUL16(icos, ROUND_MUL16(icos, -2597) + 7932);
2169 /*static inline*/ uint32_t celt_rng(CeltContext *s)
2171 s.seed = 1664525 * s.seed + 1013904223;
2172 return s.seed;
2175 private void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc)
2177 int i, j;
2178 float[2] prev = 0;
2179 float alpha, beta;
2180 const(uint8_t)* model;
2182 /* use the 2D z-transform to apply prediction in both */
2183 /* the time domain (alpha) and the frequency domain (beta) */
2185 if (opus_rc_tell(rc)+3 <= s.framebits && opus_rc_p2model(rc, 3)) {
2186 /* intra frame */
2187 alpha = 0;
2188 beta = 1.0f - 4915.0f/32768.0f;
2189 model = celt_coarse_energy_dist[s.duration][1].ptr;
2190 } else {
2191 alpha = celt_alpha_coef[s.duration];
2192 beta = 1.0f - celt_beta_coef[s.duration];
2193 model = celt_coarse_energy_dist[s.duration][0].ptr;
2196 for (i = 0; i < CELT_MAX_BANDS; i++) {
2197 for (j = 0; j < s.coded_channels; j++) {
2198 CeltFrame *frame = &s.frame[j];
2199 float value;
2200 int available;
2202 if (i < s.startband || i >= s.endband) {
2203 frame.energy[i] = 0.0;
2204 continue;
2207 available = s.framebits - opus_rc_tell(rc);
2208 if (available >= 15) {
2209 /* decode using a Laplace distribution */
2210 int k = FFMIN(i, 20) << 1;
2211 value = opus_rc_laplace(rc, model[k] << 7, model[k+1] << 6);
2212 } else if (available >= 2) {
2213 int x = opus_rc_getsymbol(rc, celt_model_energy_small.ptr);
2214 value = (x>>1) ^ -(x&1);
2215 } else if (available >= 1) {
2216 value = -cast(float)opus_rc_p2model(rc, 1);
2217 } else value = -1;
2219 frame.energy[i] = FFMAX(-9.0f, frame.energy[i]) * alpha + prev[j] + value;
2220 prev[j] += beta * value;
2225 private void celt_decode_fine_energy(CeltContext *s, OpusRangeCoder *rc)
2227 int i;
2228 for (i = s.startband; i < s.endband; i++) {
2229 int j;
2230 if (!s.fine_bits[i])
2231 continue;
2233 for (j = 0; j < s.coded_channels; j++) {
2234 CeltFrame *frame = &s.frame[j];
2235 int q2;
2236 float offset;
2237 q2 = opus_getrawbits(rc, s.fine_bits[i]);
2238 offset = (q2 + 0.5f) * (1 << (14 - s.fine_bits[i])) / 16384.0f - 0.5f;
2239 frame.energy[i] += offset;
2244 private void celt_decode_final_energy(CeltContext *s, OpusRangeCoder *rc, int bits_left)
2246 int priority, i, j;
2248 for (priority = 0; priority < 2; priority++) {
2249 for (i = s.startband; i < s.endband && bits_left >= s.coded_channels; i++) {
2250 if (s.fine_priority[i] != priority || s.fine_bits[i] >= CELT_MAX_FINE_BITS)
2251 continue;
2253 for (j = 0; j < s.coded_channels; j++) {
2254 int q2;
2255 float offset;
2256 q2 = opus_getrawbits(rc, 1);
2257 offset = (q2 - 0.5f) * (1 << (14 - s.fine_bits[i] - 1)) / 16384.0f;
2258 s.frame[j].energy[i] += offset;
2259 bits_left--;
2265 private void celt_decode_tf_changes(CeltContext *s, OpusRangeCoder *rc, int transient)
2267 int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit;
2268 int consumed, bits = transient ? 2 : 4;
2270 consumed = opus_rc_tell(rc);
2271 tf_select_bit = (s.duration != 0 && consumed+bits+1 <= s.framebits);
2273 for (i = s.startband; i < s.endband; i++) {
2274 if (consumed+bits+tf_select_bit <= s.framebits) {
2275 diff ^= opus_rc_p2model(rc, bits);
2276 consumed = opus_rc_tell(rc);
2277 tf_changed |= diff;
2279 s.tf_change[i] = diff;
2280 bits = transient ? 4 : 5;
2283 if (tf_select_bit && celt_tf_select[s.duration][transient][0][tf_changed] !=
2284 celt_tf_select[s.duration][transient][1][tf_changed])
2285 tf_select = opus_rc_p2model(rc, 1);
2287 for (i = s.startband; i < s.endband; i++) {
2288 s.tf_change[i] = celt_tf_select[s.duration][transient][tf_select][s.tf_change[i]];
2292 private void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
2294 // approx. maximum bit allocation for each band before boost/trim
2295 int[CELT_MAX_BANDS] cap;
2296 int[CELT_MAX_BANDS] boost;
2297 int[CELT_MAX_BANDS] threshold;
2298 int[CELT_MAX_BANDS] bits1;
2299 int[CELT_MAX_BANDS] bits2;
2300 int[CELT_MAX_BANDS] trim_offset;
2302 int skip_startband = s.startband;
2303 int dynalloc = 6;
2304 int alloctrim = 5;
2305 int extrabits = 0;
2307 int skip_bit = 0;
2308 int intensitystereo_bit = 0;
2309 int dualstereo_bit = 0;
2311 int remaining, bandbits;
2312 int low, high, total, done;
2313 int totalbits;
2314 int consumed;
2315 int i, j;
2317 consumed = opus_rc_tell(rc);
2319 /* obtain spread flag */
2320 s.spread = CELT_SPREAD_NORMAL;
2321 if (consumed + 4 <= s.framebits)
2322 s.spread = opus_rc_getsymbol(rc, celt_model_spread.ptr);
2324 /* generate static allocation caps */
2325 for (i = 0; i < CELT_MAX_BANDS; i++) {
2326 cap[i] = (celt_static_caps[s.duration][s.coded_channels - 1][i] + 64)
2327 * celt_freq_range[i] << (s.coded_channels - 1) << s.duration >> 2;
2330 /* obtain band boost */
2331 totalbits = s.framebits << 3; // convert to 1/8 bits
2332 consumed = opus_rc_tell_frac(rc);
2333 for (i = s.startband; i < s.endband; i++) {
2334 int quanta, band_dynalloc;
2336 boost[i] = 0;
2338 quanta = celt_freq_range[i] << (s.coded_channels - 1) << s.duration;
2339 quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta));
2340 band_dynalloc = dynalloc;
2341 while (consumed + (band_dynalloc<<3) < totalbits && boost[i] < cap[i]) {
2342 int add = opus_rc_p2model(rc, band_dynalloc);
2343 consumed = opus_rc_tell_frac(rc);
2344 if (!add)
2345 break;
2347 boost[i] += quanta;
2348 totalbits -= quanta;
2349 band_dynalloc = 1;
2351 /* dynalloc is more likely to occur if it's already been used for earlier bands */
2352 if (boost[i])
2353 dynalloc = FFMAX(2, dynalloc - 1);
2356 /* obtain allocation trim */
2357 if (consumed + (6 << 3) <= totalbits)
2358 alloctrim = opus_rc_getsymbol(rc, celt_model_alloc_trim.ptr);
2360 /* anti-collapse bit reservation */
2361 totalbits = (s.framebits << 3) - opus_rc_tell_frac(rc) - 1;
2362 s.anticollapse_bit = 0;
2363 if (s.blocks > 1 && s.duration >= 2 &&
2364 totalbits >= ((s.duration + 2) << 3))
2365 s.anticollapse_bit = 1 << 3;
2366 totalbits -= s.anticollapse_bit;
2368 /* band skip bit reservation */
2369 if (totalbits >= 1 << 3)
2370 skip_bit = 1 << 3;
2371 totalbits -= skip_bit;
2373 /* intensity/dual stereo bit reservation */
2374 if (s.coded_channels == 2) {
2375 intensitystereo_bit = celt_log2_frac[s.endband - s.startband];
2376 if (intensitystereo_bit <= totalbits) {
2377 totalbits -= intensitystereo_bit;
2378 if (totalbits >= 1 << 3) {
2379 dualstereo_bit = 1 << 3;
2380 totalbits -= 1 << 3;
2382 } else
2383 intensitystereo_bit = 0;
2386 for (i = s.startband; i < s.endband; i++) {
2387 int trim = alloctrim - 5 - s.duration;
2388 int band = celt_freq_range[i] * (s.endband - i - 1);
2389 int duration = s.duration + 3;
2390 int scale = duration + s.coded_channels - 1;
2392 /* PVQ minimum allocation threshold, below this value the band is
2393 * skipped */
2394 threshold[i] = FFMAX(3 * celt_freq_range[i] << duration >> 4,
2395 s.coded_channels << 3);
2397 trim_offset[i] = trim * (band << scale) >> 6;
2399 if (celt_freq_range[i] << s.duration == 1)
2400 trim_offset[i] -= s.coded_channels << 3;
2403 /* bisection */
2404 low = 1;
2405 high = CELT_VECTORS - 1;
2406 while (low <= high) {
2407 int center = (low + high) >> 1;
2408 done = total = 0;
2410 for (i = s.endband - 1; i >= s.startband; i--) {
2411 bandbits = celt_freq_range[i] * celt_static_alloc[center][i]
2412 << (s.coded_channels - 1) << s.duration >> 2;
2414 if (bandbits)
2415 bandbits = FFMAX(0, bandbits + trim_offset[i]);
2416 bandbits += boost[i];
2418 if (bandbits >= threshold[i] || done) {
2419 done = 1;
2420 total += FFMIN(bandbits, cap[i]);
2421 } else if (bandbits >= s.coded_channels << 3)
2422 total += s.coded_channels << 3;
2425 if (total > totalbits)
2426 high = center - 1;
2427 else
2428 low = center + 1;
2430 high = low--;
2432 for (i = s.startband; i < s.endband; i++) {
2433 bits1[i] = celt_freq_range[i] * celt_static_alloc[low][i]
2434 << (s.coded_channels - 1) << s.duration >> 2;
2435 bits2[i] = high >= CELT_VECTORS ? cap[i] :
2436 celt_freq_range[i] * celt_static_alloc[high][i]
2437 << (s.coded_channels - 1) << s.duration >> 2;
2439 if (bits1[i])
2440 bits1[i] = FFMAX(0, bits1[i] + trim_offset[i]);
2441 if (bits2[i])
2442 bits2[i] = FFMAX(0, bits2[i] + trim_offset[i]);
2443 if (low)
2444 bits1[i] += boost[i];
2445 bits2[i] += boost[i];
2447 if (boost[i])
2448 skip_startband = i;
2449 bits2[i] = FFMAX(0, bits2[i] - bits1[i]);
2452 /* bisection */
2453 low = 0;
2454 high = 1 << CELT_ALLOC_STEPS;
2455 for (i = 0; i < CELT_ALLOC_STEPS; i++) {
2456 int center = (low + high) >> 1;
2457 done = total = 0;
2459 for (j = s.endband - 1; j >= s.startband; j--) {
2460 bandbits = bits1[j] + (center * bits2[j] >> CELT_ALLOC_STEPS);
2462 if (bandbits >= threshold[j] || done) {
2463 done = 1;
2464 total += FFMIN(bandbits, cap[j]);
2465 } else if (bandbits >= s.coded_channels << 3)
2466 total += s.coded_channels << 3;
2468 if (total > totalbits)
2469 high = center;
2470 else
2471 low = center;
2474 done = total = 0;
2475 for (i = s.endband - 1; i >= s.startband; i--) {
2476 bandbits = bits1[i] + (low * bits2[i] >> CELT_ALLOC_STEPS);
2478 if (bandbits >= threshold[i] || done)
2479 done = 1;
2480 else
2481 bandbits = (bandbits >= s.coded_channels << 3) ?
2482 s.coded_channels << 3 : 0;
2484 bandbits = FFMIN(bandbits, cap[i]);
2485 s.pulses[i] = bandbits;
2486 total += bandbits;
2489 /* band skipping */
2490 for (s.codedbands = s.endband; ; s.codedbands--) {
2491 int allocation;
2492 j = s.codedbands - 1;
2494 if (j == skip_startband) {
2495 /* all remaining bands are not skipped */
2496 totalbits += skip_bit;
2497 break;
2500 /* determine the number of bits available for coding "do not skip" markers */
2501 remaining = totalbits - total;
2502 bandbits = remaining / (celt_freq_bands[j+1] - celt_freq_bands[s.startband]);
2503 remaining -= bandbits * (celt_freq_bands[j+1] - celt_freq_bands[s.startband]);
2504 allocation = s.pulses[j] + bandbits * celt_freq_range[j]
2505 + FFMAX(0, remaining - (celt_freq_bands[j] - celt_freq_bands[s.startband]));
2507 /* a "do not skip" marker is only coded if the allocation is
2508 above the chosen threshold */
2509 if (allocation >= FFMAX(threshold[j], (s.coded_channels + 1) <<3 )) {
2510 if (opus_rc_p2model(rc, 1))
2511 break;
2513 total += 1 << 3;
2514 allocation -= 1 << 3;
2517 /* the band is skipped, so reclaim its bits */
2518 total -= s.pulses[j];
2519 if (intensitystereo_bit) {
2520 total -= intensitystereo_bit;
2521 intensitystereo_bit = celt_log2_frac[j - s.startband];
2522 total += intensitystereo_bit;
2525 total += s.pulses[j] = (allocation >= s.coded_channels << 3) ?
2526 s.coded_channels << 3 : 0;
2529 /* obtain stereo flags */
2530 s.intensitystereo = 0;
2531 s.dualstereo = 0;
2532 if (intensitystereo_bit)
2533 s.intensitystereo = s.startband +
2534 opus_rc_unimodel(rc, s.codedbands + 1 - s.startband);
2535 if (s.intensitystereo <= s.startband)
2536 totalbits += dualstereo_bit; /* no intensity stereo means no dual stereo */
2537 else if (dualstereo_bit)
2538 s.dualstereo = opus_rc_p2model(rc, 1);
2540 /* supply the remaining bits in this frame to lower bands */
2541 remaining = totalbits - total;
2542 bandbits = remaining / (celt_freq_bands[s.codedbands] - celt_freq_bands[s.startband]);
2543 remaining -= bandbits * (celt_freq_bands[s.codedbands] - celt_freq_bands[s.startband]);
2544 for (i = s.startband; i < s.codedbands; i++) {
2545 int bits = FFMIN(remaining, celt_freq_range[i]);
2547 s.pulses[i] += bits + bandbits * celt_freq_range[i];
2548 remaining -= bits;
2551 for (i = s.startband; i < s.codedbands; i++) {
2552 int N = celt_freq_range[i] << s.duration;
2553 int prev_extra = extrabits;
2554 s.pulses[i] += extrabits;
2556 if (N > 1) {
2557 int dof; // degrees of freedom
2558 int temp; // dof * channels * log(dof)
2559 int offset; // fine energy quantization offset, i.e.
2560 // extra bits assigned over the standard
2561 // totalbits/dof
2562 int fine_bits, max_bits;
2564 extrabits = FFMAX(0, s.pulses[i] - cap[i]);
2565 s.pulses[i] -= extrabits;
2567 /* intensity stereo makes use of an extra degree of freedom */
2568 dof = N * s.coded_channels
2569 + (s.coded_channels == 2 && N > 2 && !s.dualstereo && i < s.intensitystereo);
2570 temp = dof * (celt_log_freq_range[i] + (s.duration<<3));
2571 offset = (temp >> 1) - dof * CELT_FINE_OFFSET;
2572 if (N == 2) /* dof=2 is the only case that doesn't fit the model */
2573 offset += dof<<1;
2575 /* grant an additional bias for the first and second pulses */
2576 if (s.pulses[i] + offset < 2 * (dof << 3))
2577 offset += temp >> 2;
2578 else if (s.pulses[i] + offset < 3 * (dof << 3))
2579 offset += temp >> 3;
2581 fine_bits = (s.pulses[i] + offset + (dof << 2)) / (dof << 3);
2582 max_bits = FFMIN((s.pulses[i]>>3) >> (s.coded_channels - 1),
2583 CELT_MAX_FINE_BITS);
2585 max_bits = FFMAX(max_bits, 0);
2587 s.fine_bits[i] = av_clip(fine_bits, 0, max_bits);
2589 /* if fine_bits was rounded down or capped,
2590 give priority for the final fine energy pass */
2591 s.fine_priority[i] = (s.fine_bits[i] * (dof<<3) >= s.pulses[i] + offset);
2593 /* the remaining bits are assigned to PVQ */
2594 s.pulses[i] -= s.fine_bits[i] << (s.coded_channels - 1) << 3;
2595 } else {
2596 /* all bits go to fine energy except for the sign bit */
2597 extrabits = FFMAX(0, s.pulses[i] - (s.coded_channels << 3));
2598 s.pulses[i] -= extrabits;
2599 s.fine_bits[i] = 0;
2600 s.fine_priority[i] = 1;
2603 /* hand back a limited number of extra fine energy bits to this band */
2604 if (extrabits > 0) {
2605 int fineextra = FFMIN(extrabits >> (s.coded_channels + 2),
2606 CELT_MAX_FINE_BITS - s.fine_bits[i]);
2607 s.fine_bits[i] += fineextra;
2609 fineextra <<= s.coded_channels + 2;
2610 s.fine_priority[i] = (fineextra >= extrabits - prev_extra);
2611 extrabits -= fineextra;
2614 s.remaining = extrabits;
2616 /* skipped bands dedicate all of their bits for fine energy */
2617 for (; i < s.endband; i++) {
2618 s.fine_bits[i] = s.pulses[i] >> (s.coded_channels - 1) >> 3;
2619 s.pulses[i] = 0;
2620 s.fine_priority[i] = s.fine_bits[i] < 1;
2624 /*static inline*/ int celt_bits2pulses(const(uint8_t)* cache, int bits)
2626 // TODO: Find the size of cache and make it into an array in the parameters list
2627 int i, low = 0, high;
2629 high = cache[0];
2630 bits--;
2632 for (i = 0; i < 6; i++) {
2633 int center = (low + high + 1) >> 1;
2634 if (cache[center] >= bits)
2635 high = center;
2636 else
2637 low = center;
2640 return (bits - (low == 0 ? -1 : cache[low]) <= cache[high] - bits) ? low : high;
2643 /*static inline*/ int celt_pulses2bits(const(uint8_t)* cache, int pulses)
2645 // TODO: Find the size of cache and make it into an array in the parameters list
2646 return (pulses == 0) ? 0 : cache[pulses] + 1;
2649 /*static inline*/ void celt_normalize_residual(const(int)* /*av_restrict*/ iy, float * /*av_restrict*/ X, int N, float g)
2651 int i;
2652 for (i = 0; i < N; i++)
2653 X[i] = g * iy[i];
2656 private void celt_exp_rotation1(float *X, uint len, uint stride, float c, float s)
2658 float *Xptr;
2659 int i;
2661 Xptr = X;
2662 for (i = 0; i < len - stride; i++) {
2663 float x1, x2;
2664 x1 = Xptr[0];
2665 x2 = Xptr[stride];
2666 Xptr[stride] = c * x2 + s * x1;
2667 *Xptr++ = c * x1 - s * x2;
2670 Xptr = &X[len - 2 * stride - 1];
2671 for (i = len - 2 * stride - 1; i >= 0; i--) {
2672 float x1, x2;
2673 x1 = Xptr[0];
2674 x2 = Xptr[stride];
2675 Xptr[stride] = c * x2 + s * x1;
2676 *Xptr-- = c * x1 - s * x2;
2680 /*static inline*/ void celt_exp_rotation(float *X, uint len, uint stride, uint K, CeltSpread spread)
2682 import std.math : PI, cos, sin;
2683 uint stride2 = 0;
2684 float c, s;
2685 float gain, theta;
2686 int i;
2688 if (2*K >= len || spread == CELT_SPREAD_NONE)
2689 return;
2691 gain = cast(float)len / (len + (20 - 5*spread) * K);
2692 theta = PI * gain * gain / 4;
2694 c = cos(theta);
2695 s = sin(theta);
2697 if (len >= stride << 3) {
2698 stride2 = 1;
2699 /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding.
2700 It's basically incrementing long as (stride2+0.5)^2 < len/stride. */
2701 while ((stride2 * stride2 + stride2) * stride + (stride >> 2) < len)
2702 stride2++;
2705 /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for
2706 extract_collapse_mask().*/
2707 len /= stride;
2708 for (i = 0; i < stride; i++) {
2709 if (stride2)
2710 celt_exp_rotation1(X + i * len, len, stride2, s, c);
2711 celt_exp_rotation1(X + i * len, len, 1, c, s);
2715 /*static inline*/ uint celt_extract_collapse_mask(const(int)* iy, uint N, uint B)
2717 uint collapse_mask;
2718 int N0;
2719 int i, j;
2721 if (B <= 1)
2722 return 1;
2724 /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for
2725 exp_rotation().*/
2726 N0 = N/B;
2727 collapse_mask = 0;
2728 for (i = 0; i < B; i++)
2729 for (j = 0; j < N0; j++)
2730 collapse_mask |= (iy[i*N0+j]!=0)<<i;
2731 return collapse_mask;
2734 /*static inline*/ void celt_renormalize_vector(float *X, int N, float gain)
2736 import core.stdc.math : sqrtf;
2737 int i;
2738 float g = 1e-15f;
2739 for (i = 0; i < N; i++)
2740 g += X[i] * X[i];
2741 g = gain / sqrtf(g);
2743 for (i = 0; i < N; i++)
2744 X[i] *= g;
2747 /*static inline*/ void celt_stereo_merge(float *X, float *Y, float mid, int N)
2749 import core.stdc.math : sqrtf;
2750 int i;
2751 float xp = 0, side = 0;
2752 float[2] E;
2753 float mid2;
2754 float t;
2755 float[2] gain;
2757 /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
2758 for (i = 0; i < N; i++) {
2759 xp += X[i] * Y[i];
2760 side += Y[i] * Y[i];
2763 /* Compensating for the mid normalization */
2764 xp *= mid;
2765 mid2 = mid;
2766 E[0] = mid2 * mid2 + side - 2 * xp;
2767 E[1] = mid2 * mid2 + side + 2 * xp;
2768 if (E[0] < 6e-4f || E[1] < 6e-4f) {
2769 for (i = 0; i < N; i++)
2770 Y[i] = X[i];
2771 return;
2774 t = E[0];
2775 gain[0] = 1.0f / sqrtf(t);
2776 t = E[1];
2777 gain[1] = 1.0f / sqrtf(t);
2779 for (i = 0; i < N; i++) {
2780 float[2] value = void;
2781 /* Apply mid scaling (side is already scaled) */
2782 value[0] = mid * X[i];
2783 value[1] = Y[i];
2784 X[i] = gain[0] * (value[0] - value[1]);
2785 Y[i] = gain[1] * (value[0] + value[1]);
2789 private void celt_interleave_hadamard (float *tmp, float *X, int N0, int stride, int hadamard)
2791 int i, j;
2792 int N = N0*stride;
2794 if (hadamard) {
2795 const(uint8_t)* ordery = celt_hadamard_ordery.ptr + stride - 2;
2796 for (i = 0; i < stride; i++)
2797 for (j = 0; j < N0; j++)
2798 tmp[j*stride+i] = X[ordery[i]*N0+j];
2799 } else {
2800 for (i = 0; i < stride; i++)
2801 for (j = 0; j < N0; j++)
2802 tmp[j*stride+i] = X[i*N0+j];
2805 for (i = 0; i < N; i++)
2806 X[i] = tmp[i];
2809 private void celt_deinterleave_hadamard (float *tmp, float *X, int N0, int stride, int hadamard)
2811 int i, j;
2812 int N = N0*stride;
2814 if (hadamard) {
2815 const(uint8_t)* ordery = celt_hadamard_ordery.ptr + stride - 2;
2816 for (i = 0; i < stride; i++)
2817 for (j = 0; j < N0; j++)
2818 tmp[ordery[i]*N0+j] = X[j*stride+i];
2819 } else {
2820 for (i = 0; i < stride; i++)
2821 for (j = 0; j < N0; j++)
2822 tmp[i*N0+j] = X[j*stride+i];
2825 for (i = 0; i < N; i++)
2826 X[i] = tmp[i];
2829 private void celt_haar1(float *X, int N0, int stride)
2831 int i, j;
2832 N0 >>= 1;
2833 for (i = 0; i < stride; i++) {
2834 for (j = 0; j < N0; j++) {
2835 float x0 = X[stride * (2 * j + 0) + i];
2836 float x1 = X[stride * (2 * j + 1) + i];
2837 X[stride * (2 * j + 0) + i] = (x0 + x1) * M_SQRT1_2;
2838 X[stride * (2 * j + 1) + i] = (x0 - x1) * M_SQRT1_2;
2843 /*static inline*/ int celt_compute_qn(int N, int b, int offset, int pulse_cap, int dualstereo)
2845 int qn, qb;
2846 int N2 = 2 * N - 1;
2847 if (dualstereo && N == 2)
2848 N2--;
2850 /* The upper limit ensures that in a stereo split with itheta==16384, we'll
2851 * always have enough bits left over to code at least one pulse in the
2852 * side; otherwise it would collapse, since it doesn't get folded. */
2853 qb = FFMIN3(b - pulse_cap - (4 << 3), (b + N2 * offset) / N2, 8 << 3);
2854 qn = (qb < (1 << 3 >> 1)) ? 1 : ((celt_qn_exp2[qb & 0x7] >> (14 - (qb >> 3))) + 1) >> 1 << 1;
2855 return qn;
2858 // this code was adapted from libopus
2859 /*static inline*/ uint64_t celt_cwrsi(uint N, uint K, uint i, int *y)
2861 uint64_t norm = 0;
2862 uint32_t p;
2863 int s, val;
2864 int k0;
2866 while (N > 2) {
2867 uint32_t q;
2869 /*Lots of pulses case:*/
2870 if (K >= N) {
2871 const uint32_t *row = celt_pvq_u_row[N];
2873 /* Are the pulses in this dimension negative? */
2874 p = row[K + 1];
2875 s = -(i >= p ? 1 : 0);
2876 i -= p & s;
2878 /*Count how many pulses were placed in this dimension.*/
2879 k0 = K;
2880 q = row[N];
2881 if (q > i) {
2882 K = N;
2883 do {
2884 p = celt_pvq_u_row[--K][N];
2885 } while (p > i);
2886 } else
2887 for (p = row[K]; p > i; p = row[K])
2888 K--;
2890 i -= p;
2891 val = (k0 - K + s) ^ s;
2892 norm += val * val;
2893 *y++ = val;
2894 } else { /*Lots of dimensions case:*/
2895 /*Are there any pulses in this dimension at all?*/
2896 p = celt_pvq_u_row[K ][N];
2897 q = celt_pvq_u_row[K + 1][N];
2899 if (p <= i && i < q) {
2900 i -= p;
2901 *y++ = 0;
2902 } else {
2903 /*Are the pulses in this dimension negative?*/
2904 s = -(i >= q ? 1 : 0);
2905 i -= q & s;
2907 /*Count how many pulses were placed in this dimension.*/
2908 k0 = K;
2909 do p = celt_pvq_u_row[--K][N];
2910 while (p > i);
2912 i -= p;
2913 val = (k0 - K + s) ^ s;
2914 norm += val * val;
2915 *y++ = val;
2918 N--;
2921 /* N == 2 */
2922 p = 2 * K + 1;
2923 s = -(i >= p ? 1 : 0);
2924 i -= p & s;
2925 k0 = K;
2926 K = (i + 1) / 2;
2928 if (K)
2929 i -= 2 * K - 1;
2931 val = (k0 - K + s) ^ s;
2932 norm += val * val;
2933 *y++ = val;
2935 /* N==1 */
2936 s = -i;
2937 val = (K + s) ^ s;
2938 norm += val * val;
2939 *y = val;
2941 return norm;
2944 /*static inline*/ float celt_decode_pulses(OpusRangeCoder *rc, int *y, uint N, uint K) {
2945 uint idx;
2946 //#define CELT_PVQ_U(n, k) (celt_pvq_u_row[FFMIN(n, k)][FFMAX(n, k)])
2947 //#define CELT_PVQ_V(n, k) (CELT_PVQ_U(n, k) + CELT_PVQ_U(n, (k) + 1))
2948 enum CELT_PVQ_U(string n, string k) = "(celt_pvq_u_row[FFMIN("~n~", "~k~")][FFMAX("~n~", "~k~")])";
2949 enum CELT_PVQ_V(string n, string k) = "("~CELT_PVQ_U!(n, k)~" + "~CELT_PVQ_U!(n, "("~k~") + 1")~")";
2950 idx = opus_rc_unimodel(rc, mixin(CELT_PVQ_V!("N", "K")));
2951 return celt_cwrsi(N, K, idx, y);
2954 /** Decode pulse vector and combine the result with the pitch vector to produce
2955 the final normalised signal in the current band. */
2956 /*static inline*/ uint celt_alg_unquant(OpusRangeCoder *rc, float *X, uint N, uint K, CeltSpread spread, uint blocks, float gain)
2958 import core.stdc.math : sqrtf;
2959 int[176] y = void;
2961 gain /= sqrtf(celt_decode_pulses(rc, y.ptr, N, K));
2962 celt_normalize_residual(y.ptr, X, N, gain);
2963 celt_exp_rotation(X, N, blocks, K, spread);
2964 return celt_extract_collapse_mask(y.ptr, N, blocks);
2967 /*static unsigned*/ int celt_decode_band(CeltContext *s, OpusRangeCoder *rc,
2968 const int band, float *X, float *Y,
2969 int N, int b, uint blocks,
2970 float *lowband, int duration,
2971 float *lowband_out, int level, float gain, float *lowband_scratch, int fill)
2973 import core.stdc.math : sqrtf;
2974 const(uint8_t)* cache;
2975 int dualstereo, split;
2976 int imid = 0, iside = 0;
2977 uint N0 = N;
2978 int N_B;
2979 int N_B0;
2980 int B0 = blocks;
2981 int time_divide = 0;
2982 int recombine = 0;
2983 int inv = 0;
2984 float mid = 0, side = 0;
2985 int longblocks = (B0 == 1);
2986 uint cm = 0;
2988 N_B0 = N_B = N / blocks;
2989 split = dualstereo = (Y !is null);
2991 if (N == 1) {
2992 /* special case for one sample */
2993 int i;
2994 float *x = X;
2995 for (i = 0; i <= dualstereo; i++) {
2996 int sign = 0;
2997 if (s.remaining2 >= 1<<3) {
2998 sign = opus_getrawbits(rc, 1);
2999 s.remaining2 -= 1 << 3;
3000 b -= 1 << 3;
3002 x[0] = sign ? -1.0f : 1.0f;
3003 x = Y;
3005 if (lowband_out)
3006 lowband_out[0] = X[0];
3007 return 1;
3010 if (!dualstereo && level == 0) {
3011 int tf_change = s.tf_change[band];
3012 int k;
3013 if (tf_change > 0)
3014 recombine = tf_change;
3015 /* Band recombining to increase frequency resolution */
3017 if (lowband &&
3018 (recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) {
3019 int j;
3020 for (j = 0; j < N; j++)
3021 lowband_scratch[j] = lowband[j];
3022 lowband = lowband_scratch;
3025 for (k = 0; k < recombine; k++) {
3026 if (lowband)
3027 celt_haar1(lowband, N >> k, 1 << k);
3028 fill = celt_bit_interleave[fill & 0xF] | celt_bit_interleave[fill >> 4] << 2;
3030 blocks >>= recombine;
3031 N_B <<= recombine;
3033 /* Increasing the time resolution */
3034 while ((N_B & 1) == 0 && tf_change < 0) {
3035 if (lowband)
3036 celt_haar1(lowband, N_B, blocks);
3037 fill |= fill << blocks;
3038 blocks <<= 1;
3039 N_B >>= 1;
3040 time_divide++;
3041 tf_change++;
3043 B0 = blocks;
3044 N_B0 = N_B;
3046 /* Reorganize the samples in time order instead of frequency order */
3047 if (B0 > 1 && lowband)
3048 celt_deinterleave_hadamard(s.scratch.ptr, lowband, N_B >> recombine, B0 << recombine, longblocks);
3051 /* If we need 1.5 more bit than we can produce, split the band in two. */
3052 cache = celt_cache_bits.ptr + celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band];
3053 if (!dualstereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) {
3054 N >>= 1;
3055 Y = X + N;
3056 split = 1;
3057 duration -= 1;
3058 if (blocks == 1)
3059 fill = (fill & 1) | (fill << 1);
3060 blocks = (blocks + 1) >> 1;
3063 if (split) {
3064 int qn;
3065 int itheta = 0;
3066 int mbits, sbits, delta;
3067 int qalloc;
3068 int pulse_cap;
3069 int offset;
3070 int orig_fill;
3071 int tell;
3073 /* Decide on the resolution to give to the split parameter theta */
3074 pulse_cap = celt_log_freq_range[band] + duration * 8;
3075 offset = (pulse_cap >> 1) - (dualstereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE :
3076 CELT_QTHETA_OFFSET);
3077 qn = (dualstereo && band >= s.intensitystereo) ? 1 :
3078 celt_compute_qn(N, b, offset, pulse_cap, dualstereo);
3079 tell = opus_rc_tell_frac(rc);
3080 if (qn != 1) {
3081 /* Entropy coding of the angle. We use a uniform pdf for the
3082 time split, a step for stereo, and a triangular one for the rest. */
3083 if (dualstereo && N > 2)
3084 itheta = opus_rc_stepmodel(rc, qn/2);
3085 else if (dualstereo || B0 > 1)
3086 itheta = opus_rc_unimodel(rc, qn+1);
3087 else
3088 itheta = opus_rc_trimodel(rc, qn);
3089 itheta = itheta * 16384 / qn;
3090 /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.
3091 Let's do that at higher complexity */
3092 } else if (dualstereo) {
3093 inv = (b > 2 << 3 && s.remaining2 > 2 << 3) ? opus_rc_p2model(rc, 2) : 0;
3094 itheta = 0;
3096 qalloc = opus_rc_tell_frac(rc) - tell;
3097 b -= qalloc;
3099 orig_fill = fill;
3100 if (itheta == 0) {
3101 imid = 32767;
3102 iside = 0;
3103 fill = av_mod_uintp2(fill, blocks);
3104 delta = -16384;
3105 } else if (itheta == 16384) {
3106 imid = 0;
3107 iside = 32767;
3108 fill &= ((1 << blocks) - 1) << blocks;
3109 delta = 16384;
3110 } else {
3111 imid = celt_cos(cast(short)itheta);
3112 iside = celt_cos(cast(short)(16384-itheta));
3113 /* This is the mid vs side allocation that minimizes squared error
3114 in that band. */
3115 delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid));
3118 mid = imid / 32768.0f;
3119 side = iside / 32768.0f;
3121 /* This is a special case for N=2 that only works for stereo and takes
3122 advantage of the fact that mid and side are orthogonal to encode
3123 the side with just one bit. */
3124 if (N == 2 && dualstereo) {
3125 int c;
3126 int sign = 0;
3127 float tmp;
3128 float* x2, y2;
3129 mbits = b;
3130 /* Only need one bit for the side */
3131 sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0;
3132 mbits -= sbits;
3133 c = (itheta > 8192);
3134 s.remaining2 -= qalloc+sbits;
3136 x2 = c ? Y : X;
3137 y2 = c ? X : Y;
3138 if (sbits)
3139 sign = opus_getrawbits(rc, 1);
3140 sign = 1 - 2 * sign;
3141 /* We use orig_fill here because we want to fold the side, but if
3142 itheta==16384, we'll have cleared the low bits of fill. */
3143 cm = celt_decode_band(s, rc, band, x2, null, N, mbits, blocks,
3144 lowband, duration, lowband_out, level, gain,
3145 lowband_scratch, orig_fill);
3146 /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
3147 and there's no need to worry about mixing with the other channel. */
3148 y2[0] = -sign * x2[1];
3149 y2[1] = sign * x2[0];
3150 X[0] *= mid;
3151 X[1] *= mid;
3152 Y[0] *= side;
3153 Y[1] *= side;
3154 tmp = X[0];
3155 X[0] = tmp - Y[0];
3156 Y[0] = tmp + Y[0];
3157 tmp = X[1];
3158 X[1] = tmp - Y[1];
3159 Y[1] = tmp + Y[1];
3160 } else {
3161 /* "Normal" split code */
3162 float *next_lowband2 = null;
3163 float *next_lowband_out1 = null;
3164 int next_level = 0;
3165 int rebalance;
3167 /* Give more bits to low-energy MDCTs than they would
3168 * otherwise deserve */
3169 if (B0 > 1 && !dualstereo && (itheta & 0x3fff)) {
3170 if (itheta > 8192)
3171 /* Rough approximation for pre-echo masking */
3172 delta -= delta >> (4 - duration);
3173 else
3174 /* Corresponds to a forward-masking slope of
3175 * 1.5 dB per 10 ms */
3176 delta = FFMIN(0, delta + (N << 3 >> (5 - duration)));
3178 mbits = av_clip((b - delta) / 2, 0, b);
3179 sbits = b - mbits;
3180 s.remaining2 -= qalloc;
3182 if (lowband && !dualstereo)
3183 next_lowband2 = lowband + N; /* >32-bit split case */
3185 /* Only stereo needs to pass on lowband_out.
3186 * Otherwise, it's handled at the end */
3187 if (dualstereo)
3188 next_lowband_out1 = lowband_out;
3189 else
3190 next_level = level + 1;
3192 rebalance = s.remaining2;
3193 if (mbits >= sbits) {
3194 /* In stereo mode, we do not apply a scaling to the mid
3195 * because we need the normalized mid for folding later */
3196 cm = celt_decode_band(s, rc, band, X, null, N, mbits, blocks,
3197 lowband, duration, next_lowband_out1,
3198 next_level, dualstereo ? 1.0f : (gain * mid),
3199 lowband_scratch, fill);
3201 rebalance = mbits - (rebalance - s.remaining2);
3202 if (rebalance > 3 << 3 && itheta != 0)
3203 sbits += rebalance - (3 << 3);
3205 /* For a stereo split, the high bits of fill are always zero,
3206 * so no folding will be done to the side. */
3207 cm |= celt_decode_band(s, rc, band, Y, null, N, sbits, blocks,
3208 next_lowband2, duration, null,
3209 next_level, gain * side, null,
3210 fill >> blocks) << ((B0 >> 1) & (dualstereo - 1));
3211 } else {
3212 /* For a stereo split, the high bits of fill are always zero,
3213 * so no folding will be done to the side. */
3214 cm = celt_decode_band(s, rc, band, Y, null, N, sbits, blocks,
3215 next_lowband2, duration, null,
3216 next_level, gain * side, null,
3217 fill >> blocks) << ((B0 >> 1) & (dualstereo - 1));
3219 rebalance = sbits - (rebalance - s.remaining2);
3220 if (rebalance > 3 << 3 && itheta != 16384)
3221 mbits += rebalance - (3 << 3);
3223 /* In stereo mode, we do not apply a scaling to the mid because
3224 * we need the normalized mid for folding later */
3225 cm |= celt_decode_band(s, rc, band, X, null, N, mbits, blocks,
3226 lowband, duration, next_lowband_out1,
3227 next_level, dualstereo ? 1.0f : (gain * mid),
3228 lowband_scratch, fill);
3231 } else {
3232 /* This is the basic no-split case */
3233 uint q = celt_bits2pulses(cache, b);
3234 uint curr_bits = celt_pulses2bits(cache, q);
3235 s.remaining2 -= curr_bits;
3237 /* Ensures we can never bust the budget */
3238 while (s.remaining2 < 0 && q > 0) {
3239 s.remaining2 += curr_bits;
3240 curr_bits = celt_pulses2bits(cache, --q);
3241 s.remaining2 -= curr_bits;
3244 if (q != 0) {
3245 /* Finally do the actual quantization */
3246 cm = celt_alg_unquant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
3247 s.spread, blocks, gain);
3248 } else {
3249 /* If there's no pulse, fill the band anyway */
3250 int j;
3251 uint cm_mask = (1 << blocks) - 1;
3252 fill &= cm_mask;
3253 if (!fill) {
3254 for (j = 0; j < N; j++)
3255 X[j] = 0.0f;
3256 } else {
3257 if (!lowband) {
3258 /* Noise */
3259 for (j = 0; j < N; j++)
3260 X[j] = ((cast(int32_t)celt_rng(s)) >> 20);
3261 cm = cm_mask;
3262 } else {
3263 /* Folded spectrum */
3264 for (j = 0; j < N; j++) {
3265 /* About 48 dB below the "normal" folding level */
3266 X[j] = lowband[j] + (((celt_rng(s)) & 0x8000) ? 1.0f / 256 : -1.0f / 256);
3268 cm = fill;
3270 celt_renormalize_vector(X, N, gain);
3275 /* This code is used by the decoder and by the resynthesis-enabled encoder */
3276 if (dualstereo) {
3277 int j;
3278 if (N != 2)
3279 celt_stereo_merge(X, Y, mid, N);
3280 if (inv) {
3281 for (j = 0; j < N; j++)
3282 Y[j] *= -1;
3284 } else if (level == 0) {
3285 int k;
3287 /* Undo the sample reorganization going from time order to frequency order */
3288 if (B0 > 1)
3289 celt_interleave_hadamard(s.scratch.ptr, X, N_B>>recombine, B0<<recombine, longblocks);
3291 /* Undo time-freq changes that we did earlier */
3292 N_B = N_B0;
3293 blocks = B0;
3294 for (k = 0; k < time_divide; k++) {
3295 blocks >>= 1;
3296 N_B <<= 1;
3297 cm |= cm >> blocks;
3298 celt_haar1(X, N_B, blocks);
3301 for (k = 0; k < recombine; k++) {
3302 cm = celt_bit_deinterleave[cm];
3303 celt_haar1(X, N0>>k, 1<<k);
3305 blocks <<= recombine;
3307 /* Scale output for later folding */
3308 if (lowband_out) {
3309 int j;
3310 float n = sqrtf(N0);
3311 for (j = 0; j < N0; j++)
3312 lowband_out[j] = n * X[j];
3314 cm = av_mod_uintp2(cm, blocks);
3316 return cm;
3319 private void celt_denormalize(CeltContext *s, CeltFrame *frame, float *data)
3321 import std.math : exp2;
3322 int i, j;
3324 for (i = s.startband; i < s.endband; i++) {
3325 float *dst = data + (celt_freq_bands[i] << s.duration);
3326 float norm = exp2(frame.energy[i] + celt_mean_energy[i]);
3328 for (j = 0; j < celt_freq_range[i] << s.duration; j++)
3329 dst[j] *= norm;
3333 private void celt_postfilter_apply_transition(CeltFrame *frame, float *data)
3335 const int T0 = frame.pf_period_old;
3336 const int T1 = frame.pf_period;
3338 float g00, g01, g02;
3339 float g10, g11, g12;
3341 float x0, x1, x2, x3, x4;
3343 int i;
3345 if (frame.pf_gains[0] == 0.0 &&
3346 frame.pf_gains_old[0] == 0.0)
3347 return;
3349 g00 = frame.pf_gains_old[0];
3350 g01 = frame.pf_gains_old[1];
3351 g02 = frame.pf_gains_old[2];
3352 g10 = frame.pf_gains[0];
3353 g11 = frame.pf_gains[1];
3354 g12 = frame.pf_gains[2];
3356 x1 = data[-T1 + 1];
3357 x2 = data[-T1];
3358 x3 = data[-T1 - 1];
3359 x4 = data[-T1 - 2];
3361 for (i = 0; i < CELT_OVERLAP; i++) {
3362 float w = ff_celt_window2[i];
3363 x0 = data[i - T1 + 2];
3365 data[i] += (1.0 - w) * g00 * data[i - T0] +
3366 (1.0 - w) * g01 * (data[i - T0 - 1] + data[i - T0 + 1]) +
3367 (1.0 - w) * g02 * (data[i - T0 - 2] + data[i - T0 + 2]) +
3368 w * g10 * x2 +
3369 w * g11 * (x1 + x3) +
3370 w * g12 * (x0 + x4);
3371 x4 = x3;
3372 x3 = x2;
3373 x2 = x1;
3374 x1 = x0;
3378 private void celt_postfilter_apply(CeltFrame *frame, float *data, int len)
3380 const int T = frame.pf_period;
3381 float g0, g1, g2;
3382 float x0, x1, x2, x3, x4;
3383 int i;
3385 if (frame.pf_gains[0] == 0.0 || len <= 0)
3386 return;
3388 g0 = frame.pf_gains[0];
3389 g1 = frame.pf_gains[1];
3390 g2 = frame.pf_gains[2];
3392 x4 = data[-T - 2];
3393 x3 = data[-T - 1];
3394 x2 = data[-T];
3395 x1 = data[-T + 1];
3397 for (i = 0; i < len; i++) {
3398 x0 = data[i - T + 2];
3399 data[i] += g0 * x2 +
3400 g1 * (x1 + x3) +
3401 g2 * (x0 + x4);
3402 x4 = x3;
3403 x3 = x2;
3404 x2 = x1;
3405 x1 = x0;
3409 private void celt_postfilter(CeltContext *s, CeltFrame *frame)
3411 import core.stdc.string : memcpy, memmove;
3412 int len = s.blocksize * s.blocks;
3414 celt_postfilter_apply_transition(frame, frame.buf.ptr + 1024);
3416 frame.pf_period_old = frame.pf_period;
3417 memcpy(frame.pf_gains_old.ptr, frame.pf_gains.ptr, frame.pf_gains.sizeof);
3419 frame.pf_period = frame.pf_period_new;
3420 memcpy(frame.pf_gains.ptr, frame.pf_gains_new.ptr, frame.pf_gains.sizeof);
3422 if (len > CELT_OVERLAP) {
3423 celt_postfilter_apply_transition(frame, frame.buf.ptr + 1024 + CELT_OVERLAP);
3424 celt_postfilter_apply(frame, frame.buf.ptr + 1024 + 2 * CELT_OVERLAP, len - 2 * CELT_OVERLAP);
3426 frame.pf_period_old = frame.pf_period;
3427 memcpy(frame.pf_gains_old.ptr, frame.pf_gains.ptr, frame.pf_gains.sizeof);
3430 memmove(frame.buf.ptr, frame.buf.ptr + len, (1024 + CELT_OVERLAP / 2) * float.sizeof);
3433 private int parse_postfilter(CeltContext *s, OpusRangeCoder *rc, int consumed)
3435 import core.stdc.string : memset;
3436 static immutable float[3][3] postfilter_taps = [
3437 [ 0.3066406250f, 0.2170410156f, 0.1296386719f ],
3438 [ 0.4638671875f, 0.2680664062f, 0.0 ],
3439 [ 0.7998046875f, 0.1000976562f, 0.0 ],
3441 int i;
3443 memset(s.frame[0].pf_gains_new.ptr, 0, (s.frame[0].pf_gains_new).sizeof);
3444 memset(s.frame[1].pf_gains_new.ptr, 0, (s.frame[1].pf_gains_new).sizeof);
3446 if (s.startband == 0 && consumed + 16 <= s.framebits) {
3447 int has_postfilter = opus_rc_p2model(rc, 1);
3448 if (has_postfilter) {
3449 float gain;
3450 int tapset, octave, period;
3452 octave = opus_rc_unimodel(rc, 6);
3453 period = (16 << octave) + opus_getrawbits(rc, 4 + octave) - 1;
3454 gain = 0.09375f * (opus_getrawbits(rc, 3) + 1);
3455 tapset = (opus_rc_tell(rc) + 2 <= s.framebits) ?
3456 opus_rc_getsymbol(rc, celt_model_tapset.ptr) : 0;
3458 for (i = 0; i < 2; i++) {
3459 CeltFrame *frame = &s.frame[i];
3461 frame.pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
3462 frame.pf_gains_new[0] = gain * postfilter_taps[tapset][0];
3463 frame.pf_gains_new[1] = gain * postfilter_taps[tapset][1];
3464 frame.pf_gains_new[2] = gain * postfilter_taps[tapset][2];
3468 consumed = opus_rc_tell(rc);
3471 return consumed;
3474 private void process_anticollapse(CeltContext *s, CeltFrame *frame, float *X)
3476 import core.stdc.math : exp2f, exp2, sqrtf;
3477 int i, j, k;
3479 for (i = s.startband; i < s.endband; i++) {
3480 int renormalize = 0;
3481 float *xptr;
3482 float[2] prev;
3483 float Ediff, r;
3484 float thresh, sqrt_1;
3485 int depth;
3487 /* depth in 1/8 bits */
3488 depth = (1 + s.pulses[i]) / (celt_freq_range[i] << s.duration);
3489 thresh = exp2f(-1.0 - 0.125f * depth);
3490 sqrt_1 = 1.0f / sqrtf(celt_freq_range[i] << s.duration);
3492 xptr = X + (celt_freq_bands[i] << s.duration);
3494 prev[0] = frame.prev_energy[0][i];
3495 prev[1] = frame.prev_energy[1][i];
3496 if (s.coded_channels == 1) {
3497 CeltFrame *frame1 = &s.frame[1];
3499 prev[0] = FFMAX(prev[0], frame1.prev_energy[0][i]);
3500 prev[1] = FFMAX(prev[1], frame1.prev_energy[1][i]);
3502 Ediff = frame.energy[i] - FFMIN(prev[0], prev[1]);
3503 Ediff = FFMAX(0, Ediff);
3505 /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
3506 short blocks don't have the same energy as long */
3507 r = exp2(1 - Ediff);
3508 if (s.duration == 3)
3509 r *= M_SQRT2;
3510 r = FFMIN(thresh, r) * sqrt_1;
3511 for (k = 0; k < 1 << s.duration; k++) {
3512 /* Detect collapse */
3513 if (!(frame.collapse_masks[i] & 1 << k)) {
3514 /* Fill with noise */
3515 for (j = 0; j < celt_freq_range[i]; j++)
3516 xptr[(j << s.duration) + k] = (celt_rng(s) & 0x8000) ? r : -r;
3517 renormalize = 1;
3521 /* We just added some energy, so we need to renormalize */
3522 if (renormalize)
3523 celt_renormalize_vector(xptr, celt_freq_range[i] << s.duration, 1.0f);
3527 private void celt_decode_bands(CeltContext *s, OpusRangeCoder *rc)
3529 import core.stdc.string : memset;
3530 float[8 * 22] lowband_scratch = void;
3531 float[2 * 8 * 100] norm = void;
3533 int totalbits = (s.framebits << 3) - s.anticollapse_bit;
3535 int update_lowband = 1;
3536 int lowband_offset = 0;
3538 int i, j;
3540 memset(s.coeffs.ptr, 0, s.coeffs.sizeof);
3542 for (i = s.startband; i < s.endband; i++) {
3543 int band_offset = celt_freq_bands[i] << s.duration;
3544 int band_size = celt_freq_range[i] << s.duration;
3545 float *X = s.coeffs[0].ptr + band_offset;
3546 float *Y = (s.coded_channels == 2) ? s.coeffs[1].ptr + band_offset : null;
3548 int consumed = opus_rc_tell_frac(rc);
3549 float *norm2 = norm.ptr + 8 * 100;
3550 int effective_lowband = -1;
3551 uint[2] cm;
3552 int b;
3554 /* Compute how many bits we want to allocate to this band */
3555 if (i != s.startband)
3556 s.remaining -= consumed;
3557 s.remaining2 = totalbits - consumed - 1;
3558 if (i <= s.codedbands - 1) {
3559 int curr_balance = s.remaining / FFMIN(3, s.codedbands-i);
3560 b = av_clip_uintp2(FFMIN(s.remaining2 + 1, s.pulses[i] + curr_balance), 14);
3561 } else
3562 b = 0;
3564 if (celt_freq_bands[i] - celt_freq_range[i] >= celt_freq_bands[s.startband] &&
3565 (update_lowband || lowband_offset == 0))
3566 lowband_offset = i;
3568 /* Get a conservative estimate of the collapse_mask's for the bands we're
3569 going to be folding from. */
3570 if (lowband_offset != 0 && (s.spread != CELT_SPREAD_AGGRESSIVE ||
3571 s.blocks > 1 || s.tf_change[i] < 0)) {
3572 int foldstart, foldend;
3574 /* This ensures we never repeat spectral content within one band */
3575 effective_lowband = FFMAX(celt_freq_bands[s.startband],
3576 celt_freq_bands[lowband_offset] - celt_freq_range[i]);
3577 foldstart = lowband_offset;
3578 while (celt_freq_bands[--foldstart] > effective_lowband) {}
3579 foldend = lowband_offset - 1;
3580 while (celt_freq_bands[++foldend] < effective_lowband + celt_freq_range[i]) {}
3582 cm[0] = cm[1] = 0;
3583 for (j = foldstart; j < foldend; j++) {
3584 cm[0] |= s.frame[0].collapse_masks[j];
3585 cm[1] |= s.frame[s.coded_channels - 1].collapse_masks[j];
3587 } else
3588 /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost
3589 always) be non-zero.*/
3590 cm[0] = cm[1] = (1 << s.blocks) - 1;
3592 if (s.dualstereo && i == s.intensitystereo) {
3593 /* Switch off dual stereo to do intensity */
3594 s.dualstereo = 0;
3595 for (j = celt_freq_bands[s.startband] << s.duration; j < band_offset; j++)
3596 norm[j] = (norm[j] + norm2[j]) / 2;
3599 if (s.dualstereo) {
3600 cm[0] = celt_decode_band(s, rc, i, X, null, band_size, b / 2, s.blocks,
3601 effective_lowband != -1 ? norm.ptr + (effective_lowband << s.duration) : null, s.duration,
3602 norm.ptr + band_offset, 0, 1.0f, lowband_scratch.ptr, cm[0]);
3604 cm[1] = celt_decode_band(s, rc, i, Y, null, band_size, b/2, s.blocks,
3605 effective_lowband != -1 ? norm2 + (effective_lowband << s.duration) : null, s.duration,
3606 norm2 + band_offset, 0, 1.0f, lowband_scratch.ptr, cm[1]);
3607 } else {
3608 cm[0] = celt_decode_band(s, rc, i, X, Y, band_size, b, s.blocks,
3609 effective_lowband != -1 ? norm.ptr + (effective_lowband << s.duration) : null, s.duration,
3610 norm.ptr + band_offset, 0, 1.0f, lowband_scratch.ptr, cm[0]|cm[1]);
3612 cm[1] = cm[0];
3615 s.frame[0].collapse_masks[i] = cast(uint8_t)cm[0];
3616 s.frame[s.coded_channels - 1].collapse_masks[i] = cast(uint8_t)cm[1];
3617 s.remaining += s.pulses[i] + consumed;
3619 /* Update the folding position only as long as we have 1 bit/sample depth */
3620 update_lowband = (b > band_size << 3);
3624 int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc,
3625 float **output, int coded_channels, int frame_size,
3626 int startband, int endband)
3628 import core.stdc.string : memcpy, memset;
3629 int i, j;
3631 int consumed; // bits of entropy consumed thus far for this frame
3632 int silence = 0;
3633 int transient = 0;
3634 int anticollapse = 0;
3635 IMDCT15Context *imdct;
3636 float imdct_scale = 1.0;
3638 if (coded_channels != 1 && coded_channels != 2) {
3639 //av_log(AV_LOG_ERROR, "Invalid number of coded channels: %d\n", coded_channels);
3640 return AVERROR_INVALIDDATA;
3642 if (startband < 0 || startband > endband || endband > CELT_MAX_BANDS) {
3643 //av_log(AV_LOG_ERROR, "Invalid start/end band: %d %d\n", startband, endband);
3644 return AVERROR_INVALIDDATA;
3647 s.flushed = 0;
3648 s.coded_channels = coded_channels;
3649 s.startband = startband;
3650 s.endband = endband;
3651 s.framebits = rc.rb.bytes * 8;
3653 s.duration = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
3654 if (s.duration > CELT_MAX_LOG_BLOCKS ||
3655 frame_size != CELT_SHORT_BLOCKSIZE * (1 << s.duration)) {
3656 //av_log(AV_LOG_ERROR, "Invalid CELT frame size: %d\n", frame_size);
3657 return AVERROR_INVALIDDATA;
3660 if (!s.output_channels)
3661 s.output_channels = coded_channels;
3663 memset(s.frame[0].collapse_masks.ptr, 0, s.frame[0].collapse_masks.sizeof);
3664 memset(s.frame[1].collapse_masks.ptr, 0, s.frame[1].collapse_masks.sizeof);
3666 consumed = opus_rc_tell(rc);
3668 /* obtain silence flag */
3669 if (consumed >= s.framebits)
3670 silence = 1;
3671 else if (consumed == 1)
3672 silence = opus_rc_p2model(rc, 15);
3675 if (silence) {
3676 consumed = s.framebits;
3677 rc.total_read_bits += s.framebits - opus_rc_tell(rc);
3680 /* obtain post-filter options */
3681 consumed = parse_postfilter(s, rc, consumed);
3683 /* obtain transient flag */
3684 if (s.duration != 0 && consumed+3 <= s.framebits)
3685 transient = opus_rc_p2model(rc, 3);
3687 s.blocks = transient ? 1 << s.duration : 1;
3688 s.blocksize = frame_size / s.blocks;
3690 imdct = s.imdct[transient ? 0 : s.duration];
3692 if (coded_channels == 1) {
3693 for (i = 0; i < CELT_MAX_BANDS; i++)
3694 s.frame[0].energy[i] = FFMAX(s.frame[0].energy[i], s.frame[1].energy[i]);
3697 celt_decode_coarse_energy(s, rc);
3698 celt_decode_tf_changes (s, rc, transient);
3699 celt_decode_allocation (s, rc);
3700 celt_decode_fine_energy (s, rc);
3701 celt_decode_bands (s, rc);
3703 if (s.anticollapse_bit)
3704 anticollapse = opus_getrawbits(rc, 1);
3706 celt_decode_final_energy(s, rc, s.framebits - opus_rc_tell(rc));
3708 /* apply anti-collapse processing and denormalization to
3709 * each coded channel */
3710 for (i = 0; i < s.coded_channels; i++) {
3711 CeltFrame *frame = &s.frame[i];
3713 if (anticollapse)
3714 process_anticollapse(s, frame, s.coeffs[i].ptr);
3716 celt_denormalize(s, frame, s.coeffs[i].ptr);
3719 /* stereo . mono downmix */
3720 if (s.output_channels < s.coded_channels) {
3721 vector_fmac_scalar(s.coeffs[0].ptr, s.coeffs[1].ptr, 1.0f, /*FFALIGN(frame_size, 16)*/frame_size);
3722 imdct_scale = 0.5;
3723 } else if (s.output_channels > s.coded_channels)
3724 memcpy(s.coeffs[1].ptr, s.coeffs[0].ptr, frame_size * float.sizeof);
3726 if (silence) {
3727 for (i = 0; i < 2; i++) {
3728 CeltFrame *frame = &s.frame[i];
3730 for (j = 0; j < /*FF_ARRAY_ELEMS*/frame.energy.length; j++)
3731 frame.energy[j] = CELT_ENERGY_SILENCE;
3733 memset(s.coeffs.ptr, 0, s.coeffs.sizeof);
3736 /* transform and output for each output channel */
3737 for (i = 0; i < s.output_channels; i++) {
3738 CeltFrame *frame = &s.frame[i];
3739 float m = frame.deemph_coeff;
3741 /* iMDCT and overlap-add */
3742 for (j = 0; j < s.blocks; j++) {
3743 float *dst = frame.buf.ptr + 1024 + j * s.blocksize;
3745 imdct.imdct_half(imdct, dst + CELT_OVERLAP / 2, s.coeffs[i].ptr + j, s.blocks, imdct_scale);
3746 vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2, celt_window.ptr, CELT_OVERLAP / 2);
3749 /* postfilter */
3750 celt_postfilter(s, frame);
3752 /* deemphasis and output scaling */
3753 for (j = 0; j < frame_size; j++) {
3754 float tmp = frame.buf[1024 - frame_size + j] + m;
3755 m = tmp * CELT_DEEMPH_COEFF;
3756 output[i][j] = tmp / 32768.;
3758 frame.deemph_coeff = m;
3761 if (coded_channels == 1)
3762 memcpy(s.frame[1].energy.ptr, s.frame[0].energy.ptr, s.frame[0].energy.sizeof);
3764 for (i = 0; i < 2; i++ ) {
3765 CeltFrame *frame = &s.frame[i];
3767 if (!transient) {
3768 memcpy(frame.prev_energy[1].ptr, frame.prev_energy[0].ptr, frame.prev_energy[0].sizeof);
3769 memcpy(frame.prev_energy[0].ptr, frame.energy.ptr, frame.prev_energy[0].sizeof);
3770 } else {
3771 for (j = 0; j < CELT_MAX_BANDS; j++)
3772 frame.prev_energy[0][j] = FFMIN(frame.prev_energy[0][j], frame.energy[j]);
3775 for (j = 0; j < s.startband; j++) {
3776 frame.prev_energy[0][j] = CELT_ENERGY_SILENCE;
3777 frame.energy[j] = 0.0;
3779 for (j = s.endband; j < CELT_MAX_BANDS; j++) {
3780 frame.prev_energy[0][j] = CELT_ENERGY_SILENCE;
3781 frame.energy[j] = 0.0;
3785 s.seed = rc.range;
3787 return 0;
3790 void ff_celt_flush(CeltContext *s)
3792 import core.stdc.string : memset;
3793 int i, j;
3795 if (s.flushed)
3796 return;
3798 for (i = 0; i < 2; i++) {
3799 CeltFrame *frame = &s.frame[i];
3801 for (j = 0; j < CELT_MAX_BANDS; j++)
3802 frame.prev_energy[0][j] = frame.prev_energy[1][j] = CELT_ENERGY_SILENCE;
3804 memset(frame.energy.ptr, 0, frame.energy.sizeof);
3805 memset(frame.buf.ptr, 0, frame.buf.sizeof);
3807 memset(frame.pf_gains.ptr, 0, frame.pf_gains.sizeof);
3808 memset(frame.pf_gains_old.ptr, 0, frame.pf_gains_old.sizeof);
3809 memset(frame.pf_gains_new.ptr, 0, frame.pf_gains_new.sizeof);
3811 frame.deemph_coeff = 0.0;
3813 s.seed = 0;
3815 s.flushed = 1;
3818 void ff_celt_free(CeltContext **ps)
3820 CeltContext *s = *ps;
3821 int i;
3823 if (!s)
3824 return;
3826 for (i = 0; i < /*FF_ARRAY_ELEMS*/s.imdct.length; i++)
3827 ff_imdct15_uninit(&s.imdct[i]);
3829 //av_freep(&s.dsp);
3830 av_freep(ps);
3833 int ff_celt_init(/*AVCodecContext *avctx,*/ CeltContext **ps, int output_channels)
3835 CeltContext *s;
3836 int i, ret;
3838 if (output_channels != 1 && output_channels != 2) {
3839 //av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n", output_channels);
3840 return AVERROR(EINVAL);
3843 s = av_mallocz!CeltContext();
3844 if (!s)
3845 return AVERROR(ENOMEM);
3847 //s.avctx = avctx;
3848 s.output_channels = output_channels;
3850 for (i = 0; i < /*FF_ARRAY_ELEMS*/s.imdct.length; i++) {
3851 ret = ff_imdct15_init(&s.imdct[i], i + 3);
3852 if (ret < 0)
3853 goto fail;
3856 //!!!s.dsp = avpriv_float_dsp_alloc(avctx.flags & AV_CODEC_FLAG_BITEXACT);
3857 /*if (!s.dsp) {
3858 ret = AVERROR(ENOMEM);
3859 goto fail;
3862 ff_celt_flush(s);
3864 *ps = s;
3866 return 0;
3867 fail:
3868 ff_celt_free(&s);
3869 return ret;
3873 struct SilkFrame {
3874 int coded;
3875 int log_gain;
3876 int16_t[16] nlsf;
3877 float[16] lpc;
3879 float[2 * SILK_HISTORY] output;
3880 float[2 * SILK_HISTORY] lpc_history;
3881 int primarylag;
3883 int prev_voiced;
3886 struct SilkContext {
3887 //AVCodecContext *avctx;
3888 int output_channels;
3890 int midonly;
3891 int subframes;
3892 int sflength;
3893 int flength;
3894 int nlsf_interp_factor;
3896 OpusBandwidth bandwidth;
3897 int wb;
3899 SilkFrame[2] frame;
3900 float[2] prev_stereo_weights;
3901 float[2] stereo_weights;
3903 int prev_coded_channels;
3906 static immutable uint16_t[26] silk_model_stereo_s1 = [
3907 256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200,
3908 201, 202, 210, 234, 244, 245, 246, 247, 249, 256
3911 static immutable uint16_t[4] silk_model_stereo_s2 = [256, 85, 171, 256];
3913 static immutable uint16_t[6] silk_model_stereo_s3 = [256, 51, 102, 154, 205, 256];
3915 static immutable uint16_t[3] silk_model_mid_only = [256, 192, 256];
3917 static immutable uint16_t[3] silk_model_frame_type_inactive = [256, 26, 256];
3919 static immutable uint16_t[5] silk_model_frame_type_active = [256, 24, 98, 246, 256];
3921 static immutable uint16_t[9][3] silk_model_gain_highbits = [
3922 [256, 32, 144, 212, 241, 253, 254, 255, 256],
3923 [256, 2, 19, 64, 124, 186, 233, 252, 256],
3924 [256, 1, 4, 30, 101, 195, 245, 254, 256]
3927 static immutable uint16_t[9] silk_model_gain_lowbits = [256, 32, 64, 96, 128, 160, 192, 224, 256];
3929 static immutable uint16_t[42] silk_model_gain_delta = [
3930 256, 6, 11, 22, 53, 185, 206, 214, 218, 221, 223, 225, 227, 228, 229, 230,
3931 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
3932 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
3934 static immutable uint16_t[33][2][2] silk_model_lsf_s1 = [
3936 [ // NB or MB, unvoiced
3937 256, 44, 78, 108, 127, 148, 160, 171, 174, 177, 179, 195, 197, 199, 200, 205,
3938 207, 208, 211, 214, 215, 216, 218, 220, 222, 225, 226, 235, 244, 246, 253, 255, 256
3939 ], [ // NB or MB, voiced
3940 256, 1, 11, 12, 20, 23, 31, 39, 53, 66, 80, 81, 95, 107, 120, 131,
3941 142, 154, 165, 175, 185, 196, 204, 213, 221, 228, 236, 237, 238, 244, 245, 251, 256
3943 ], [
3944 [ // WB, unvoiced
3945 256, 31, 52, 55, 72, 73, 81, 98, 102, 103, 121, 137, 141, 143, 146, 147,
3946 157, 158, 161, 177, 188, 204, 206, 208, 211, 213, 224, 225, 229, 238, 246, 253, 256
3947 ], [ // WB, voiced
3948 256, 1, 5, 21, 26, 44, 55, 60, 74, 89, 90, 93, 105, 118, 132, 146,
3949 152, 166, 178, 180, 186, 187, 199, 211, 222, 232, 235, 245, 250, 251, 252, 253, 256
3954 static immutable uint16_t[10][32] silk_model_lsf_s2 = [
3955 // NB, MB
3956 [ 256, 1, 2, 3, 18, 242, 253, 254, 255, 256 ],
3957 [ 256, 1, 2, 4, 38, 221, 253, 254, 255, 256 ],
3958 [ 256, 1, 2, 6, 48, 197, 252, 254, 255, 256 ],
3959 [ 256, 1, 2, 10, 62, 185, 246, 254, 255, 256 ],
3960 [ 256, 1, 4, 20, 73, 174, 248, 254, 255, 256 ],
3961 [ 256, 1, 4, 21, 76, 166, 239, 254, 255, 256 ],
3962 [ 256, 1, 8, 32, 85, 159, 226, 252, 255, 256 ],
3963 [ 256, 1, 2, 20, 83, 161, 219, 249, 255, 256 ],
3965 // WB
3966 [ 256, 1, 2, 3, 12, 244, 253, 254, 255, 256 ],
3967 [ 256, 1, 2, 4, 32, 218, 253, 254, 255, 256 ],
3968 [ 256, 1, 2, 5, 47, 199, 252, 254, 255, 256 ],
3969 [ 256, 1, 2, 12, 61, 187, 252, 254, 255, 256 ],
3970 [ 256, 1, 5, 24, 72, 172, 249, 254, 255, 256 ],
3971 [ 256, 1, 2, 16, 70, 170, 242, 254, 255, 256 ],
3972 [ 256, 1, 2, 17, 78, 165, 226, 251, 255, 256 ],
3973 [ 256, 1, 8, 29, 79, 156, 237, 254, 255, 256 ]
3976 static immutable uint16_t[8] silk_model_lsf_s2_ext = [ 256, 156, 216, 240, 249, 253, 255, 256 ];
3978 static immutable uint16_t[6] silk_model_lsf_interpolation_offset = [ 256, 13, 35, 64, 75, 256 ];
3980 static immutable uint16_t[33] silk_model_pitch_highbits = [
3981 256, 3, 6, 12, 23, 44, 74, 106, 125, 136, 146, 158, 171, 184, 196, 207,
3982 216, 224, 231, 237, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
3985 static immutable uint16_t[5] silk_model_pitch_lowbits_nb= [ 256, 64, 128, 192, 256 ];
3987 static immutable uint16_t[7] silk_model_pitch_lowbits_mb= [ 256, 43, 85, 128, 171, 213, 256 ];
3989 static immutable uint16_t[9] silk_model_pitch_lowbits_wb= [ 256, 32, 64, 96, 128, 160, 192, 224, 256 ];
3991 static immutable uint16_t[22] silk_model_pitch_delta = [
3992 256, 46, 48, 50, 53, 57, 63, 73, 88, 114, 152, 182, 204, 219, 229, 236,
3993 242, 246, 250, 252, 254, 256
3996 static immutable uint16_t[4] silk_model_pitch_contour_nb10ms = [ 256, 143, 193, 256 ];
3998 static immutable uint16_t[12] silk_model_pitch_contour_nb20ms = [
3999 256, 68, 80, 101, 118, 137, 159, 189, 213, 230, 246, 256
4002 static immutable uint16_t[13] silk_model_pitch_contour_mbwb10ms = [
4003 256, 91, 137, 176, 195, 209, 221, 229, 236, 242, 247, 252, 256
4006 static immutable uint16_t[35] silk_model_pitch_contour_mbwb20ms = [
4007 256, 33, 55, 73, 89, 104, 118, 132, 145, 158, 168, 177, 186, 194, 200, 206,
4008 212, 217, 221, 225, 229, 232, 235, 238, 240, 242, 244, 246, 248, 250, 252, 253,
4009 254, 255, 256
4012 static immutable uint16_t[4] silk_model_ltp_filter = [ 256, 77, 157, 256 ];
4014 static immutable uint16_t[9] silk_model_ltp_filter0_sel = [
4015 256, 185, 200, 213, 226, 235, 244, 250, 256
4018 static immutable uint16_t[17] silk_model_ltp_filter1_sel = [
4019 256, 57, 91, 112, 132, 147, 160, 172, 185, 195, 205, 214, 224, 233, 241, 248, 256
4022 static immutable uint16_t[33] silk_model_ltp_filter2_sel = [
4023 256, 15, 31, 45, 57, 69, 81, 92, 103, 114, 124, 133, 142, 151, 160, 168,
4024 176, 184, 192, 199, 206, 212, 218, 223, 227, 232, 236, 240, 244, 247, 251, 254, 256
4027 static immutable uint16_t[4] silk_model_ltp_scale_index = [ 256, 128, 192, 256 ];
4029 static immutable uint16_t[5] silk_model_lcg_seed = [ 256, 64, 128, 192, 256 ];
4031 static immutable uint16_t[10][2] silk_model_exc_rate = [
4032 [ 256, 15, 66, 78, 124, 169, 182, 215, 242, 256 ], // unvoiced
4033 [ 256, 33, 63, 99, 116, 150, 199, 217, 238, 256 ] // voiced
4036 static immutable uint16_t[19][11] silk_model_pulse_count = [
4037 [ 256, 131, 205, 230, 238, 241, 244, 245, 246,
4038 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 ],
4039 [ 256, 58, 151, 211, 234, 241, 244, 245, 246,
4040 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 ],
4041 [ 256, 43, 94, 140, 173, 197, 213, 224, 232,
4042 238, 241, 244, 247, 249, 250, 251, 253, 254, 256 ],
4043 [ 256, 17, 69, 140, 197, 228, 240, 245, 246,
4044 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 ],
4045 [ 256, 6, 27, 68, 121, 170, 205, 226, 237,
4046 243, 246, 248, 250, 251, 252, 253, 254, 255, 256 ],
4047 [ 256, 7, 21, 43, 71, 100, 128, 153, 173,
4048 190, 203, 214, 223, 230, 235, 239, 243, 246, 256 ],
4049 [ 256, 2, 7, 21, 50, 92, 138, 179, 210,
4050 229, 240, 246, 249, 251, 252, 253, 254, 255, 256 ],
4051 [ 256, 1, 3, 7, 17, 36, 65, 100, 137,
4052 171, 199, 219, 233, 241, 246, 250, 252, 254, 256 ],
4053 [ 256, 1, 3, 5, 10, 19, 33, 53, 77,
4054 104, 132, 158, 181, 201, 216, 227, 235, 241, 256 ],
4055 [ 256, 1, 2, 3, 9, 36, 94, 150, 189,
4056 214, 228, 238, 244, 247, 250, 252, 253, 254, 256 ],
4057 [ 256, 2, 3, 9, 36, 94, 150, 189, 214,
4058 228, 238, 244, 247, 250, 252, 253, 254, 256, 256 ]
4061 static immutable uint16_t[168][4] silk_model_pulse_location = [
4063 256, 126, 256,
4064 256, 56, 198, 256,
4065 256, 25, 126, 230, 256,
4066 256, 12, 72, 180, 244, 256,
4067 256, 7, 42, 126, 213, 250, 256,
4068 256, 4, 24, 83, 169, 232, 253, 256,
4069 256, 3, 15, 53, 125, 200, 242, 254, 256,
4070 256, 2, 10, 35, 89, 162, 221, 248, 255, 256,
4071 256, 2, 7, 24, 63, 126, 191, 233, 251, 255, 256,
4072 256, 1, 5, 17, 45, 94, 157, 211, 241, 252, 255, 256,
4073 256, 1, 5, 13, 33, 70, 125, 182, 223, 245, 253, 255, 256,
4074 256, 1, 4, 11, 26, 54, 98, 151, 199, 232, 248, 254, 255, 256,
4075 256, 1, 3, 9, 21, 42, 77, 124, 172, 212, 237, 249, 254, 255, 256,
4076 256, 1, 2, 6, 16, 33, 60, 97, 144, 187, 220, 241, 250, 254, 255, 256,
4077 256, 1, 2, 3, 11, 25, 47, 80, 120, 163, 201, 229, 245, 253, 254, 255, 256,
4078 256, 1, 2, 3, 4, 17, 35, 62, 98, 139, 180, 214, 238, 252, 253, 254, 255, 256
4080 256, 127, 256,
4081 256, 53, 202, 256,
4082 256, 22, 127, 233, 256,
4083 256, 11, 72, 183, 246, 256,
4084 256, 6, 41, 127, 215, 251, 256,
4085 256, 4, 24, 83, 170, 232, 253, 256,
4086 256, 3, 16, 56, 127, 200, 241, 254, 256,
4087 256, 3, 12, 39, 92, 162, 218, 246, 255, 256,
4088 256, 3, 11, 30, 67, 124, 185, 229, 249, 255, 256,
4089 256, 3, 10, 25, 53, 97, 151, 200, 233, 250, 255, 256,
4090 256, 1, 8, 21, 43, 77, 123, 171, 209, 237, 251, 255, 256,
4091 256, 1, 2, 13, 35, 62, 97, 139, 186, 219, 244, 254, 255, 256,
4092 256, 1, 2, 8, 22, 48, 85, 128, 171, 208, 234, 248, 254, 255, 256,
4093 256, 1, 2, 6, 16, 36, 67, 107, 149, 189, 220, 240, 250, 254, 255, 256,
4094 256, 1, 2, 5, 13, 29, 55, 90, 128, 166, 201, 227, 243, 251, 254, 255, 256,
4095 256, 1, 2, 4, 10, 22, 43, 73, 109, 147, 183, 213, 234, 246, 252, 254, 255, 256
4097 256, 127, 256,
4098 256, 49, 206, 256,
4099 256, 20, 127, 236, 256,
4100 256, 11, 71, 184, 246, 256,
4101 256, 7, 43, 127, 214, 250, 256,
4102 256, 6, 30, 87, 169, 229, 252, 256,
4103 256, 5, 23, 62, 126, 194, 236, 252, 256,
4104 256, 6, 20, 49, 96, 157, 209, 239, 253, 256,
4105 256, 1, 16, 39, 74, 125, 175, 215, 245, 255, 256,
4106 256, 1, 2, 23, 55, 97, 149, 195, 236, 254, 255, 256,
4107 256, 1, 7, 23, 50, 86, 128, 170, 206, 233, 249, 255, 256,
4108 256, 1, 6, 18, 39, 70, 108, 148, 186, 217, 238, 250, 255, 256,
4109 256, 1, 4, 13, 30, 56, 90, 128, 166, 200, 226, 243, 252, 255, 256,
4110 256, 1, 4, 11, 25, 47, 76, 110, 146, 180, 209, 231, 245, 252, 255, 256,
4111 256, 1, 3, 8, 19, 37, 62, 93, 128, 163, 194, 219, 237, 248, 253, 255, 256,
4112 256, 1, 2, 6, 15, 30, 51, 79, 111, 145, 177, 205, 226, 241, 250, 254, 255, 256
4114 256, 128, 256,
4115 256, 42, 214, 256,
4116 256, 21, 128, 235, 256,
4117 256, 12, 72, 184, 245, 256,
4118 256, 8, 42, 128, 214, 249, 256,
4119 256, 8, 31, 86, 176, 231, 251, 256,
4120 256, 5, 20, 58, 130, 202, 238, 253, 256,
4121 256, 6, 18, 45, 97, 174, 221, 241, 251, 256,
4122 256, 6, 25, 53, 88, 128, 168, 203, 231, 250, 256,
4123 256, 4, 18, 40, 71, 108, 148, 185, 216, 238, 252, 256,
4124 256, 3, 13, 31, 57, 90, 128, 166, 199, 225, 243, 253, 256,
4125 256, 2, 10, 23, 44, 73, 109, 147, 183, 212, 233, 246, 254, 256,
4126 256, 1, 6, 16, 33, 58, 90, 128, 166, 198, 223, 240, 250, 255, 256,
4127 256, 1, 5, 12, 25, 46, 75, 110, 146, 181, 210, 231, 244, 251, 255, 256,
4128 256, 1, 3, 8, 18, 35, 60, 92, 128, 164, 196, 221, 238, 248, 253, 255, 256,
4129 256, 1, 3, 7, 14, 27, 48, 76, 110, 146, 180, 208, 229, 242, 249, 253, 255, 256
4133 static immutable uint16_t[3] silk_model_excitation_lsb = [256, 136, 256];
4135 static immutable uint16_t[3][7][2][3] silk_model_excitation_sign = [
4136 [ // Inactive
4137 [ // Low offset
4138 [256, 2, 256],
4139 [256, 207, 256],
4140 [256, 189, 256],
4141 [256, 179, 256],
4142 [256, 174, 256],
4143 [256, 163, 256],
4144 [256, 157, 256]
4145 ], [ // High offset
4146 [256, 58, 256],
4147 [256, 245, 256],
4148 [256, 238, 256],
4149 [256, 232, 256],
4150 [256, 225, 256],
4151 [256, 220, 256],
4152 [256, 211, 256]
4154 ], [ // Unvoiced
4155 [ // Low offset
4156 [256, 1, 256],
4157 [256, 210, 256],
4158 [256, 190, 256],
4159 [256, 178, 256],
4160 [256, 169, 256],
4161 [256, 162, 256],
4162 [256, 152, 256]
4163 ], [ // High offset
4164 [256, 48, 256],
4165 [256, 242, 256],
4166 [256, 235, 256],
4167 [256, 224, 256],
4168 [256, 214, 256],
4169 [256, 205, 256],
4170 [256, 190, 256]
4172 ], [ // Voiced
4173 [ // Low offset
4174 [256, 1, 256],
4175 [256, 162, 256],
4176 [256, 152, 256],
4177 [256, 147, 256],
4178 [256, 144, 256],
4179 [256, 141, 256],
4180 [256, 138, 256]
4181 ], [ // High offset
4182 [256, 8, 256],
4183 [256, 203, 256],
4184 [256, 187, 256],
4185 [256, 176, 256],
4186 [256, 168, 256],
4187 [256, 161, 256],
4188 [256, 154, 256]
4193 static immutable int16_t[16] silk_stereo_weights = [
4194 -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
4195 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732
4198 static immutable uint8_t[10][32] silk_lsf_s2_model_sel_nbmb = [
4199 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4200 [ 1, 3, 1, 2, 2, 1, 2, 1, 1, 1 ],
4201 [ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
4202 [ 1, 2, 2, 2, 2, 1, 2, 1, 1, 1 ],
4203 [ 2, 3, 3, 3, 3, 2, 2, 2, 2, 2 ],
4204 [ 0, 5, 3, 3, 2, 2, 2, 2, 1, 1 ],
4205 [ 0, 2, 2, 2, 2, 2, 2, 2, 2, 1 ],
4206 [ 2, 3, 6, 4, 4, 4, 5, 4, 5, 5 ],
4207 [ 2, 4, 5, 5, 4, 5, 4, 6, 4, 4 ],
4208 [ 2, 4, 4, 7, 4, 5, 4, 5, 5, 4 ],
4209 [ 4, 3, 3, 3, 2, 3, 2, 2, 2, 2 ],
4210 [ 1, 5, 5, 6, 4, 5, 4, 5, 5, 5 ],
4211 [ 2, 7, 4, 6, 5, 5, 5, 5, 5, 5 ],
4212 [ 2, 7, 5, 5, 5, 5, 5, 6, 5, 4 ],
4213 [ 3, 3, 5, 4, 4, 5, 4, 5, 4, 4 ],
4214 [ 2, 3, 3, 5, 5, 4, 4, 4, 4, 4 ],
4215 [ 2, 4, 4, 6, 4, 5, 4, 5, 5, 5 ],
4216 [ 2, 5, 4, 6, 5, 5, 5, 4, 5, 4 ],
4217 [ 2, 7, 4, 5, 4, 5, 4, 5, 5, 5 ],
4218 [ 2, 5, 4, 6, 7, 6, 5, 6, 5, 4 ],
4219 [ 3, 6, 7, 4, 6, 5, 5, 6, 4, 5 ],
4220 [ 2, 7, 6, 4, 4, 4, 5, 4, 5, 5 ],
4221 [ 4, 5, 5, 4, 6, 6, 5, 6, 5, 4 ],
4222 [ 2, 5, 5, 6, 5, 6, 4, 6, 4, 4 ],
4223 [ 4, 5, 5, 5, 3, 7, 4, 5, 5, 4 ],
4224 [ 2, 3, 4, 5, 5, 6, 4, 5, 5, 4 ],
4225 [ 2, 3, 2, 3, 3, 4, 2, 3, 3, 3 ],
4226 [ 1, 1, 2, 2, 2, 2, 2, 3, 2, 2 ],
4227 [ 4, 5, 5, 6, 6, 6, 5, 6, 4, 5 ],
4228 [ 3, 5, 5, 4, 4, 4, 4, 3, 3, 2 ],
4229 [ 2, 5, 3, 7, 5, 5, 4, 4, 5, 4 ],
4230 [ 4, 4, 5, 4, 5, 6, 5, 6, 5, 4 ]
4233 static immutable uint8_t[16][32] silk_lsf_s2_model_sel_wb = [
4234 [ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ],
4235 [ 10, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 8, 11 ],
4236 [ 10, 13, 13, 11, 15, 12, 12, 13, 10, 13, 12, 13, 13, 12, 11, 11 ],
4237 [ 8, 10, 9, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9 ],
4238 [ 8, 14, 13, 12, 14, 12, 15, 13, 12, 12, 12, 13, 13, 12, 12, 11 ],
4239 [ 8, 11, 13, 13, 12, 11, 11, 13, 11, 11, 11, 11, 11, 11, 10, 12 ],
4240 [ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ],
4241 [ 8, 10, 14, 11, 15, 10, 13, 11, 12, 13, 13, 12, 11, 11, 10, 11 ],
4242 [ 8, 14, 10, 14, 14, 12, 13, 12, 14, 13, 12, 12, 13, 11, 11, 11 ],
4243 [ 10, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ],
4244 [ 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9 ],
4245 [ 10, 10, 11, 12, 13, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 11 ],
4246 [ 10, 10, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 11 ],
4247 [ 11, 12, 12, 12, 14, 12, 12, 13, 11, 13, 12, 12, 13, 12, 11, 12 ],
4248 [ 8, 14, 12, 13, 12, 15, 13, 10, 14, 13, 15, 12, 12, 11, 13, 11 ],
4249 [ 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 8 ],
4250 [ 9, 14, 13, 15, 13, 12, 13, 11, 12, 13, 12, 12, 12, 11, 11, 12 ],
4251 [ 9, 11, 11, 12, 12, 11, 11, 13, 10, 11, 11, 13, 13, 13, 11, 12 ],
4252 [ 10, 11, 11, 10, 10, 10, 11, 10, 9, 10, 9, 10, 9, 9, 9, 12 ],
4253 [ 8, 10, 11, 13, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8 ],
4254 [ 11, 12, 11, 13, 11, 11, 10, 10, 9, 9, 9, 9, 9, 10, 10, 12 ],
4255 [ 10, 14, 11, 15, 15, 12, 13, 12, 13, 11, 13, 11, 11, 10, 11, 11 ],
4256 [ 10, 11, 13, 14, 14, 11, 13, 11, 12, 12, 11, 11, 11, 11, 10, 12 ],
4257 [ 9, 11, 11, 12, 12, 12, 12, 11, 13, 13, 13, 11, 9, 9, 9, 9 ],
4258 [ 10, 13, 11, 14, 14, 12, 15, 12, 12, 13, 11, 12, 12, 11, 11, 11 ],
4259 [ 8, 14, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ],
4260 [ 8, 14, 14, 11, 13, 10, 13, 13, 11, 12, 12, 15, 15, 12, 12, 12 ],
4261 [ 11, 11, 15, 11, 13, 12, 11, 11, 11, 10, 10, 11, 11, 11, 10, 11 ],
4262 [ 8, 8, 9, 8, 8, 8, 10, 9, 10, 9, 9, 10, 10, 10, 9, 9 ],
4263 [ 8, 11, 10, 13, 11, 11, 10, 11, 10, 9, 8, 8, 9, 8, 8, 9 ],
4264 [ 11, 13, 13, 12, 15, 13, 11, 11, 10, 11, 10, 10, 9, 8, 9, 8 ],
4265 [ 10, 11, 13, 11, 12, 11, 11, 11, 10, 9, 10, 14, 12, 8, 8, 8 ]
4268 static immutable uint8_t[9][2] silk_lsf_pred_weights_nbmb = [
4269 [179, 138, 140, 148, 151, 149, 153, 151, 163],
4270 [116, 67, 82, 59, 92, 72, 100, 89, 92]
4273 static immutable uint8_t[15][2] silk_lsf_pred_weights_wb = [
4274 [175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182],
4275 [ 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155]
4278 static immutable uint8_t[9][32] silk_lsf_weight_sel_nbmb = [
4279 [ 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
4280 [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ],
4281 [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4282 [ 1, 1, 1, 0, 0, 0, 0, 1, 0 ],
4283 [ 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
4284 [ 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
4285 [ 1, 0, 1, 1, 0, 0, 0, 1, 0 ],
4286 [ 0, 1, 1, 0, 0, 1, 1, 0, 0 ],
4287 [ 0, 0, 1, 1, 0, 1, 0, 1, 1 ],
4288 [ 0, 0, 1, 1, 0, 0, 1, 1, 1 ],
4289 [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4290 [ 0, 1, 0, 1, 1, 1, 1, 1, 0 ],
4291 [ 0, 1, 0, 1, 1, 1, 1, 1, 0 ],
4292 [ 0, 1, 1, 1, 1, 1, 1, 1, 0 ],
4293 [ 1, 0, 1, 1, 0, 1, 1, 1, 1 ],
4294 [ 0, 1, 1, 1, 1, 1, 0, 1, 0 ],
4295 [ 0, 0, 1, 1, 0, 1, 0, 1, 0 ],
4296 [ 0, 0, 1, 1, 1, 0, 1, 1, 1 ],
4297 [ 0, 1, 1, 0, 0, 1, 1, 1, 0 ],
4298 [ 0, 0, 0, 1, 1, 1, 0, 1, 0 ],
4299 [ 0, 1, 1, 0, 0, 1, 0, 1, 0 ],
4300 [ 0, 1, 1, 0, 0, 0, 1, 1, 0 ],
4301 [ 0, 0, 0, 0, 0, 1, 1, 1, 1 ],
4302 [ 0, 0, 1, 1, 0, 0, 0, 1, 1 ],
4303 [ 0, 0, 0, 1, 0, 1, 1, 1, 1 ],
4304 [ 0, 1, 1, 1, 1, 1, 1, 1, 0 ],
4305 [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4306 [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4307 [ 0, 0, 1, 0, 1, 1, 0, 1, 0 ],
4308 [ 1, 0, 0, 1, 0, 0, 0, 0, 0 ],
4309 [ 0, 0, 0, 1, 1, 0, 1, 0, 1 ],
4310 [ 1, 0, 1, 1, 0, 1, 1, 1, 1 ]
4313 static immutable uint8_t[15][32] silk_lsf_weight_sel_wb = [
4314 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
4315 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4316 [ 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 ],
4317 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ],
4318 [ 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0 ],
4319 [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4320 [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 ],
4321 [ 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 ],
4322 [ 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 ],
4323 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
4324 [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4325 [ 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 ],
4326 [ 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 ],
4327 [ 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 ],
4328 [ 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 ],
4329 [ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 ],
4330 [ 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0 ],
4331 [ 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0 ],
4332 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
4333 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ],
4334 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4335 [ 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0 ],
4336 [ 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0 ],
4337 [ 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 ],
4338 [ 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 ],
4339 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
4340 [ 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1 ],
4341 [ 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 ],
4342 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
4343 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
4344 [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
4345 [ 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 ]
4348 static immutable uint8_t[10][32] silk_lsf_codebook_nbmb = [
4349 [ 12, 35, 60, 83, 108, 132, 157, 180, 206, 228 ],
4350 [ 15, 32, 55, 77, 101, 125, 151, 175, 201, 225 ],
4351 [ 19, 42, 66, 89, 114, 137, 162, 184, 209, 230 ],
4352 [ 12, 25, 50, 72, 97, 120, 147, 172, 200, 223 ],
4353 [ 26, 44, 69, 90, 114, 135, 159, 180, 205, 225 ],
4354 [ 13, 22, 53, 80, 106, 130, 156, 180, 205, 228 ],
4355 [ 15, 25, 44, 64, 90, 115, 142, 168, 196, 222 ],
4356 [ 19, 24, 62, 82, 100, 120, 145, 168, 190, 214 ],
4357 [ 22, 31, 50, 79, 103, 120, 151, 170, 203, 227 ],
4358 [ 21, 29, 45, 65, 106, 124, 150, 171, 196, 224 ],
4359 [ 30, 49, 75, 97, 121, 142, 165, 186, 209, 229 ],
4360 [ 19, 25, 52, 70, 93, 116, 143, 166, 192, 219 ],
4361 [ 26, 34, 62, 75, 97, 118, 145, 167, 194, 217 ],
4362 [ 25, 33, 56, 70, 91, 113, 143, 165, 196, 223 ],
4363 [ 21, 34, 51, 72, 97, 117, 145, 171, 196, 222 ],
4364 [ 20, 29, 50, 67, 90, 117, 144, 168, 197, 221 ],
4365 [ 22, 31, 48, 66, 95, 117, 146, 168, 196, 222 ],
4366 [ 24, 33, 51, 77, 116, 134, 158, 180, 200, 224 ],
4367 [ 21, 28, 70, 87, 106, 124, 149, 170, 194, 217 ],
4368 [ 26, 33, 53, 64, 83, 117, 152, 173, 204, 225 ],
4369 [ 27, 34, 65, 95, 108, 129, 155, 174, 210, 225 ],
4370 [ 20, 26, 72, 99, 113, 131, 154, 176, 200, 219 ],
4371 [ 34, 43, 61, 78, 93, 114, 155, 177, 205, 229 ],
4372 [ 23, 29, 54, 97, 124, 138, 163, 179, 209, 229 ],
4373 [ 30, 38, 56, 89, 118, 129, 158, 178, 200, 231 ],
4374 [ 21, 29, 49, 63, 85, 111, 142, 163, 193, 222 ],
4375 [ 27, 48, 77, 103, 133, 158, 179, 196, 215, 232 ],
4376 [ 29, 47, 74, 99, 124, 151, 176, 198, 220, 237 ],
4377 [ 33, 42, 61, 76, 93, 121, 155, 174, 207, 225 ],
4378 [ 29, 53, 87, 112, 136, 154, 170, 188, 208, 227 ],
4379 [ 24, 30, 52, 84, 131, 150, 166, 186, 203, 229 ],
4380 [ 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 ]
4383 static immutable uint8_t[16][32] silk_lsf_codebook_wb = [
4384 [ 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239 ],
4385 [ 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236 ],
4386 [ 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240 ],
4387 [ 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237 ],
4388 [ 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240 ],
4389 [ 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236 ],
4390 [ 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218 ],
4391 [ 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236 ],
4392 [ 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237 ],
4393 [ 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241 ],
4394 [ 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225 ],
4395 [ 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234 ],
4396 [ 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233 ],
4397 [ 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237 ],
4398 [ 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240 ],
4399 [ 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237 ],
4400 [ 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236 ],
4401 [ 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237 ],
4402 [ 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238 ],
4403 [ 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239 ],
4404 [ 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235 ],
4405 [ 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238 ],
4406 [ 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236 ],
4407 [ 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237 ],
4408 [ 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240 ],
4409 [ 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239 ],
4410 [ 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241 ],
4411 [ 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231 ],
4412 [ 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242 ],
4413 [ 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239 ],
4414 [ 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240 ],
4415 [ 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 ]
4418 static immutable uint16_t[11] silk_lsf_min_spacing_nbmb = [
4419 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461
4422 static immutable uint16_t[17] silk_lsf_min_spacing_wb = [
4423 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347
4426 static immutable uint8_t[10] silk_lsf_ordering_nbmb = [
4427 0, 9, 6, 3, 4, 5, 8, 1, 2, 7
4430 static immutable uint8_t[16] silk_lsf_ordering_wb = [
4431 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1
4434 static immutable int16_t[129] silk_cosine = [ /* (0.12) */
4435 4096, 4095, 4091, 4085,
4436 4076, 4065, 4052, 4036,
4437 4017, 3997, 3973, 3948,
4438 3920, 3889, 3857, 3822,
4439 3784, 3745, 3703, 3659,
4440 3613, 3564, 3513, 3461,
4441 3406, 3349, 3290, 3229,
4442 3166, 3102, 3035, 2967,
4443 2896, 2824, 2751, 2676,
4444 2599, 2520, 2440, 2359,
4445 2276, 2191, 2106, 2019,
4446 1931, 1842, 1751, 1660,
4447 1568, 1474, 1380, 1285,
4448 1189, 1093, 995, 897,
4449 799, 700, 601, 501,
4450 401, 301, 201, 101,
4451 0, -101, -201, -301,
4452 -401, -501, -601, -700,
4453 -799, -897, -995, -1093,
4454 -1189, -1285, -1380, -1474,
4455 -1568, -1660, -1751, -1842,
4456 -1931, -2019, -2106, -2191,
4457 -2276, -2359, -2440, -2520,
4458 -2599, -2676, -2751, -2824,
4459 -2896, -2967, -3035, -3102,
4460 -3166, -3229, -3290, -3349,
4461 -3406, -3461, -3513, -3564,
4462 -3613, -3659, -3703, -3745,
4463 -3784, -3822, -3857, -3889,
4464 -3920, -3948, -3973, -3997,
4465 -4017, -4036, -4052, -4065,
4466 -4076, -4085, -4091, -4095,
4467 -4096
4470 static immutable uint16_t[3] silk_pitch_scale = [ 4, 6, 8];
4472 static immutable uint16_t[3] silk_pitch_min_lag = [ 16, 24, 32];
4474 static immutable uint16_t[3] silk_pitch_max_lag = [144, 216, 288];
4476 static immutable int8_t[2][3] silk_pitch_offset_nb10ms = [
4477 [ 0, 0],
4478 [ 1, 0],
4479 [ 0, 1]
4482 static immutable int8_t[4][11] silk_pitch_offset_nb20ms = [
4483 [ 0, 0, 0, 0],
4484 [ 2, 1, 0, -1],
4485 [-1, 0, 1, 2],
4486 [-1, 0, 0, 1],
4487 [-1, 0, 0, 0],
4488 [ 0, 0, 0, 1],
4489 [ 0, 0, 1, 1],
4490 [ 1, 1, 0, 0],
4491 [ 1, 0, 0, 0],
4492 [ 0, 0, 0, -1],
4493 [ 1, 0, 0, -1]
4496 static immutable int8_t[2][12] silk_pitch_offset_mbwb10ms = [
4497 [ 0, 0],
4498 [ 0, 1],
4499 [ 1, 0],
4500 [-1, 1],
4501 [ 1, -1],
4502 [-1, 2],
4503 [ 2, -1],
4504 [-2, 2],
4505 [ 2, -2],
4506 [-2, 3],
4507 [ 3, -2],
4508 [-3, 3]
4511 static immutable int8_t[4][34] silk_pitch_offset_mbwb20ms = [
4512 [ 0, 0, 0, 0],
4513 [ 0, 0, 1, 1],
4514 [ 1, 1, 0, 0],
4515 [-1, 0, 0, 0],
4516 [ 0, 0, 0, 1],
4517 [ 1, 0, 0, 0],
4518 [-1, 0, 0, 1],
4519 [ 0, 0, 0, -1],
4520 [-1, 0, 1, 2],
4521 [ 1, 0, 0, -1],
4522 [-2, -1, 1, 2],
4523 [ 2, 1, 0, -1],
4524 [-2, 0, 0, 2],
4525 [-2, 0, 1, 3],
4526 [ 2, 1, -1, -2],
4527 [-3, -1, 1, 3],
4528 [ 2, 0, 0, -2],
4529 [ 3, 1, 0, -2],
4530 [-3, -1, 2, 4],
4531 [-4, -1, 1, 4],
4532 [ 3, 1, -1, -3],
4533 [-4, -1, 2, 5],
4534 [ 4, 2, -1, -3],
4535 [ 4, 1, -1, -4],
4536 [-5, -1, 2, 6],
4537 [ 5, 2, -1, -4],
4538 [-6, -2, 2, 6],
4539 [-5, -2, 2, 5],
4540 [ 6, 2, -1, -5],
4541 [-7, -2, 3, 8],
4542 [ 6, 2, -2, -6],
4543 [ 5, 2, -2, -5],
4544 [ 8, 3, -2, -7],
4545 [-9, -3, 3, 9]
4548 static immutable int8_t[5][8] silk_ltp_filter0_taps = [
4549 [ 4, 6, 24, 7, 5],
4550 [ 0, 0, 2, 0, 0],
4551 [ 12, 28, 41, 13, -4],
4552 [ -9, 15, 42, 25, 14],
4553 [ 1, -2, 62, 41, -9],
4554 [-10, 37, 65, -4, 3],
4555 [ -6, 4, 66, 7, -8],
4556 [ 16, 14, 38, -3, 33]
4559 static immutable int8_t[5][16] silk_ltp_filter1_taps = [
4560 [ 13, 22, 39, 23, 12],
4561 [ -1, 36, 64, 27, -6],
4562 [ -7, 10, 55, 43, 17],
4563 [ 1, 1, 8, 1, 1],
4564 [ 6, -11, 74, 53, -9],
4565 [-12, 55, 76, -12, 8],
4566 [ -3, 3, 93, 27, -4],
4567 [ 26, 39, 59, 3, -8],
4568 [ 2, 0, 77, 11, 9],
4569 [ -8, 22, 44, -6, 7],
4570 [ 40, 9, 26, 3, 9],
4571 [ -7, 20, 101, -7, 4],
4572 [ 3, -8, 42, 26, 0],
4573 [-15, 33, 68, 2, 23],
4574 [ -2, 55, 46, -2, 15],
4575 [ 3, -1, 21, 16, 41]
4578 static immutable int8_t[5][32] silk_ltp_filter2_taps = [
4579 [ -6, 27, 61, 39, 5],
4580 [-11, 42, 88, 4, 1],
4581 [ -2, 60, 65, 6, -4],
4582 [ -1, -5, 73, 56, 1],
4583 [ -9, 19, 94, 29, -9],
4584 [ 0, 12, 99, 6, 4],
4585 [ 8, -19, 102, 46, -13],
4586 [ 3, 2, 13, 3, 2],
4587 [ 9, -21, 84, 72, -18],
4588 [-11, 46, 104, -22, 8],
4589 [ 18, 38, 48, 23, 0],
4590 [-16, 70, 83, -21, 11],
4591 [ 5, -11, 117, 22, -8],
4592 [ -6, 23, 117, -12, 3],
4593 [ 3, -8, 95, 28, 4],
4594 [-10, 15, 77, 60, -15],
4595 [ -1, 4, 124, 2, -4],
4596 [ 3, 38, 84, 24, -25],
4597 [ 2, 13, 42, 13, 31],
4598 [ 21, -4, 56, 46, -1],
4599 [ -1, 35, 79, -13, 19],
4600 [ -7, 65, 88, -9, -14],
4601 [ 20, 4, 81, 49, -29],
4602 [ 20, 0, 75, 3, -17],
4603 [ 5, -9, 44, 92, -8],
4604 [ 1, -3, 22, 69, 31],
4605 [ -6, 95, 41, -12, 5],
4606 [ 39, 67, 16, -4, 1],
4607 [ 0, -6, 120, 55, -36],
4608 [-13, 44, 122, 4, -24],
4609 [ 81, 5, 11, 3, 7],
4610 [ 2, 0, 9, 10, 88]
4613 static immutable uint16_t[3] silk_ltp_scale_factor = [15565, 12288, 8192];
4615 static immutable uint8_t[2][3] silk_shell_blocks = [
4616 [ 5, 10], // NB
4617 [ 8, 15], // MB
4618 [10, 20] // WB
4621 static immutable uint8_t[2][2] silk_quant_offset = [ /* (0.23) */
4622 [25, 60], // Inactive or Unvoiced
4623 [ 8, 25] // Voiced
4626 static immutable int[3] silk_stereo_interp_len = [
4627 64, 96, 128
4631 /*static inline*/ void silk_stabilize_lsf(int16_t* nlsf/*[16]*/, int order, const(uint16_t)* min_delta/*[17]*/)
4633 int pass, i;
4634 for (pass = 0; pass < 20; pass++) {
4635 int k, min_diff = 0;
4636 for (i = 0; i < order+1; i++) {
4637 int low = i != 0 ? nlsf[i-1] : 0;
4638 int high = i != order ? nlsf[i] : 32768;
4639 int diff = (high - low) - (min_delta[i]);
4641 if (diff < min_diff) {
4642 min_diff = diff;
4643 k = i;
4645 if (pass == 20)
4646 break;
4649 if (min_diff == 0) /* no issues; stabilized */
4650 return;
4652 /* wiggle one or two LSFs */
4653 if (k == 0) {
4654 /* repel away from lower bound */
4655 nlsf[0] = min_delta[0];
4656 } else if (k == order) {
4657 /* repel away from higher bound */
4658 nlsf[order-1] = cast(short)(32768 - min_delta[order]);
4659 } else {
4660 /* repel away from current position */
4661 int min_center = 0, max_center = 32768, center_val;
4663 /* lower extent */
4664 for (i = 0; i < k; i++)
4665 min_center += min_delta[i];
4666 min_center += min_delta[k] >> 1;
4668 /* upper extent */
4669 for (i = order; i > k; i--)
4670 max_center -= min_delta[i];
4671 max_center -= min_delta[k] >> 1;
4673 /* move apart */
4674 center_val = nlsf[k - 1] + nlsf[k];
4675 center_val = (center_val >> 1) + (center_val & 1); // rounded divide by 2
4676 center_val = FFMIN(max_center, FFMAX(min_center, center_val));
4678 nlsf[k - 1] = cast(short)(center_val - (min_delta[k] >> 1));
4679 nlsf[k] = cast(short)(nlsf[k - 1] + min_delta[k]);
4683 /* resort to the fall-back method, the standard method for LSF stabilization */
4685 /* sort; as the LSFs should be nearly sorted, use insertion sort */
4686 for (i = 1; i < order; i++) {
4687 int j, value = nlsf[i];
4688 for (j = i - 1; j >= 0 && nlsf[j] > value; j--)
4689 nlsf[j + 1] = nlsf[j];
4690 nlsf[j + 1] = cast(short)value;
4693 /* push forwards to increase distance */
4694 if (nlsf[0] < min_delta[0])
4695 nlsf[0] = min_delta[0];
4696 for (i = 1; i < order; i++)
4697 if (nlsf[i] < nlsf[i - 1] + min_delta[i])
4698 nlsf[i] = cast(short)(nlsf[i - 1] + min_delta[i]);
4700 /* push backwards to increase distance */
4701 if (nlsf[order-1] > 32768 - min_delta[order])
4702 nlsf[order-1] = cast(short)(32768 - min_delta[order]);
4703 for (i = order-2; i >= 0; i--)
4704 if (nlsf[i] > nlsf[i + 1] - min_delta[i+1])
4705 nlsf[i] = cast(short)(nlsf[i + 1] - min_delta[i+1]);
4707 return;
4710 /*static inline*/ int silk_is_lpc_stable(const(int16_t)* lpc/*[16]*/, int order)
4712 int k, j, DC_resp = 0;
4713 int32_t[16][2] lpc32; // Q24
4714 int totalinvgain = 1 << 30; // 1.0 in Q30
4715 int32_t *row = lpc32[0].ptr;
4716 int32_t *prevrow;
4718 /* initialize the first row for the Levinson recursion */
4719 for (k = 0; k < order; k++) {
4720 DC_resp += lpc[k];
4721 row[k] = lpc[k] * 4096;
4724 if (DC_resp >= 4096)
4725 return 0;
4727 /* check if prediction gain pushes any coefficients too far */
4728 for (k = order - 1; 1; k--) {
4729 int rc; // Q31; reflection coefficient
4730 int gaindiv; // Q30; inverse of the gain (the divisor)
4731 int gain; // gain for this reflection coefficient
4732 int fbits; // fractional bits used for the gain
4733 int error; // Q29; estimate of the error of our partial estimate of 1/gaindiv
4735 if (FFABS(row[k]) > 16773022)
4736 return 0;
4738 rc = -(row[k] * 128);
4739 gaindiv = (1 << 30) - MULH(rc, rc);
4741 totalinvgain = MULH(totalinvgain, gaindiv) << 2;
4742 if (k == 0)
4743 return (totalinvgain >= 107374);
4745 /* approximate 1.0/gaindiv */
4746 fbits = opus_ilog(gaindiv);
4747 gain = ((1 << 29) - 1) / (gaindiv >> (fbits + 1 - 16)); // Q<fbits-16>
4748 error = cast(int)((1 << 29) - MULL(gaindiv << (15 + 16 - fbits), gain, 16));
4749 gain = ((gain << 16) + (error * gain >> 13));
4751 /* switch to the next row of the LPC coefficients */
4752 prevrow = row;
4753 row = lpc32[k & 1].ptr;
4755 for (j = 0; j < k; j++) {
4756 int x = cast(int)(prevrow[j] - ROUND_MULL(prevrow[k - j - 1], rc, 31));
4757 row[j] = cast(int)(ROUND_MULL(x, gain, fbits));
4762 static void silk_lsp2poly(const(int32_t)* lsp/*[16]*/, int32_t* pol/*[16]*/, int half_order)
4764 int i, j;
4766 pol[0] = 65536; // 1.0 in Q16
4767 pol[1] = -lsp[0];
4769 for (i = 1; i < half_order; i++) {
4770 pol[i + 1] = cast(int)(pol[i - 1] * 2 - ROUND_MULL(lsp[2 * i], pol[i], 16));
4771 for (j = i; j > 1; j--)
4772 pol[j] += pol[j - 2] - ROUND_MULL(lsp[2 * i], pol[j - 1], 16);
4774 pol[1] -= lsp[2 * i];
4778 static void silk_lsf2lpc(const(int16_t)* nlsf/*[16]*/, float* lpcf/*[16]*/, int order)
4780 int i, k;
4781 int32_t[16] lsp; // Q17; 2*cos(LSF)
4782 int32_t[9] p, q; // Q16
4783 int32_t[16] lpc32; // Q17
4784 int16_t[16] lpc; // Q12
4786 /* convert the LSFs to LSPs, i.e. 2*cos(LSF) */
4787 for (k = 0; k < order; k++) {
4788 int index = nlsf[k] >> 8;
4789 int offset = nlsf[k] & 255;
4790 int k2 = (order == 10) ? silk_lsf_ordering_nbmb[k] : silk_lsf_ordering_wb[k];
4792 /* interpolate and round */
4793 lsp[k2] = silk_cosine[index] * 256;
4794 lsp[k2] += (silk_cosine[index + 1] - silk_cosine[index]) * offset;
4795 lsp[k2] = (lsp[k2] + 4) >> 3;
4798 silk_lsp2poly(lsp.ptr , p.ptr, order >> 1);
4799 silk_lsp2poly(lsp.ptr + 1, q.ptr, order >> 1);
4801 /* reconstruct A(z) */
4802 for (k = 0; k < order>>1; k++) {
4803 lpc32[k] = -p[k + 1] - p[k] - q[k + 1] + q[k];
4804 lpc32[order-k-1] = -p[k + 1] - p[k] + q[k + 1] - q[k];
4807 /* limit the range of the LPC coefficients to each fit within an int16_t */
4808 for (i = 0; i < 10; i++) {
4809 int j;
4810 uint maxabs = 0;
4811 for (j = 0, k = 0; j < order; j++) {
4812 uint x = FFABS(lpc32[k]);
4813 if (x > maxabs) {
4814 maxabs = x; // Q17
4815 k = j;
4819 maxabs = (maxabs + 16) >> 5; // convert to Q12
4821 if (maxabs > 32767) {
4822 /* perform bandwidth expansion */
4823 uint chirp, chirp_base; // Q16
4824 maxabs = FFMIN(maxabs, 163838); // anything above this overflows chirp's numerator
4825 chirp_base = chirp = 65470 - ((maxabs - 32767) << 14) / ((maxabs * (k+1)) >> 2);
4827 for (k = 0; k < order; k++) {
4828 lpc32[k] = cast(int)(ROUND_MULL(lpc32[k], chirp, 16));
4829 chirp = (chirp_base * chirp + 32768) >> 16;
4831 } else break;
4834 if (i == 10) {
4835 /* time's up: just clamp */
4836 for (k = 0; k < order; k++) {
4837 int x = (lpc32[k] + 16) >> 5;
4838 lpc[k] = av_clip_int16(x);
4839 lpc32[k] = lpc[k] << 5; // shortcut mandated by the spec; drops lower 5 bits
4841 } else {
4842 for (k = 0; k < order; k++)
4843 lpc[k] = cast(short)((lpc32[k] + 16) >> 5);
4846 /* if the prediction gain causes the LPC filter to become unstable,
4847 apply further bandwidth expansion on the Q17 coefficients */
4848 for (i = 1; i <= 16 && !silk_is_lpc_stable(lpc.ptr, order); i++) {
4849 uint chirp, chirp_base;
4850 chirp_base = chirp = 65536 - (1 << i);
4852 for (k = 0; k < order; k++) {
4853 lpc32[k] = cast(int)(ROUND_MULL(lpc32[k], chirp, 16));
4854 lpc[k] = cast(short)((lpc32[k] + 16) >> 5);
4855 chirp = (chirp_base * chirp + 32768) >> 16;
4859 for (i = 0; i < order; i++)
4860 lpcf[i] = lpc[i] / 4096.0f;
4863 /*static inline*/ void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
4864 OpusRangeCoder *rc,
4865 float* lpc_leadin/*[16]*/, float* lpc/*[16]*/,
4866 int *lpc_order, int *has_lpc_leadin, int voiced)
4868 import core.stdc.string : memcpy;
4869 int i;
4870 int order; // order of the LP polynomial; 10 for NB/MB and 16 for WB
4871 int8_t lsf_i1;
4872 int8_t[16] lsf_i2; // stage-1 and stage-2 codebook indices
4873 int16_t[16] lsf_res; // residual as a Q10 value
4874 int16_t[16] nlsf; // Q15
4876 *lpc_order = order = s.wb ? 16 : 10;
4878 /* obtain LSF stage-1 and stage-2 indices */
4879 lsf_i1 = cast(byte)opus_rc_getsymbol(rc, silk_model_lsf_s1[s.wb][voiced].ptr);
4880 for (i = 0; i < order; i++) {
4881 int index = s.wb ? silk_lsf_s2_model_sel_wb [lsf_i1][i] :
4882 silk_lsf_s2_model_sel_nbmb[lsf_i1][i];
4883 lsf_i2[i] = cast(byte)(opus_rc_getsymbol(rc, silk_model_lsf_s2[index].ptr) - 4);
4884 if (lsf_i2[i] == -4)
4885 lsf_i2[i] -= opus_rc_getsymbol(rc, silk_model_lsf_s2_ext.ptr);
4886 else if (lsf_i2[i] == 4)
4887 lsf_i2[i] += opus_rc_getsymbol(rc, silk_model_lsf_s2_ext.ptr);
4890 /* reverse the backwards-prediction step */
4891 for (i = order - 1; i >= 0; i--) {
4892 int qstep = s.wb ? 9830 : 11796;
4894 lsf_res[i] = cast(short)(lsf_i2[i] * 1024);
4895 if (lsf_i2[i] < 0) lsf_res[i] += 102;
4896 else if (lsf_i2[i] > 0) lsf_res[i] -= 102;
4897 lsf_res[i] = (lsf_res[i] * qstep) >> 16;
4899 if (i + 1 < order) {
4900 int weight = s.wb ? silk_lsf_pred_weights_wb [silk_lsf_weight_sel_wb [lsf_i1][i]][i] :
4901 silk_lsf_pred_weights_nbmb[silk_lsf_weight_sel_nbmb[lsf_i1][i]][i];
4902 lsf_res[i] += (lsf_res[i+1] * weight) >> 8;
4906 /* reconstruct the NLSF coefficients from the supplied indices */
4907 for (i = 0; i < order; i++) {
4908 const uint8_t * codebook = s.wb ? silk_lsf_codebook_wb[lsf_i1].ptr : silk_lsf_codebook_nbmb[lsf_i1].ptr;
4909 int cur, prev, next, weight_sq, weight, ipart, fpart, y, value;
4911 /* find the weight of the residual */
4912 /* TODO: precompute */
4913 cur = codebook[i];
4914 prev = i ? codebook[i - 1] : 0;
4915 next = i + 1 < order ? codebook[i + 1] : 256;
4916 weight_sq = (1024 / (cur - prev) + 1024 / (next - cur)) << 16;
4918 /* approximate square-root with mandated fixed-point arithmetic */
4919 ipart = opus_ilog(weight_sq);
4920 fpart = (weight_sq >> (ipart-8)) & 127;
4921 y = ((ipart & 1) ? 32768 : 46214) >> ((32 - ipart)>>1);
4922 weight = y + ((213 * fpart * y) >> 16);
4924 value = cur * 128 + (lsf_res[i] * 16384) / weight;
4925 nlsf[i] = cast(short)av_clip_uintp2(value, 15);
4928 /* stabilize the NLSF coefficients */
4929 silk_stabilize_lsf(nlsf.ptr, order, s.wb ? silk_lsf_min_spacing_wb.ptr : silk_lsf_min_spacing_nbmb.ptr);
4931 /* produce an interpolation for the first 2 subframes, */
4932 /* and then convert both sets of NLSFs to LPC coefficients */
4933 *has_lpc_leadin = 0;
4934 if (s.subframes == 4) {
4935 int offset = opus_rc_getsymbol(rc, silk_model_lsf_interpolation_offset.ptr);
4936 if (offset != 4 && frame.coded) {
4937 *has_lpc_leadin = 1;
4938 if (offset != 0) {
4939 int16_t[16] nlsf_leadin;
4940 for (i = 0; i < order; i++)
4941 nlsf_leadin[i] = cast(short)(frame.nlsf[i] + ((nlsf[i] - frame.nlsf[i]) * offset >> 2));
4942 silk_lsf2lpc(nlsf_leadin.ptr, lpc_leadin, order);
4943 } else /* avoid re-computation for a (roughly) 1-in-4 occurrence */
4944 memcpy(lpc_leadin, frame.lpc.ptr, 16 * float.sizeof);
4945 } else
4946 offset = 4;
4947 s.nlsf_interp_factor = offset;
4949 silk_lsf2lpc(nlsf.ptr, lpc, order);
4950 } else {
4951 s.nlsf_interp_factor = 4;
4952 silk_lsf2lpc(nlsf.ptr, lpc, order);
4955 memcpy(frame.nlsf.ptr, nlsf.ptr, order * nlsf[0].sizeof);
4956 memcpy(frame.lpc.ptr, lpc, order * lpc[0].sizeof);
4959 /*static inline*/ void silk_count_children(OpusRangeCoder *rc, int model, int32_t total, int32_t* child/*[2]*/)
4961 if (total != 0) {
4962 child[0] = opus_rc_getsymbol(rc, silk_model_pulse_location[model].ptr + (((total - 1 + 5) * (total - 1)) >> 1));
4963 child[1] = total - child[0];
4964 } else {
4965 child[0] = 0;
4966 child[1] = 0;
4970 /*static inline*/ void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
4971 float* excitationf,
4972 int qoffset_high, int active, int voiced)
4974 import core.stdc.string : memset;
4975 int i;
4976 uint32_t seed;
4977 int shellblocks;
4978 int ratelevel;
4979 uint8_t[20] pulsecount; // total pulses in each shell block
4980 uint8_t[20] lsbcount = 0; // raw lsbits defined for each pulse in each shell block
4981 int32_t[320] excitation; // Q23
4983 /* excitation parameters */
4984 seed = opus_rc_getsymbol(rc, silk_model_lcg_seed.ptr);
4985 shellblocks = silk_shell_blocks[s.bandwidth][s.subframes >> 2];
4986 ratelevel = opus_rc_getsymbol(rc, silk_model_exc_rate[voiced].ptr);
4988 for (i = 0; i < shellblocks; i++) {
4989 pulsecount[i] = cast(ubyte)opus_rc_getsymbol(rc, silk_model_pulse_count[ratelevel].ptr);
4990 if (pulsecount[i] == 17) {
4991 while (pulsecount[i] == 17 && ++lsbcount[i] != 10)
4992 pulsecount[i] = cast(ubyte)opus_rc_getsymbol(rc, silk_model_pulse_count[9].ptr);
4993 if (lsbcount[i] == 10)
4994 pulsecount[i] = cast(ubyte)opus_rc_getsymbol(rc, silk_model_pulse_count[10].ptr);
4998 /* decode pulse locations using PVQ */
4999 for (i = 0; i < shellblocks; i++) {
5000 if (pulsecount[i] != 0) {
5001 int a, b, c, d;
5002 int32_t * location = excitation.ptr + 16*i;
5003 int32_t[2][4] branch;
5004 branch[0][0] = pulsecount[i];
5006 /* unrolled tail recursion */
5007 for (a = 0; a < 1; a++) {
5008 silk_count_children(rc, 0, branch[0][a], branch[1].ptr);
5009 for (b = 0; b < 2; b++) {
5010 silk_count_children(rc, 1, branch[1][b], branch[2].ptr);
5011 for (c = 0; c < 2; c++) {
5012 silk_count_children(rc, 2, branch[2][c], branch[3].ptr);
5013 for (d = 0; d < 2; d++) {
5014 silk_count_children(rc, 3, branch[3][d], location);
5015 location += 2;
5020 } else
5021 memset(excitation.ptr + 16*i, 0, 16*int32_t.sizeof);
5024 /* decode least significant bits */
5025 for (i = 0; i < shellblocks << 4; i++) {
5026 int bit;
5027 for (bit = 0; bit < lsbcount[i >> 4]; bit++)
5028 excitation[i] = (excitation[i] << 1) |
5029 opus_rc_getsymbol(rc, silk_model_excitation_lsb.ptr);
5032 /* decode signs */
5033 for (i = 0; i < shellblocks << 4; i++) {
5034 if (excitation[i] != 0) {
5035 int sign = opus_rc_getsymbol(rc, silk_model_excitation_sign[active + voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)].ptr);
5036 if (sign == 0)
5037 excitation[i] *= -1;
5041 /* assemble the excitation */
5042 for (i = 0; i < shellblocks << 4; i++) {
5043 int value = excitation[i];
5044 excitation[i] = value * 256 | silk_quant_offset[voiced][qoffset_high];
5045 if (value < 0) excitation[i] += 20;
5046 else if (value > 0) excitation[i] -= 20;
5048 /* invert samples pseudorandomly */
5049 seed = 196314165 * seed + 907633515;
5050 if (seed & 0x80000000)
5051 excitation[i] *= -1;
5052 seed += value;
5054 excitationf[i] = excitation[i] / 8388608.0f;
5058 /** Maximum residual history according to 4.2.7.6.1 */
5059 enum SILK_MAX_LAG = (288 + LTP_ORDER / 2);
5061 /** Order of the LTP filter */
5062 enum LTP_ORDER = 5;
5064 static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
5065 int frame_num, int channel, int coded_channels, int active, int active1)
5067 import core.stdc.string : memmove;
5068 /* per frame */
5069 int voiced; // combines with active to indicate inactive, active, or active+voiced
5070 int qoffset_high;
5071 int order; // order of the LPC coefficients
5072 float[16] lpc_leadin;
5073 float[16] lpc_body;
5074 float[SILK_MAX_LAG + SILK_HISTORY] residual;
5075 int has_lpc_leadin;
5076 float ltpscale;
5078 /* per subframe */
5079 static struct SF {
5080 float gain;
5081 int pitchlag;
5082 float[5] ltptaps;
5084 SF[4] sf = void;
5086 //const(SilkFrame)* frame = s.frame.ptr + channel;
5087 SilkFrame* frame = s.frame.ptr + channel;
5089 int i;
5091 /* obtain stereo weights */
5092 if (coded_channels == 2 && channel == 0) {
5093 int n;
5094 int[2] wi, ws, w;
5095 n = opus_rc_getsymbol(rc, silk_model_stereo_s1.ptr);
5096 wi[0] = opus_rc_getsymbol(rc, silk_model_stereo_s2.ptr) + 3 * (n / 5);
5097 ws[0] = opus_rc_getsymbol(rc, silk_model_stereo_s3.ptr);
5098 wi[1] = opus_rc_getsymbol(rc, silk_model_stereo_s2.ptr) + 3 * (n % 5);
5099 ws[1] = opus_rc_getsymbol(rc, silk_model_stereo_s3.ptr);
5101 for (i = 0; i < 2; i++)
5102 w[i] = silk_stereo_weights[wi[i]] +
5103 (((silk_stereo_weights[wi[i] + 1] - silk_stereo_weights[wi[i]]) * 6554) >> 16)
5104 * (ws[i]*2 + 1);
5106 s.stereo_weights[0] = (w[0] - w[1]) / 8192.0;
5107 s.stereo_weights[1] = w[1] / 8192.0;
5109 /* and read the mid-only flag */
5110 s.midonly = active1 ? 0 : opus_rc_getsymbol(rc, silk_model_mid_only.ptr);
5113 /* obtain frame type */
5114 if (!active) {
5115 qoffset_high = opus_rc_getsymbol(rc, silk_model_frame_type_inactive.ptr);
5116 voiced = 0;
5117 } else {
5118 int type = opus_rc_getsymbol(rc, silk_model_frame_type_active.ptr);
5119 qoffset_high = type & 1;
5120 voiced = type >> 1;
5123 /* obtain subframe quantization gains */
5124 for (i = 0; i < s.subframes; i++) {
5125 int log_gain; //Q7
5126 int ipart, fpart, lingain;
5128 if (i == 0 && (frame_num == 0 || !frame.coded)) {
5129 /* gain is coded absolute */
5130 int x = opus_rc_getsymbol(rc, silk_model_gain_highbits[active + voiced].ptr);
5131 log_gain = (x<<3) | opus_rc_getsymbol(rc, silk_model_gain_lowbits.ptr);
5133 if (frame.coded)
5134 log_gain = FFMAX(log_gain, frame.log_gain - 16);
5135 } else {
5136 /* gain is coded relative */
5137 int delta_gain = opus_rc_getsymbol(rc, silk_model_gain_delta.ptr);
5138 log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16,
5139 frame.log_gain + delta_gain - 4), 6);
5142 frame.log_gain = log_gain;
5144 /* approximate 2**(x/128) with a Q7 (i.e. non-integer) input */
5145 log_gain = (log_gain * 0x1D1C71 >> 16) + 2090;
5146 ipart = log_gain >> 7;
5147 fpart = log_gain & 127;
5148 lingain = (1 << ipart) + ((-174 * fpart * (128-fpart) >>16) + fpart) * ((1<<ipart) >> 7);
5149 sf[i].gain = lingain / 65536.0f;
5152 /* obtain LPC filter coefficients */
5153 silk_decode_lpc(s, frame, rc, lpc_leadin.ptr, lpc_body.ptr, &order, &has_lpc_leadin, voiced);
5155 /* obtain pitch lags, if this is a voiced frame */
5156 if (voiced) {
5157 int lag_absolute = (!frame_num || !frame.prev_voiced);
5158 int primarylag; // primary pitch lag for the entire SILK frame
5159 int ltpfilter;
5160 const(int8_t)* offsets;
5162 if (!lag_absolute) {
5163 int delta = opus_rc_getsymbol(rc, silk_model_pitch_delta.ptr);
5164 if (delta)
5165 primarylag = frame.primarylag + delta - 9;
5166 else
5167 lag_absolute = 1;
5170 if (lag_absolute) {
5171 /* primary lag is coded absolute */
5172 int highbits, lowbits;
5173 static immutable uint16_t*[3] model = [
5174 silk_model_pitch_lowbits_nb.ptr, silk_model_pitch_lowbits_mb.ptr,
5175 silk_model_pitch_lowbits_wb.ptr
5177 highbits = opus_rc_getsymbol(rc, silk_model_pitch_highbits.ptr);
5178 lowbits = opus_rc_getsymbol(rc, model[s.bandwidth]);
5180 primarylag = silk_pitch_min_lag[s.bandwidth] +
5181 highbits*silk_pitch_scale[s.bandwidth] + lowbits;
5183 frame.primarylag = primarylag;
5185 if (s.subframes == 2)
5186 offsets = (s.bandwidth == OPUS_BANDWIDTH_NARROWBAND)
5187 ? silk_pitch_offset_nb10ms[opus_rc_getsymbol(rc, silk_model_pitch_contour_nb10ms.ptr)].ptr
5188 : silk_pitch_offset_mbwb10ms[opus_rc_getsymbol(rc, silk_model_pitch_contour_mbwb10ms.ptr)].ptr;
5189 else
5190 offsets = (s.bandwidth == OPUS_BANDWIDTH_NARROWBAND)
5191 ? silk_pitch_offset_nb20ms[opus_rc_getsymbol(rc, silk_model_pitch_contour_nb20ms.ptr)].ptr
5192 : silk_pitch_offset_mbwb20ms[opus_rc_getsymbol(rc, silk_model_pitch_contour_mbwb20ms.ptr)].ptr;
5194 for (i = 0; i < s.subframes; i++)
5195 sf[i].pitchlag = av_clip(primarylag + offsets[i],
5196 silk_pitch_min_lag[s.bandwidth],
5197 silk_pitch_max_lag[s.bandwidth]);
5199 /* obtain LTP filter coefficients */
5200 ltpfilter = opus_rc_getsymbol(rc, silk_model_ltp_filter.ptr);
5201 for (i = 0; i < s.subframes; i++) {
5202 int index, j;
5203 static immutable uint16_t*[3] filter_sel = [
5204 silk_model_ltp_filter0_sel.ptr, silk_model_ltp_filter1_sel.ptr,
5205 silk_model_ltp_filter2_sel.ptr
5207 static immutable int8_t[5]*[3] /*(*filter_taps[])[5]*/ filter_taps = [
5208 silk_ltp_filter0_taps.ptr, silk_ltp_filter1_taps.ptr, silk_ltp_filter2_taps.ptr
5210 index = opus_rc_getsymbol(rc, filter_sel[ltpfilter]);
5211 for (j = 0; j < 5; j++)
5212 sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f;
5216 /* obtain LTP scale factor */
5217 if (voiced && frame_num == 0)
5218 ltpscale = silk_ltp_scale_factor[opus_rc_getsymbol(rc, silk_model_ltp_scale_index.ptr)] / 16384.0f;
5219 else ltpscale = 15565.0f/16384.0f;
5221 /* generate the excitation signal for the entire frame */
5222 silk_decode_excitation(s, rc, residual.ptr + SILK_MAX_LAG, qoffset_high, active, voiced);
5224 /* skip synthesising the side channel if we want mono-only */
5225 if (s.output_channels == channel)
5226 return;
5228 /* generate the output signal */
5229 for (i = 0; i < s.subframes; i++) {
5230 const(float)* lpc_coeff = (i < 2 && has_lpc_leadin) ? lpc_leadin.ptr : lpc_body.ptr;
5231 float *dst = frame.output.ptr + SILK_HISTORY + i * s.sflength;
5232 float *resptr = residual.ptr + SILK_MAX_LAG + i * s.sflength;
5233 float *lpc = frame.lpc_history.ptr + SILK_HISTORY + i * s.sflength;
5234 float sum;
5235 int j, k;
5237 if (voiced) {
5238 int out_end;
5239 float scale;
5241 if (i < 2 || s.nlsf_interp_factor == 4) {
5242 out_end = -i * s.sflength;
5243 scale = ltpscale;
5244 } else {
5245 out_end = -(i - 2) * s.sflength;
5246 scale = 1.0f;
5249 /* when the LPC coefficients change, a re-whitening filter is used */
5250 /* to produce a residual that accounts for the change */
5251 for (j = - sf[i].pitchlag - LTP_ORDER/2; j < out_end; j++) {
5252 sum = dst[j];
5253 for (k = 0; k < order; k++)
5254 sum -= lpc_coeff[k] * dst[j - k - 1];
5255 resptr[j] = av_clipf(sum, -1.0f, 1.0f) * scale / sf[i].gain;
5258 if (out_end) {
5259 float rescale = sf[i-1].gain / sf[i].gain;
5260 for (j = out_end; j < 0; j++)
5261 resptr[j] *= rescale;
5264 /* LTP synthesis */
5265 for (j = 0; j < s.sflength; j++) {
5266 sum = resptr[j];
5267 for (k = 0; k < LTP_ORDER; k++)
5268 sum += sf[i].ltptaps[k] * resptr[j - sf[i].pitchlag + LTP_ORDER/2 - k];
5269 resptr[j] = sum;
5273 /* LPC synthesis */
5274 for (j = 0; j < s.sflength; j++) {
5275 sum = resptr[j] * sf[i].gain;
5276 for (k = 1; k <= order; k++)
5277 sum += lpc_coeff[k - 1] * lpc[j - k];
5279 lpc[j] = sum;
5280 dst[j] = av_clipf(sum, -1.0f, 1.0f);
5284 frame.prev_voiced = voiced;
5285 memmove(frame.lpc_history.ptr, frame.lpc_history.ptr + s.flength, SILK_HISTORY * float.sizeof);
5286 memmove(frame.output.ptr, frame.output.ptr + s.flength, SILK_HISTORY * float.sizeof);
5288 frame.coded = 1;
5291 static void silk_unmix_ms(SilkContext *s, float *l, float *r)
5293 import core.stdc.string : memcpy;
5294 float *mid = s.frame[0].output.ptr + SILK_HISTORY - s.flength;
5295 float *side = s.frame[1].output.ptr + SILK_HISTORY - s.flength;
5296 float w0_prev = s.prev_stereo_weights[0];
5297 float w1_prev = s.prev_stereo_weights[1];
5298 float w0 = s.stereo_weights[0];
5299 float w1 = s.stereo_weights[1];
5300 int n1 = silk_stereo_interp_len[s.bandwidth];
5301 int i;
5303 for (i = 0; i < n1; i++) {
5304 float interp0 = w0_prev + i * (w0 - w0_prev) / n1;
5305 float interp1 = w1_prev + i * (w1 - w1_prev) / n1;
5306 float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
5308 l[i] = av_clipf((1 + interp1) * mid[i - 1] + side[i - 1] + interp0 * p0, -1.0, 1.0);
5309 r[i] = av_clipf((1 - interp1) * mid[i - 1] - side[i - 1] - interp0 * p0, -1.0, 1.0);
5312 for (; i < s.flength; i++) {
5313 float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
5315 l[i] = av_clipf((1 + w1) * mid[i - 1] + side[i - 1] + w0 * p0, -1.0, 1.0);
5316 r[i] = av_clipf((1 - w1) * mid[i - 1] - side[i - 1] - w0 * p0, -1.0, 1.0);
5319 memcpy(s.prev_stereo_weights.ptr, s.stereo_weights.ptr, s.stereo_weights.sizeof);
5322 static void silk_flush_frame(SilkFrame *frame)
5324 import core.stdc.string : memset;
5325 if (!frame.coded)
5326 return;
5328 memset(frame.output.ptr, 0, frame.output.sizeof);
5329 memset(frame.lpc_history.ptr, 0, frame.lpc_history.sizeof);
5331 memset(frame.lpc.ptr, 0, frame.lpc.sizeof);
5332 memset(frame.nlsf.ptr, 0, frame.nlsf.sizeof);
5334 frame.log_gain = 0;
5336 frame.primarylag = 0;
5337 frame.prev_voiced = 0;
5338 frame.coded = 0;
5341 int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
5342 float** output/*[2]*/,
5343 OpusBandwidth bandwidth,
5344 int coded_channels,
5345 int duration_ms)
5347 import core.stdc.string : memcpy;
5348 int[6][2] active;
5349 int[2] redundancy;
5350 int nb_frames, i, j;
5352 if (bandwidth > OPUS_BANDWIDTH_WIDEBAND ||
5353 coded_channels > 2 || duration_ms > 60) {
5354 //av_log(s.avctx, AV_LOG_ERROR, "Invalid parameters passed to the SILK decoder.\n");
5355 return AVERROR(EINVAL);
5358 nb_frames = 1 + (duration_ms > 20) + (duration_ms > 40);
5359 s.subframes = duration_ms / nb_frames / 5; // 5ms subframes
5360 s.sflength = 20 * (bandwidth + 2);
5361 s.flength = s.sflength * s.subframes;
5362 s.bandwidth = bandwidth;
5363 s.wb = bandwidth == OPUS_BANDWIDTH_WIDEBAND;
5365 /* make sure to flush the side channel when switching from mono to stereo */
5366 if (coded_channels > s.prev_coded_channels)
5367 silk_flush_frame(&s.frame[1]);
5368 s.prev_coded_channels = coded_channels;
5370 /* read the LP-layer header bits */
5371 for (i = 0; i < coded_channels; i++) {
5372 for (j = 0; j < nb_frames; j++)
5373 active[i][j] = opus_rc_p2model(rc, 1);
5375 redundancy[i] = opus_rc_p2model(rc, 1);
5376 if (redundancy[i]) {
5377 //av_log(s.avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n");
5378 return AVERROR_PATCHWELCOME;
5382 for (i = 0; i < nb_frames; i++) {
5383 for (j = 0; j < coded_channels && !s.midonly; j++)
5384 silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i]);
5386 /* reset the side channel if it is not coded */
5387 if (s.midonly && s.frame[1].coded)
5388 silk_flush_frame(&s.frame[1]);
5390 if (coded_channels == 1 || s.output_channels == 1) {
5391 for (j = 0; j < s.output_channels; j++) {
5392 memcpy(output[j] + i * s.flength, s.frame[0].output.ptr + SILK_HISTORY - s.flength - 2, s.flength * float.sizeof);
5394 } else {
5395 silk_unmix_ms(s, output[0] + i * s.flength, output[1] + i * s.flength);
5398 s.midonly = 0;
5401 return nb_frames * s.flength;
5404 void ff_silk_free(SilkContext **ps)
5406 av_freep(ps);
5409 void ff_silk_flush(SilkContext *s)
5411 import core.stdc.string : memset;
5412 silk_flush_frame(&s.frame[0]);
5413 silk_flush_frame(&s.frame[1]);
5415 memset(s.prev_stereo_weights.ptr, 0, s.prev_stereo_weights.sizeof);
5418 int ff_silk_init(/*AVCodecContext *avctx,*/ SilkContext **ps, int output_channels)
5420 SilkContext *s;
5422 if (output_channels != 1 && output_channels != 2) {
5423 //av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n", output_channels);
5424 return AVERROR(EINVAL);
5427 s = av_mallocz!SilkContext();
5428 if (!s)
5429 return AVERROR(ENOMEM);
5431 //s.avctx = avctx;
5432 s.output_channels = output_channels;
5434 ff_silk_flush(s);
5436 *ps = s;
5438 return 0;
5442 version = sincresample_use_full_table;
5443 version(X86) {
5444 version(D_PIC) {} else version = sincresample_use_sse;
5448 // ////////////////////////////////////////////////////////////////////////// //
5449 public struct OpusResampler {
5450 nothrow @nogc:
5451 public:
5452 alias Quality = int;
5453 enum : uint {
5454 Fastest = 0,
5455 Voip = 3,
5456 Default = 4,
5457 Desktop = 5,
5458 Best = 10,
5461 enum Error {
5462 OK = 0,
5463 NoMemory,
5464 BadState,
5465 BadArgument,
5466 BadData,
5469 private:
5470 nothrow @trusted @nogc:
5471 alias ResamplerFn = int function (ref OpusResampler st, uint chanIdx, const(float)* indata, uint *indataLen, float *outdata, uint *outdataLen);
5473 private:
5474 uint inRate;
5475 uint outRate;
5476 uint numRate; // from
5477 uint denRate; // to
5479 Quality srQuality;
5480 uint chanCount;
5481 uint filterLen;
5482 uint memAllocSize;
5483 uint bufferSize;
5484 int intAdvance;
5485 int fracAdvance;
5486 float cutoff;
5487 uint oversample;
5488 bool started;
5490 // these are per-channel
5491 int[64] lastSample;
5492 uint[64] sampFracNum;
5493 uint[64] magicSamples;
5495 float* mem;
5496 uint realMemLen; // how much memory really allocated
5497 float* sincTable;
5498 uint sincTableLen;
5499 uint realSincTableLen; // how much memory really allocated
5500 ResamplerFn resampler;
5502 int inStride;
5503 int outStride;
5505 public:
5506 static string errorStr (int err) {
5507 switch (err) with (Error) {
5508 case OK: return "success";
5509 case NoMemory: return "memory allocation failed";
5510 case BadState: return "bad resampler state";
5511 case BadArgument: return "invalid argument";
5512 case BadData: return "bad data passed";
5513 default:
5515 return "unknown error";
5518 public:
5519 @disable this (this);
5520 ~this () { deinit(); }
5522 @property bool inited () const pure { return (resampler !is null); }
5524 void deinit () {
5525 import core.stdc.stdlib : free;
5526 if (mem !is null) { free(mem); mem = null; }
5527 if (sincTable !is null) { free(sincTable); sincTable = null; }
5529 memAllocSize = realMemLen = 0;
5530 sincTableLen = realSincTableLen = 0;
5531 resampler = null;
5532 started = false;
5534 inRate = outRate = numRate = denRate = 0;
5535 srQuality = cast(Quality)666;
5536 chanCount = 0;
5537 filterLen = 0;
5538 memAllocSize = 0;
5539 bufferSize = 0;
5540 intAdvance = 0;
5541 fracAdvance = 0;
5542 cutoff = 0;
5543 oversample = 0;
5544 started = 0;
5546 mem = null;
5547 realMemLen = 0; // how much memory really allocated
5548 sincTable = null;
5549 sincTableLen = 0;
5550 realSincTableLen = 0; // how much memory really allocated
5551 resampler = null;
5553 inStride = outStride = 0;
5556 /** Create a new resampler with integer input and output rates.
5558 * Params:
5559 * chans = Number of channels to be processed
5560 * inRate = Input sampling rate (integer number of Hz).
5561 * outRate = Output sampling rate (integer number of Hz).
5562 * aquality = Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.
5564 * Returns:
5565 * 0 or error code
5567 Error setup (uint chans, uint ainRate, uint aoutRate, Quality aquality/*, usize line=__LINE__*/) {
5568 //{ import core.stdc.stdio; printf("init: %u -> %u at %u\n", ainRate, aoutRate, cast(uint)line); }
5569 import core.stdc.stdlib : malloc, free;
5571 deinit();
5572 if (aquality < 0) aquality = 0;
5573 if (aquality > OpusResampler.Best) aquality = OpusResampler.Best;
5574 if (chans < 1 || chans > 16) return Error.BadArgument;
5576 started = false;
5577 inRate = 0;
5578 outRate = 0;
5579 numRate = 0;
5580 denRate = 0;
5581 srQuality = cast(Quality)666; // it's ok
5582 sincTableLen = 0;
5583 memAllocSize = 0;
5584 filterLen = 0;
5585 mem = null;
5586 resampler = null;
5588 cutoff = 1.0f;
5589 chanCount = chans;
5590 inStride = 1;
5591 outStride = 1;
5593 bufferSize = 160;
5595 // per channel data
5596 lastSample[] = 0;
5597 magicSamples[] = 0;
5598 sampFracNum[] = 0;
5600 setQuality(aquality);
5601 setRate(ainRate, aoutRate);
5603 if (auto filterErr = updateFilter()) { deinit(); return filterErr; }
5604 skipZeros(); // make sure that the first samples to go out of the resamplers don't have leading zeros
5606 return Error.OK;
5609 /** Set (change) the input/output sampling rates (integer value).
5611 * Params:
5612 * ainRate = Input sampling rate (integer number of Hz).
5613 * aoutRate = Output sampling rate (integer number of Hz).
5615 * Returns:
5616 * 0 or error code
5618 Error setRate (uint ainRate, uint aoutRate/*, usize line=__LINE__*/) {
5619 //{ import core.stdc.stdio; printf("changing rate: %u -> %u at %u\n", ainRate, aoutRate, cast(uint)line); }
5620 if (inRate == ainRate && outRate == aoutRate) return Error.OK;
5621 //{ import core.stdc.stdio; printf("changing rate: %u -> %u at %u\n", ratioNum, ratioDen, cast(uint)line); }
5623 uint oldDen = denRate;
5624 inRate = ainRate;
5625 outRate = aoutRate;
5626 auto div = gcd(ainRate, aoutRate);
5627 numRate = ainRate/div;
5628 denRate = aoutRate/div;
5630 if (oldDen > 0) {
5631 foreach (ref v; sampFracNum.ptr[0..chanCount]) {
5632 v = v*denRate/oldDen;
5633 // safety net
5634 if (v >= denRate) v = denRate-1;
5638 return (inited ? updateFilter() : Error.OK);
5641 /** Get the current input/output sampling rates (integer value).
5643 * Params:
5644 * ainRate = Input sampling rate (integer number of Hz) copied.
5645 * aoutRate = Output sampling rate (integer number of Hz) copied.
5647 void getRate (out uint ainRate, out uint aoutRate) {
5648 ainRate = inRate;
5649 aoutRate = outRate;
5652 @property uint getInRate () { return inRate; }
5653 @property uint getOutRate () { return outRate; }
5655 @property uint getChans () { return chanCount; }
5657 /** Get the current resampling ratio. This will be reduced to the least common denominator.
5659 * Params:
5660 * ratioNum = Numerator of the sampling rate ratio copied
5661 * ratioDen = Denominator of the sampling rate ratio copied
5663 void getRatio (out uint ratioNum, out uint ratioDen) {
5664 ratioNum = numRate;
5665 ratioDen = denRate;
5668 /** Set (change) the conversion quality.
5670 * Params:
5671 * quality = Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.
5673 * Returns:
5674 * 0 or error code
5676 Error setQuality (Quality aquality) {
5677 if (aquality < 0) aquality = 0;
5678 if (aquality > OpusResampler.Best) aquality = OpusResampler.Best;
5679 if (srQuality == aquality) return Error.OK;
5680 srQuality = aquality;
5681 return (inited ? updateFilter() : Error.OK);
5684 /** Get the conversion quality.
5686 * Returns:
5687 * Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality.
5689 int getQuality () { return srQuality; }
5691 /** Get the latency introduced by the resampler measured in input samples.
5693 * Returns:
5694 * Input latency;
5696 int inputLatency () { return filterLen/2; }
5698 /** Get the latency introduced by the resampler measured in output samples.
5700 * Returns:
5701 * Output latency.
5703 int outputLatency () { return ((filterLen/2)*denRate+(numRate>>1))/numRate; }
5705 /* Make sure that the first samples to go out of the resamplers don't have
5706 * leading zeros. This is only useful before starting to use a newly created
5707 * resampler. It is recommended to use that when resampling an audio file, as
5708 * it will generate a file with the same length. For real-time processing,
5709 * it is probably easier not to use this call (so that the output duration
5710 * is the same for the first frame).
5712 * Setup/reset sequence will automatically call this, so it is private.
5714 private void skipZeros () { foreach (immutable i; 0..chanCount) lastSample.ptr[i] = filterLen/2; }
5716 static struct Data {
5717 const(float)[] dataIn;
5718 float[] dataOut;
5719 uint inputSamplesUsed; // out value, in samples (i.e. multiplied by channel count)
5720 uint outputSamplesUsed; // out value, in samples (i.e. multiplied by channel count)
5723 /** Resample (an interleaved) float array. The input and output buffers must *not* overlap.
5724 * `data.dataIn` can be empty, but `data.dataOut` can't.
5725 * Function will return number of consumed samples (*not* *frames*!) in `data.inputSamplesUsed`,
5726 * and number of produced samples in `data.outputSamplesUsed`.
5727 * You should provide enough samples for all channels, and all channels will be processed.
5729 * Params:
5730 * data = input and output buffers, number of frames consumed and produced
5732 * Returns:
5733 * 0 or error code
5735 Error process(string mode="interleaved") (ref Data data) {
5736 static assert(mode == "interleaved" || mode == "sequential");
5738 data.inputSamplesUsed = data.outputSamplesUsed = 0;
5739 if (!inited) return Error.BadState;
5741 if (data.dataIn.length%chanCount || data.dataOut.length < 1 || data.dataOut.length%chanCount) return Error.BadData;
5742 if (data.dataIn.length > uint.max/4 || data.dataOut.length > uint.max/4) return Error.BadData;
5744 static if (mode == "interleaved") {
5745 inStride = outStride = chanCount;
5746 } else {
5747 inStride = outStride = 1;
5749 uint iofs = 0, oofs = 0;
5750 immutable uint idclen = cast(uint)(data.dataIn.length/chanCount);
5751 immutable uint odclen = cast(uint)(data.dataOut.length/chanCount);
5752 foreach (immutable i; 0..chanCount) {
5753 data.inputSamplesUsed = idclen;
5754 data.outputSamplesUsed = odclen;
5755 if (data.dataIn.length) {
5756 processOneChannel(i, data.dataIn.ptr+iofs, &data.inputSamplesUsed, data.dataOut.ptr+oofs, &data.outputSamplesUsed);
5757 } else {
5758 processOneChannel(i, null, &data.inputSamplesUsed, data.dataOut.ptr+oofs, &data.outputSamplesUsed);
5760 static if (mode == "interleaved") {
5761 ++iofs;
5762 ++oofs;
5763 } else {
5764 iofs += idclen;
5765 oofs += odclen;
5768 data.inputSamplesUsed *= chanCount;
5769 data.outputSamplesUsed *= chanCount;
5770 return Error.OK;
5774 //HACK for libswresample
5775 // return -1 or number of outframes
5776 int swrconvert (float** outbuf, int outframes, const(float)**inbuf, int inframes) {
5777 if (!inited || outframes < 1 || inframes < 0) return -1;
5778 inStride = outStride = 1;
5779 Data data;
5780 foreach (immutable i; 0..chanCount) {
5781 data.dataIn = (inframes ? inbuf[i][0..inframes] : null);
5782 data.dataOut = (outframes ? outbuf[i][0..outframes] : null);
5783 data.inputSamplesUsed = inframes;
5784 data.outputSamplesUsed = outframes;
5785 if (inframes > 0) {
5786 processOneChannel(i, data.dataIn.ptr, &data.inputSamplesUsed, data.dataOut.ptr, &data.outputSamplesUsed);
5787 } else {
5788 processOneChannel(i, null, &data.inputSamplesUsed, data.dataOut.ptr, &data.outputSamplesUsed);
5791 return data.outputSamplesUsed;
5794 /// Reset a resampler so a new (unrelated) stream can be processed.
5795 void reset () {
5796 lastSample[] = 0;
5797 magicSamples[] = 0;
5798 sampFracNum[] = 0;
5799 //foreach (immutable i; 0..chanCount*(filterLen-1)) mem[i] = 0;
5800 if (mem !is null) mem[0..chanCount*(filterLen-1)] = 0;
5801 skipZeros(); // make sure that the first samples to go out of the resamplers don't have leading zeros
5804 private:
5805 Error processOneChannel (uint chanIdx, const(float)* indata, uint* indataLen, float* outdata, uint* outdataLen) {
5806 uint ilen = *indataLen;
5807 uint olen = *outdataLen;
5808 float* x = mem+chanIdx*memAllocSize;
5809 const int filterOfs = filterLen-1;
5810 const uint xlen = memAllocSize-filterOfs;
5811 const int istride = inStride;
5812 if (magicSamples.ptr[chanIdx]) olen -= magic(chanIdx, &outdata, olen);
5813 if (!magicSamples.ptr[chanIdx]) {
5814 while (ilen && olen) {
5815 uint ichunk = (ilen > xlen ? xlen : ilen);
5816 uint ochunk = olen;
5817 if (indata !is null) {
5818 foreach (immutable j; 0..ichunk) x[j+filterOfs] = indata[j*istride];
5819 } else {
5820 foreach (immutable j; 0..ichunk) x[j+filterOfs] = 0;
5822 processNative(chanIdx, &ichunk, outdata, &ochunk);
5823 ilen -= ichunk;
5824 olen -= ochunk;
5825 outdata += ochunk*outStride;
5826 if (indata) indata += ichunk*istride;
5829 *indataLen -= ilen;
5830 *outdataLen -= olen;
5831 return Error.OK;
5834 Error processNative (uint chanIdx, uint* indataLen, float* outdata, uint* outdataLen) {
5835 immutable N = filterLen;
5836 int outSample = 0;
5837 float* x = mem+chanIdx*memAllocSize;
5838 uint ilen;
5840 started = true;
5842 // call the right resampler through the function ptr
5843 outSample = resampler(this, chanIdx, x, indataLen, outdata, outdataLen);
5845 if (lastSample.ptr[chanIdx] < cast(int)*indataLen) *indataLen = lastSample.ptr[chanIdx];
5846 *outdataLen = outSample;
5847 lastSample.ptr[chanIdx] -= *indataLen;
5849 ilen = *indataLen;
5851 foreach (immutable j; 0..N-1) x[j] = x[j+ilen];
5853 return Error.OK;
5856 int magic (uint chanIdx, float **outdata, uint outdataLen) {
5857 uint tempInLen = magicSamples.ptr[chanIdx];
5858 float* x = mem+chanIdx*memAllocSize;
5859 processNative(chanIdx, &tempInLen, *outdata, &outdataLen);
5860 magicSamples.ptr[chanIdx] -= tempInLen;
5861 // if we couldn't process all "magic" input samples, save the rest for next time
5862 if (magicSamples.ptr[chanIdx]) {
5863 immutable N = filterLen;
5864 foreach (immutable i; 0..magicSamples.ptr[chanIdx]) x[N-1+i] = x[N-1+i+tempInLen];
5866 *outdata += outdataLen*outStride;
5867 return outdataLen;
5870 Error updateFilter () {
5871 uint oldFilterLen = filterLen;
5872 uint oldAllocSize = memAllocSize;
5873 bool useDirect;
5874 uint minSincTableLen;
5875 uint minAllocSize;
5877 intAdvance = numRate/denRate;
5878 fracAdvance = numRate%denRate;
5879 oversample = qualityMap.ptr[srQuality].oversample;
5880 filterLen = qualityMap.ptr[srQuality].baseLength;
5882 if (numRate > denRate) {
5883 // down-sampling
5884 cutoff = qualityMap.ptr[srQuality].downsampleBandwidth*denRate/numRate;
5885 // FIXME: divide the numerator and denominator by a certain amount if they're too large
5886 filterLen = filterLen*numRate/denRate;
5887 // Round up to make sure we have a multiple of 8 for SSE
5888 filterLen = ((filterLen-1)&(~0x7))+8;
5889 if (2*denRate < numRate) oversample >>= 1;
5890 if (4*denRate < numRate) oversample >>= 1;
5891 if (8*denRate < numRate) oversample >>= 1;
5892 if (16*denRate < numRate) oversample >>= 1;
5893 if (oversample < 1) oversample = 1;
5894 } else {
5895 // up-sampling
5896 cutoff = qualityMap.ptr[srQuality].upsampleBandwidth;
5899 // choose the resampling type that requires the least amount of memory
5900 version(sincresample_use_full_table) {
5901 useDirect = true;
5902 if (int.max/float.sizeof/denRate < filterLen) goto fail;
5903 } else {
5904 useDirect = (filterLen*denRate <= filterLen*oversample+8 && int.max/float.sizeof/denRate >= filterLen);
5907 if (useDirect) {
5908 minSincTableLen = filterLen*denRate;
5909 } else {
5910 if ((int.max/float.sizeof-8)/oversample < filterLen) goto fail;
5911 minSincTableLen = filterLen*oversample+8;
5914 if (sincTableLen < minSincTableLen) {
5915 import core.stdc.stdlib : realloc;
5916 auto nslen = cast(uint)(minSincTableLen*float.sizeof);
5917 if (nslen > realSincTableLen) {
5918 if (nslen < 512*1024) nslen = 512*1024; // inc to 3 mb?
5919 auto x = cast(float*)realloc(sincTable, nslen);
5920 if (!x) goto fail;
5921 sincTable = x;
5922 realSincTableLen = nslen;
5924 sincTableLen = minSincTableLen;
5927 if (useDirect) {
5928 foreach (int i; 0..denRate) {
5929 foreach (int j; 0..filterLen) {
5930 sincTable[i*filterLen+j] = sinc(cutoff, ((j-cast(int)filterLen/2+1)-(cast(float)i)/denRate), filterLen, qualityMap.ptr[srQuality].windowFunc);
5933 if (srQuality > 8) {
5934 resampler = &resamplerBasicDirect!double;
5935 } else {
5936 resampler = &resamplerBasicDirect!float;
5938 } else {
5939 foreach (immutable int i; -4..cast(int)(oversample*filterLen+4)) {
5940 sincTable[i+4] = sinc(cutoff, (i/cast(float)oversample-filterLen/2), filterLen, qualityMap.ptr[srQuality].windowFunc);
5942 if (srQuality > 8) {
5943 resampler = &resamplerBasicInterpolate!double;
5944 } else {
5945 resampler = &resamplerBasicInterpolate!float;
5949 /* Here's the place where we update the filter memory to take into account
5950 the change in filter length. It's probably the messiest part of the code
5951 due to handling of lots of corner cases. */
5953 // adding bufferSize to filterLen won't overflow here because filterLen could be multiplied by float.sizeof above
5954 minAllocSize = filterLen-1+bufferSize;
5955 if (minAllocSize > memAllocSize) {
5956 import core.stdc.stdlib : realloc;
5957 if (int.max/float.sizeof/chanCount < minAllocSize) goto fail;
5958 auto nslen = cast(uint)(chanCount*minAllocSize*mem[0].sizeof);
5959 if (nslen > realMemLen) {
5960 if (nslen < 16384) nslen = 16384;
5961 auto x = cast(float*)realloc(mem, nslen);
5962 if (x is null) goto fail;
5963 mem = x;
5964 realMemLen = nslen;
5966 memAllocSize = minAllocSize;
5968 if (!started) {
5969 //foreach (i=0;i<chanCount*memAllocSize;i++) mem[i] = 0;
5970 mem[0..chanCount*memAllocSize] = 0;
5971 } else if (filterLen > oldFilterLen) {
5972 // increase the filter length
5973 foreach_reverse (uint i; 0..chanCount) {
5974 uint j;
5975 uint olen = oldFilterLen;
5977 // try and remove the magic samples as if nothing had happened
5978 //FIXME: this is wrong but for now we need it to avoid going over the array bounds
5979 olen = oldFilterLen+2*magicSamples.ptr[i];
5980 for (j = oldFilterLen-1+magicSamples.ptr[i]; j--; ) mem[i*memAllocSize+j+magicSamples.ptr[i]] = mem[i*oldAllocSize+j];
5981 //for (j = 0; j < magicSamples.ptr[i]; ++j) mem[i*memAllocSize+j] = 0;
5982 mem[i*memAllocSize..i*memAllocSize+magicSamples.ptr[i]] = 0;
5983 magicSamples.ptr[i] = 0;
5985 if (filterLen > olen) {
5986 // if the new filter length is still bigger than the "augmented" length
5987 // copy data going backward
5988 for (j = 0; j < olen-1; ++j) mem[i*memAllocSize+(filterLen-2-j)] = mem[i*memAllocSize+(olen-2-j)];
5989 // then put zeros for lack of anything better
5990 for (; j < filterLen-1; ++j) mem[i*memAllocSize+(filterLen-2-j)] = 0;
5991 // adjust lastSample
5992 lastSample.ptr[i] += (filterLen-olen)/2;
5993 } else {
5994 // put back some of the magic!
5995 magicSamples.ptr[i] = (olen-filterLen)/2;
5996 for (j = 0; j < filterLen-1+magicSamples.ptr[i]; ++j) mem[i*memAllocSize+j] = mem[i*memAllocSize+j+magicSamples.ptr[i]];
5999 } else if (filterLen < oldFilterLen) {
6000 // reduce filter length, this a bit tricky
6001 // we need to store some of the memory as "magic" samples so they can be used directly as input the next time(s)
6002 foreach (immutable i; 0..chanCount) {
6003 uint j;
6004 uint oldMagic = magicSamples.ptr[i];
6005 magicSamples.ptr[i] = (oldFilterLen-filterLen)/2;
6006 // we must copy some of the memory that's no longer used
6007 // copy data going backward
6008 for (j = 0; j < filterLen-1+magicSamples.ptr[i]+oldMagic; ++j) {
6009 mem[i*memAllocSize+j] = mem[i*memAllocSize+j+magicSamples.ptr[i]];
6011 magicSamples.ptr[i] += oldMagic;
6014 return Error.OK;
6016 fail:
6017 resampler = null;
6018 /* mem may still contain consumed input samples for the filter.
6019 Restore filterLen so that filterLen-1 still points to the position after
6020 the last of these samples. */
6021 filterLen = oldFilterLen;
6022 return Error.NoMemory;
6027 // ////////////////////////////////////////////////////////////////////////// //
6028 static immutable double[68] kaiser12Table = [
6029 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076,
6030 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014,
6031 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601,
6032 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014,
6033 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490,
6034 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546,
6035 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178,
6036 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947,
6037 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058,
6038 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438,
6039 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734,
6040 0.00001000, 0.00000000];
6042 static immutable double[36] kaiser10Table = [
6043 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446,
6044 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347,
6045 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962,
6046 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451,
6047 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739,
6048 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000];
6050 static immutable double[36] kaiser8Table = [
6051 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200,
6052 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126,
6053 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272,
6054 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,
6055 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,
6056 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000];
6058 static immutable double[36] kaiser6Table = [
6059 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,
6060 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,
6061 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561,
6062 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058,
6063 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600,
6064 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000];
6066 struct FuncDef {
6067 immutable(double)* table;
6068 int oversample;
6071 static immutable FuncDef Kaiser12 = FuncDef(kaiser12Table.ptr, 64);
6072 static immutable FuncDef Kaiser10 = FuncDef(kaiser10Table.ptr, 32);
6073 static immutable FuncDef Kaiser8 = FuncDef(kaiser8Table.ptr, 32);
6074 static immutable FuncDef Kaiser6 = FuncDef(kaiser6Table.ptr, 32);
6077 struct QualityMapping {
6078 int baseLength;
6079 int oversample;
6080 float downsampleBandwidth;
6081 float upsampleBandwidth;
6082 immutable FuncDef* windowFunc;
6086 /* This table maps conversion quality to internal parameters. There are two
6087 reasons that explain why the up-sampling bandwidth is larger than the
6088 down-sampling bandwidth:
6089 1) When up-sampling, we can assume that the spectrum is already attenuated
6090 close to the Nyquist rate (from an A/D or a previous resampling filter)
6091 2) Any aliasing that occurs very close to the Nyquist rate will be masked
6092 by the sinusoids/noise just below the Nyquist rate (guaranteed only for
6093 up-sampling).
6095 static immutable QualityMapping[11] qualityMap = [
6096 QualityMapping( 8, 4, 0.830f, 0.860f, &Kaiser6 ), /* Q0 */
6097 QualityMapping( 16, 4, 0.850f, 0.880f, &Kaiser6 ), /* Q1 */
6098 QualityMapping( 32, 4, 0.882f, 0.910f, &Kaiser6 ), /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */
6099 QualityMapping( 48, 8, 0.895f, 0.917f, &Kaiser8 ), /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */
6100 QualityMapping( 64, 8, 0.921f, 0.940f, &Kaiser8 ), /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */
6101 QualityMapping( 80, 16, 0.922f, 0.940f, &Kaiser10), /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */
6102 QualityMapping( 96, 16, 0.940f, 0.945f, &Kaiser10), /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */
6103 QualityMapping(128, 16, 0.950f, 0.950f, &Kaiser10), /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */
6104 QualityMapping(160, 16, 0.960f, 0.960f, &Kaiser10), /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */
6105 QualityMapping(192, 32, 0.968f, 0.968f, &Kaiser12), /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */
6106 QualityMapping(256, 32, 0.975f, 0.975f, &Kaiser12), /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */
6110 nothrow @trusted @nogc:
6111 /*8, 24, 40, 56, 80, 104, 128, 160, 200, 256, 320*/
6112 double computeFunc (float x, immutable FuncDef* func) {
6113 import core.stdc.math : lrintf;
6114 import std.math : floor;
6115 //double[4] interp;
6116 float y = x*func.oversample;
6117 int ind = cast(int)lrintf(floor(y));
6118 float frac = (y-ind);
6119 immutable f2 = frac*frac;
6120 immutable f3 = f2*frac;
6121 double interp3 = -0.1666666667*frac+0.1666666667*(f3);
6122 double interp2 = frac+0.5*(f2)-0.5*(f3);
6123 //double interp2 = 1.0f-0.5f*frac-f2+0.5f*f3;
6124 double interp0 = -0.3333333333*frac+0.5*(f2)-0.1666666667*(f3);
6125 // just to make sure we don't have rounding problems
6126 double interp1 = 1.0f-interp3-interp2-interp0;
6127 //sum = frac*accum[1]+(1-frac)*accum[2];
6128 return interp0*func.table[ind]+interp1*func.table[ind+1]+interp2*func.table[ind+2]+interp3*func.table[ind+3];
6132 // the slow way of computing a sinc for the table; should improve that some day
6133 float sinc (float cutoff, float x, int N, immutable FuncDef *windowFunc) {
6134 version(LittleEndian) {
6135 align(1) union temp_float { align(1): float f; uint n; }
6136 } else {
6137 static T fabs(T) (T n) pure { static if (__VERSION__ > 2067) pragma(inline, true); return (n < 0 ? -n : n); }
6139 import std.math : sin, PI;
6140 version(LittleEndian) {
6141 temp_float txx = void;
6142 txx.f = x;
6143 txx.n &= 0x7fff_ffff; // abs
6144 if (txx.f < 1.0e-6f) return cutoff;
6145 if (txx.f > 0.5f*N) return 0;
6146 } else {
6147 if (fabs(x) < 1.0e-6f) return cutoff;
6148 if (fabs(x) > 0.5f*N) return 0;
6150 //FIXME: can it really be any slower than this?
6151 immutable float xx = x*cutoff;
6152 immutable pixx = PI*xx;
6153 version(LittleEndian) {
6154 return cutoff*sin(pixx)/pixx*computeFunc(2.0*txx.f/N, windowFunc);
6155 } else {
6156 return cutoff*sin(pixx)/pixx*computeFunc(fabs(2.0*x/N), windowFunc);
6161 void cubicCoef (in float frac, float* interp) {
6162 immutable f2 = frac*frac;
6163 immutable f3 = f2*frac;
6164 // compute interpolation coefficients; i'm not sure whether this corresponds to cubic interpolation but I know it's MMSE-optimal on a sinc
6165 interp[0] = -0.16667f*frac+0.16667f*f3;
6166 interp[1] = frac+0.5f*f2-0.5f*f3;
6167 //interp[2] = 1.0f-0.5f*frac-f2+0.5f*f3;
6168 interp[3] = -0.33333f*frac+0.5f*f2-0.16667f*f3;
6169 // just to make sure we don't have rounding problems
6170 interp[2] = 1.0-interp[0]-interp[1]-interp[3];
6174 // ////////////////////////////////////////////////////////////////////////// //
6175 int resamplerBasicDirect(T) (ref OpusResampler st, uint chanIdx, const(float)* indata, uint* indataLen, float* outdata, uint* outdataLen)
6176 if (is(T == float) || is(T == double))
6178 auto N = st.filterLen;
6179 static if (is(T == double)) assert(N%4 == 0);
6180 int outSample = 0;
6181 int lastSample = st.lastSample.ptr[chanIdx];
6182 uint sampFracNum = st.sampFracNum.ptr[chanIdx];
6183 const(float)* sincTable = st.sincTable;
6184 immutable outStride = st.outStride;
6185 immutable intAdvance = st.intAdvance;
6186 immutable fracAdvance = st.fracAdvance;
6187 immutable denRate = st.denRate;
6188 T sum = void;
6189 while (!(lastSample >= cast(int)(*indataLen) || outSample >= cast(int)(*outdataLen))) {
6190 const(float)* sinct = &sincTable[sampFracNum*N];
6191 const(float)* iptr = &indata[lastSample];
6192 static if (is(T == float)) {
6193 // at least 2x speedup with SSE here (but for unrolled loop)
6194 if (N%4 == 0) {
6195 version(sincresample_use_sse) {
6196 //align(64) __gshared float[4] zero = 0;
6197 align(64) __gshared float[4+128] zeroesBuf = 0; // dmd cannot into such aligns, alas
6198 __gshared uint zeroesptr = 0;
6199 if (zeroesptr == 0) {
6200 zeroesptr = cast(uint)zeroesBuf.ptr;
6201 if (zeroesptr&0x3f) zeroesptr = (zeroesptr|0x3f)+1;
6203 //assert((zeroesptr&0x3f) == 0, "wtf?!");
6204 asm nothrow @safe @nogc {
6205 mov ECX,[N];
6206 shr ECX,2;
6207 mov EAX,[zeroesptr];
6208 movaps XMM0,[EAX];
6209 mov EAX,[sinct];
6210 mov EBX,[iptr];
6211 mov EDX,16;
6212 align 8;
6213 rbdseeloop:
6214 movups XMM1,[EAX];
6215 movups XMM2,[EBX];
6216 mulps XMM1,XMM2;
6217 addps XMM0,XMM1;
6218 add EAX,EDX;
6219 add EBX,EDX;
6220 dec ECX;
6221 jnz rbdseeloop;
6222 // store result in sum
6223 movhlps XMM1,XMM0; // now low part of XMM1 contains high part of XMM0
6224 addps XMM0,XMM1; // low part of XMM0 is ok
6225 movaps XMM1,XMM0;
6226 shufps XMM1,XMM0,0b_01_01_01_01; // 2nd float of XMM0 goes to the 1st float of XMM1
6227 addss XMM0,XMM1;
6228 movss [sum],XMM0;
6231 float sum1 = 0;
6232 foreach (immutable j; 0..N) sum1 += sinct[j]*iptr[j];
6233 import std.math;
6234 if (fabs(sum-sum1) > 0.000001f) {
6235 import core.stdc.stdio;
6236 printf("sum=%f; sum1=%f\n", sum, sum1);
6237 assert(0);
6240 } else {
6241 // no SSE; for my i3 unrolled loop is almost of the speed of SSE code
6242 T[4] accum = 0;
6243 foreach (immutable j; 0..N/4) {
6244 accum.ptr[0] += *sinct++ * *iptr++;
6245 accum.ptr[1] += *sinct++ * *iptr++;
6246 accum.ptr[2] += *sinct++ * *iptr++;
6247 accum.ptr[3] += *sinct++ * *iptr++;
6249 sum = accum.ptr[0]+accum.ptr[1]+accum.ptr[2]+accum.ptr[3];
6251 } else {
6252 sum = 0;
6253 foreach (immutable j; 0..N) sum += *sinct++ * *iptr++;
6255 outdata[outStride*outSample++] = sum;
6256 } else {
6257 if (N%4 == 0) {
6258 //TODO: write SSE code here!
6259 // for my i3 unrolled loop is ~2 times faster
6260 T[4] accum = 0;
6261 foreach (immutable j; 0..N/4) {
6262 accum.ptr[0] += cast(double)*sinct++ * cast(double)*iptr++;
6263 accum.ptr[1] += cast(double)*sinct++ * cast(double)*iptr++;
6264 accum.ptr[2] += cast(double)*sinct++ * cast(double)*iptr++;
6265 accum.ptr[3] += cast(double)*sinct++ * cast(double)*iptr++;
6267 sum = accum.ptr[0]+accum.ptr[1]+accum.ptr[2]+accum.ptr[3];
6268 } else {
6269 sum = 0;
6270 foreach (immutable j; 0..N) sum += cast(double)*sinct++ * cast(double)*iptr++;
6272 outdata[outStride*outSample++] = cast(float)sum;
6274 lastSample += intAdvance;
6275 sampFracNum += fracAdvance;
6276 if (sampFracNum >= denRate) {
6277 sampFracNum -= denRate;
6278 ++lastSample;
6281 st.lastSample.ptr[chanIdx] = lastSample;
6282 st.sampFracNum.ptr[chanIdx] = sampFracNum;
6283 return outSample;
6287 int resamplerBasicInterpolate(T) (ref OpusResampler st, uint chanIdx, const(float)* indata, uint *indataLen, float *outdata, uint *outdataLen)
6288 if (is(T == float) || is(T == double))
6290 immutable N = st.filterLen;
6291 assert(N%4 == 0);
6292 int outSample = 0;
6293 int lastSample = st.lastSample.ptr[chanIdx];
6294 uint sampFracNum = st.sampFracNum.ptr[chanIdx];
6295 immutable outStride = st.outStride;
6296 immutable intAdvance = st.intAdvance;
6297 immutable fracAdvance = st.fracAdvance;
6298 immutable denRate = st.denRate;
6299 float sum;
6301 float[4] interp = void;
6302 T[4] accum = void;
6303 while (!(lastSample >= cast(int)(*indataLen) || outSample >= cast(int)(*outdataLen))) {
6304 const(float)* iptr = &indata[lastSample];
6305 const int offset = sampFracNum*st.oversample/st.denRate;
6306 const float frac = (cast(float)((sampFracNum*st.oversample)%st.denRate))/st.denRate;
6307 accum[] = 0;
6308 //TODO: optimize!
6309 foreach (immutable j; 0..N) {
6310 immutable T currIn = iptr[j];
6311 accum.ptr[0] += currIn*(st.sincTable[4+(j+1)*st.oversample-offset-2]);
6312 accum.ptr[1] += currIn*(st.sincTable[4+(j+1)*st.oversample-offset-1]);
6313 accum.ptr[2] += currIn*(st.sincTable[4+(j+1)*st.oversample-offset]);
6314 accum.ptr[3] += currIn*(st.sincTable[4+(j+1)*st.oversample-offset+1]);
6317 cubicCoef(frac, interp.ptr);
6318 sum = (interp.ptr[0]*accum.ptr[0])+(interp.ptr[1]*accum.ptr[1])+(interp.ptr[2]*accum.ptr[2])+(interp.ptr[3]*accum.ptr[3]);
6320 outdata[outStride*outSample++] = sum;
6321 lastSample += intAdvance;
6322 sampFracNum += fracAdvance;
6323 if (sampFracNum >= denRate) {
6324 sampFracNum -= denRate;
6325 ++lastSample;
6329 st.lastSample.ptr[chanIdx] = lastSample;
6330 st.sampFracNum.ptr[chanIdx] = sampFracNum;
6331 return outSample;
6335 // ////////////////////////////////////////////////////////////////////////// //
6336 uint gcd (uint a, uint b) pure {
6337 if (a == 0) return b;
6338 if (b == 0) return a;
6339 for (;;) {
6340 if (a > b) {
6341 a %= b;
6342 if (a == 0) return b;
6343 if (a == 1) return 1;
6344 } else {
6345 b %= a;
6346 if (b == 0) return a;
6347 if (b == 1) return 1;
6353 enum AV_SAMPLE_FMT_FLTP = 8; //HACK
6356 static immutable uint16_t[16] silk_frame_duration_ms = [
6357 10, 20, 40, 60,
6358 10, 20, 40, 60,
6359 10, 20, 40, 60,
6360 10, 20,
6361 10, 20,
6364 /* number of samples of silence to feed to the resampler at the beginning */
6365 static immutable int[5] silk_resample_delay = [ 4, 8, 11, 11, 11 ];
6367 static immutable uint8_t[5] celt_band_end = [ 13, 17, 17, 19, 21 ];
6369 static int get_silk_samplerate (int config) {
6370 return (config < 4 ? 8000 : config < 8 ? 12000 : 16000);
6374 * Range decoder
6376 static int opus_rc_init (OpusRangeCoder *rc, const(uint8_t)* data, int size) {
6377 //conwritefln!"size=%s; 0x%02x"(size, data[0]);
6378 int ret = rc.gb.init_get_bits8(data, size);
6379 if (ret < 0) return ret;
6381 rc.range = 128;
6382 rc.value = 127 - rc.gb.get_bits(7);
6383 rc.total_read_bits = 9;
6384 opus_rc_normalize(rc);
6385 //conwriteln("range=", rc.range, "; value=", rc.value);
6386 //assert(0);
6388 return 0;
6391 static void opus_raw_init (OpusRangeCoder* rc, const(uint8_t)* rightend, uint bytes) {
6392 rc.rb.position = rightend;
6393 rc.rb.bytes = bytes;
6394 rc.rb.cachelen = 0;
6395 rc.rb.cacheval = 0;
6398 static void opus_fade (float *out_, const(float)* in1, const(float)* in2, const(float)* window, int len) {
6399 for (int i = 0; i < len; i++) out_[i] = in2[i] * window[i] + in1[i] * (1.0 - window[i]);
6402 static int opus_flush_resample (OpusStreamContext* s, int nb_samples) {
6403 int celt_size = av_audio_fifo_size(s.celt_delay); //k8
6404 int ret, i;
6405 ret = s.flr.swrconvert(cast(float**)s.out_, nb_samples, null, 0);
6406 if (ret < 0) return AVERROR_BUG;
6407 if (ret != nb_samples) {
6408 //av_log(s.avctx, AV_LOG_ERROR, "Wrong number of flushed samples: %d\n", ret);
6409 return AVERROR_BUG;
6412 if (celt_size) {
6413 if (celt_size != nb_samples) {
6414 //av_log(s.avctx, AV_LOG_ERROR, "Wrong number of CELT delay samples.\n");
6415 return AVERROR_BUG;
6417 av_audio_fifo_read(s.celt_delay, cast(void**)s.celt_output.ptr, nb_samples);
6418 for (i = 0; i < s.output_channels; i++) {
6419 vector_fmac_scalar(s.out_[i], s.celt_output[i], 1.0, nb_samples);
6423 if (s.redundancy_idx) {
6424 for (i = 0; i < s.output_channels; i++) {
6425 opus_fade(s.out_[i], s.out_[i], s.redundancy_output[i] + 120 + s.redundancy_idx, ff_celt_window2.ptr + s.redundancy_idx, 120 - s.redundancy_idx);
6427 s.redundancy_idx = 0;
6430 s.out_[0] += nb_samples;
6431 s.out_[1] += nb_samples;
6432 s.out_size -= nb_samples * float.sizeof;
6434 return 0;
6437 static int opus_init_resample (OpusStreamContext* s) {
6438 float[16] delay = 0.0;
6439 const(float)*[2] delayptr = [ cast(immutable(float)*)delay.ptr, cast(immutable(float)*)delay.ptr ];
6440 float[128] odelay = void;
6441 float*[2] odelayptr = [ odelay.ptr, odelay.ptr ];
6442 int ret;
6444 if (s.flr.inited && s.flr.getInRate == s.silk_samplerate) {
6445 s.flr.reset();
6446 } else if (!s.flr.inited || s.flr.getChans != s.output_channels) {
6447 // use Voip(3) quality
6448 if (s.flr.setup(s.output_channels, s.silk_samplerate, 48000, 3) != s.flr.Error.OK) return AVERROR_BUG;
6449 } else {
6450 if (s.flr.setRate(s.silk_samplerate, 48000) != s.flr.Error.OK) return AVERROR_BUG;
6453 ret = s.flr.swrconvert(odelayptr.ptr, 128, delayptr.ptr, silk_resample_delay[s.packet.bandwidth]);
6454 if (ret < 0) {
6455 //av_log(s.avctx, AV_LOG_ERROR, "Error feeding initial silence to the resampler.\n");
6456 return AVERROR_BUG;
6459 return 0;
6462 static int opus_decode_redundancy (OpusStreamContext* s, const(uint8_t)* data, int size) {
6463 int ret;
6464 OpusBandwidth bw = s.packet.bandwidth;
6466 if (s.packet.mode == OPUS_MODE_SILK && bw == OPUS_BANDWIDTH_MEDIUMBAND) bw = OPUS_BANDWIDTH_WIDEBAND;
6468 ret = opus_rc_init(&s.redundancy_rc, data, size);
6469 if (ret < 0) goto fail;
6470 opus_raw_init(&s.redundancy_rc, data + size, size);
6472 ret = ff_celt_decode_frame(s.celt, &s.redundancy_rc, s.redundancy_output.ptr, s.packet.stereo + 1, 240, 0, celt_band_end[s.packet.bandwidth]);
6473 if (ret < 0) goto fail;
6475 return 0;
6476 fail:
6477 //av_log(s.avctx, AV_LOG_ERROR, "Error decoding the redundancy frame.\n");
6478 return ret;
6481 static int opus_decode_frame (OpusStreamContext* s, const(uint8_t)* data, int size) {
6482 import core.stdc.string : memcpy;
6483 int samples = s.packet.frame_duration;
6484 int redundancy = 0;
6485 int redundancy_size, redundancy_pos;
6486 int ret, i, consumed;
6487 int delayed_samples = s.delayed_samples;
6489 ret = opus_rc_init(&s.rc, data, size);
6490 if (ret < 0) return ret;
6492 //if (s.packet.mode != OPUS_MODE_CELT) assert(0);
6493 // decode the silk frame
6494 if (s.packet.mode == OPUS_MODE_SILK || s.packet.mode == OPUS_MODE_HYBRID) {
6495 if (!s.flr.inited) {
6496 ret = opus_init_resample(s);
6497 if (ret < 0) return ret;
6499 //conwriteln("silk sr: ", s.silk_samplerate);
6501 samples = ff_silk_decode_superframe(s.silk, &s.rc, s.silk_output.ptr,
6502 FFMIN(s.packet.bandwidth, OPUS_BANDWIDTH_WIDEBAND),
6503 s.packet.stereo + 1,
6504 silk_frame_duration_ms[s.packet.config]);
6505 if (samples < 0) {
6506 //av_log(s.avctx, AV_LOG_ERROR, "Error decoding a SILK frame.\n");
6507 return samples;
6509 //samples = swr_convert(s.swr, cast(uint8_t**)s.out_.ptr, s.packet.frame_duration, cast(const(uint8_t)**)s.silk_output.ptr, samples);
6510 immutable insamples = samples;
6511 samples = s.flr.swrconvert(cast(float**)s.out_.ptr, s.packet.frame_duration, cast(const(float)**)s.silk_output.ptr, samples);
6512 if (samples < 0) {
6513 //av_log(s.avctx, AV_LOG_ERROR, "Error resampling SILK data.\n");
6514 return samples;
6516 //conwriteln("dcsamples: ", samples, "; outs=", s.packet.frame_duration, "; ins=", insamples);
6517 //k8???!!! assert((samples & 7) == 0);
6518 s.delayed_samples += s.packet.frame_duration - samples;
6519 } else {
6520 ff_silk_flush(s.silk);
6523 // decode redundancy information
6524 consumed = opus_rc_tell(&s.rc);
6525 if (s.packet.mode == OPUS_MODE_HYBRID && consumed + 37 <= size * 8) redundancy = opus_rc_p2model(&s.rc, 12);
6526 else if (s.packet.mode == OPUS_MODE_SILK && consumed + 17 <= size * 8) redundancy = 1;
6528 if (redundancy) {
6529 redundancy_pos = opus_rc_p2model(&s.rc, 1);
6531 if (s.packet.mode == OPUS_MODE_HYBRID)
6532 redundancy_size = opus_rc_unimodel(&s.rc, 256) + 2;
6533 else
6534 redundancy_size = size - (consumed + 7) / 8;
6535 size -= redundancy_size;
6536 if (size < 0) {
6537 //av_log(s.avctx, AV_LOG_ERROR, "Invalid redundancy frame size.\n");
6538 return AVERROR_INVALIDDATA;
6541 if (redundancy_pos) {
6542 ret = opus_decode_redundancy(s, data + size, redundancy_size);
6543 if (ret < 0) return ret;
6544 ff_celt_flush(s.celt);
6548 // decode the CELT frame
6549 if (s.packet.mode == OPUS_MODE_CELT || s.packet.mode == OPUS_MODE_HYBRID) {
6550 float*[2] out_tmp = [ s.out_[0], s.out_[1] ];
6551 float **dst = (s.packet.mode == OPUS_MODE_CELT ? out_tmp.ptr : s.celt_output.ptr);
6552 int celt_output_samples = samples;
6553 int delay_samples = av_audio_fifo_size(s.celt_delay);
6555 if (delay_samples) {
6556 if (s.packet.mode == OPUS_MODE_HYBRID) {
6557 av_audio_fifo_read(s.celt_delay, cast(void**)s.celt_output.ptr, delay_samples);
6559 for (i = 0; i < s.output_channels; i++) {
6560 vector_fmac_scalar(out_tmp[i], s.celt_output[i], 1.0, delay_samples);
6561 out_tmp[i] += delay_samples;
6563 celt_output_samples -= delay_samples;
6564 } else {
6565 //av_log(s.avctx, AV_LOG_WARNING, "Spurious CELT delay samples present.\n");
6566 av_audio_fifo_drain(s.celt_delay, delay_samples);
6567 //if (s.avctx.err_recognition & AV_EF_EXPLODE) return AVERROR_BUG;
6571 opus_raw_init(&s.rc, data + size, size);
6573 ret = ff_celt_decode_frame(s.celt, &s.rc, dst,
6574 s.packet.stereo + 1,
6575 s.packet.frame_duration,
6576 (s.packet.mode == OPUS_MODE_HYBRID) ? 17 : 0,
6577 celt_band_end[s.packet.bandwidth]);
6578 if (ret < 0) return ret;
6580 if (s.packet.mode == OPUS_MODE_HYBRID) {
6581 int celt_delay = s.packet.frame_duration - celt_output_samples;
6582 void*[2] delaybuf = [ s.celt_output[0] + celt_output_samples,
6583 s.celt_output[1] + celt_output_samples ];
6585 for (i = 0; i < s.output_channels; i++) {
6586 vector_fmac_scalar(out_tmp[i], s.celt_output[i], 1.0, celt_output_samples);
6589 ret = av_audio_fifo_write(s.celt_delay, delaybuf.ptr, celt_delay);
6590 if (ret < 0) return ret;
6592 } else {
6593 ff_celt_flush(s.celt);
6596 if (s.redundancy_idx) {
6597 for (i = 0; i < s.output_channels; i++) {
6598 opus_fade(s.out_[i], s.out_[i],
6599 s.redundancy_output[i] + 120 + s.redundancy_idx,
6600 ff_celt_window2.ptr + s.redundancy_idx, 120 - s.redundancy_idx);
6602 s.redundancy_idx = 0;
6605 if (redundancy) {
6606 if (!redundancy_pos) {
6607 ff_celt_flush(s.celt);
6608 ret = opus_decode_redundancy(s, data + size, redundancy_size);
6609 if (ret < 0) return ret;
6611 for (i = 0; i < s.output_channels; i++) {
6612 opus_fade(s.out_[i] + samples - 120 + delayed_samples,
6613 s.out_[i] + samples - 120 + delayed_samples,
6614 s.redundancy_output[i] + 120,
6615 ff_celt_window2.ptr, 120 - delayed_samples);
6616 if (delayed_samples)
6617 s.redundancy_idx = 120 - delayed_samples;
6619 } else {
6620 for (i = 0; i < s.output_channels; i++) {
6621 memcpy(s.out_[i] + delayed_samples, s.redundancy_output[i], 120 * float.sizeof);
6622 opus_fade(s.out_[i] + 120 + delayed_samples,
6623 s.redundancy_output[i] + 120,
6624 s.out_[i] + 120 + delayed_samples,
6625 ff_celt_window2.ptr, 120);
6630 return samples;
6633 static int opus_decode_subpacket (OpusStreamContext* s, const(uint8_t)* buf, int buf_size, float** out_, int out_size, int nb_samples) {
6634 import core.stdc.string : memset;
6635 int output_samples = 0;
6636 int flush_needed = 0;
6637 int i, j, ret;
6639 s.out_[0] = out_[0];
6640 s.out_[1] = out_[1];
6641 s.out_size = out_size;
6643 /* check if we need to flush the resampler */
6644 if (s.flr.inited) {
6645 if (buf) {
6646 int64_t cur_samplerate = s.flr.getInRate;
6647 //av_opt_get_int(s.swr, "in_sample_rate", 0, &cur_samplerate);
6648 flush_needed = (s.packet.mode == OPUS_MODE_CELT) || (cur_samplerate != s.silk_samplerate);
6649 } else {
6650 flush_needed = !!s.delayed_samples;
6654 if (!buf && !flush_needed)
6655 return 0;
6657 /* use dummy output buffers if the channel is not mapped to anything */
6658 if (s.out_[0] is null ||
6659 (s.output_channels == 2 && s.out_[1] is null)) {
6660 av_fast_malloc(cast(void**)&s.out_dummy, &s.out_dummy_allocated_size, s.out_size);
6661 if (!s.out_dummy)
6662 return AVERROR(ENOMEM);
6663 if (!s.out_[0])
6664 s.out_[0] = s.out_dummy;
6665 if (!s.out_[1])
6666 s.out_[1] = s.out_dummy;
6669 /* flush the resampler if necessary */
6670 if (flush_needed) {
6671 ret = opus_flush_resample(s, s.delayed_samples);
6672 if (ret < 0) {
6673 //av_log(s.avctx, AV_LOG_ERROR, "Error flushing the resampler.\n");
6674 return ret;
6676 //swr_close(s.swr);
6677 s.flr.deinit();
6678 output_samples += s.delayed_samples;
6679 s.delayed_samples = 0;
6681 if (!buf)
6682 goto finish;
6685 /* decode all the frames in the packet */
6686 for (i = 0; i < s.packet.frame_count; i++) {
6687 int size = s.packet.frame_size[i];
6688 int samples = opus_decode_frame(s, buf + s.packet.frame_offset[i], size);
6690 if (samples < 0) {
6691 //av_log(s.avctx, AV_LOG_ERROR, "Error decoding an Opus frame.\n");
6692 //if (s.avctx.err_recognition & AV_EF_EXPLODE) return samples;
6694 for (j = 0; j < s.output_channels; j++)
6695 memset(s.out_[j], 0, s.packet.frame_duration * float.sizeof);
6696 samples = s.packet.frame_duration;
6698 output_samples += samples;
6700 for (j = 0; j < s.output_channels; j++)
6701 s.out_[j] += samples;
6702 s.out_size -= samples * float.sizeof;
6705 finish:
6706 s.out_[0] = s.out_[1] = null;
6707 s.out_size = 0;
6709 return output_samples;
6713 // ////////////////////////////////////////////////////////////////////////// //
6714 int opus_decode_packet (/*AVCtx* avctx,*/ OpusContext* c, AVFrame* frame, int* got_frame_ptr, AVPacket* avpkt) {
6715 import core.stdc.string : memcpy, memset;
6716 //AVFrame *frame = data;
6717 const(uint8_t)*buf = avpkt.data;
6718 int buf_size = avpkt.size;
6719 int coded_samples = 0;
6720 int decoded_samples = int.max;
6721 int delayed_samples = 0;
6722 int i, ret;
6725 if (buf_size > 3) {
6726 import iv.vfs;
6727 auto fo = VFile("./zpkt.bin", "w");
6728 fo.rawWriteExact(buf[0..buf_size]);
6729 fo.close();
6730 assert(0);
6734 // calculate the number of delayed samples
6735 for (i = 0; i < c.nb_streams; i++) {
6736 OpusStreamContext *s = &c.streams[i];
6737 s.out_[0] = s.out_[1] = null;
6738 delayed_samples = FFMAX(delayed_samples, s.delayed_samples+av_audio_fifo_size(c.sync_buffers[i]));
6741 // decode the header of the first sub-packet to find out the sample count
6742 if (buf !is null) {
6743 OpusPacket *pkt = &c.streams[0].packet;
6744 ret = ff_opus_parse_packet(pkt, buf, buf_size, c.nb_streams > 1);
6745 if (ret < 0) {
6746 //av_log(avctx, AV_LOG_ERROR, "Error parsing the packet header.\n");
6747 return ret;
6749 coded_samples += pkt.frame_count * pkt.frame_duration;
6750 c.streams[0].silk_samplerate = get_silk_samplerate(pkt.config);
6753 frame.nb_samples = coded_samples + delayed_samples;
6754 //conwriteln("frame samples: ", frame.nb_samples);
6756 /* no input or buffered data => nothing to do */
6757 if (!frame.nb_samples) {
6758 *got_frame_ptr = 0;
6759 return 0;
6762 /* setup the data buffers */
6763 ret = ff_get_buffer(frame, 0);
6764 if (ret < 0) return ret;
6765 frame.nb_samples = 0;
6767 memset(c.out_, 0, c.nb_streams*2*(*c.out_).sizeof);
6768 for (i = 0; i < c.in_channels; i++) {
6769 ChannelMap *map = &c.channel_maps[i];
6770 //if (!map.copy) conwriteln("[", 2*map.stream_idx+map.channel_idx, "] = [", i, "]");
6771 if (!map.copy) c.out_[2*map.stream_idx+map.channel_idx] = cast(float*)frame.extended_data[i];
6774 // read the data from the sync buffers
6775 for (i = 0; i < c.nb_streams; i++) {
6776 float** out_ = c.out_+2*i;
6777 int sync_size = av_audio_fifo_size(c.sync_buffers[i]);
6779 float[32] sync_dummy = void;
6780 int out_dummy = (!out_[0]) | ((!out_[1]) << 1);
6782 if (!out_[0]) out_[0] = sync_dummy.ptr;
6783 if (!out_[1]) out_[1] = sync_dummy.ptr;
6784 if (out_dummy && sync_size > /*FF_ARRAY_ELEMS*/sync_dummy.length) return AVERROR_BUG;
6786 ret = av_audio_fifo_read(c.sync_buffers[i], cast(void**)out_, sync_size);
6787 if (ret < 0) return ret;
6789 if (out_dummy & 1) out_[0] = null; else out_[0] += ret;
6790 if (out_dummy & 2) out_[1] = null; else out_[1] += ret;
6792 //conwriteln("ret=", ret);
6793 c.out_size[i] = cast(int)(frame.linesize[0]-ret*float.sizeof);
6796 // decode each sub-packet
6797 for (i = 0; i < c.nb_streams; i++) {
6798 OpusStreamContext *s = &c.streams[i];
6799 if (i && buf) {
6800 ret = ff_opus_parse_packet(&s.packet, buf, buf_size, (i != c.nb_streams-1));
6801 if (ret < 0) {
6802 //av_log(avctx, AV_LOG_ERROR, "Error parsing the packet header.\n");
6803 return ret;
6805 if (coded_samples != s.packet.frame_count * s.packet.frame_duration) {
6806 //av_log(avctx, AV_LOG_ERROR, "Mismatching coded sample count in substream %d.\n", i);
6807 return AVERROR_INVALIDDATA;
6809 s.silk_samplerate = get_silk_samplerate(s.packet.config);
6812 ret = opus_decode_subpacket(&c.streams[i], buf, s.packet.data_size, c.out_+2*i, c.out_size[i], coded_samples);
6813 if (ret < 0) return ret;
6814 c.decoded_samples[i] = ret;
6815 decoded_samples = FFMIN(decoded_samples, ret);
6817 buf += s.packet.packet_size;
6818 buf_size -= s.packet.packet_size;
6821 // buffer the extra samples
6822 for (i = 0; i < c.nb_streams; i++) {
6823 int buffer_samples = c.decoded_samples[i]-decoded_samples;
6824 if (buffer_samples) {
6825 float*[2] buff = [ c.out_[2 * i + 0] ? c.out_[2 * i + 0] : cast(float*)frame.extended_data[0],
6826 c.out_[2 * i + 1] ? c.out_[2 * i + 1] : cast(float*)frame.extended_data[0] ];
6827 buff[0] += decoded_samples;
6828 buff[1] += decoded_samples;
6829 ret = av_audio_fifo_write(c.sync_buffers[i], cast(void**)buff.ptr, buffer_samples);
6830 if (ret < 0) return ret;
6834 for (i = 0; i < c.in_channels; i++) {
6835 ChannelMap *map = &c.channel_maps[i];
6836 // handle copied channels
6837 if (map.copy) {
6838 memcpy(frame.extended_data[i], frame.extended_data[map.copy_idx], frame.linesize[0]);
6839 } else if (map.silence) {
6840 memset(frame.extended_data[i], 0, frame.linesize[0]);
6842 if (c.gain_i && decoded_samples > 0) {
6843 vector_fmul_scalar(cast(float*)frame.extended_data[i], cast(float*)frame.extended_data[i], c.gain, /*FFALIGN(decoded_samples, 8)*/decoded_samples);
6847 //frame.nb_samples = decoded_samples;
6848 *got_frame_ptr = !!decoded_samples;
6850 //return /*avpkt.size*/datasize;
6851 return decoded_samples;
6855 void opus_decode_flush (OpusContext* c) {
6856 import core.stdc.string : memset;
6857 for (int i = 0; i < c.nb_streams; i++) {
6858 OpusStreamContext *s = &c.streams[i];
6860 memset(&s.packet, 0, s.packet.sizeof);
6861 s.delayed_samples = 0;
6863 if (s.celt_delay) av_audio_fifo_drain(s.celt_delay, av_audio_fifo_size(s.celt_delay));
6864 //swr_close(s.swr);
6865 s.flr.deinit();
6867 av_audio_fifo_drain(c.sync_buffers[i], av_audio_fifo_size(c.sync_buffers[i]));
6869 ff_silk_flush(s.silk);
6870 ff_celt_flush(s.celt);
6874 int opus_decode_close (OpusContext* c) {
6875 int i;
6877 for (i = 0; i < c.nb_streams; i++) {
6878 OpusStreamContext *s = &c.streams[i];
6880 ff_silk_free(&s.silk);
6881 ff_celt_free(&s.celt);
6883 av_freep(&s.out_dummy);
6884 s.out_dummy_allocated_size = 0;
6886 av_audio_fifo_free(s.celt_delay);
6887 //swr_free(&s.swr);
6888 s.flr.deinit();
6891 av_freep(&c.streams);
6893 if (c.sync_buffers) {
6894 for (i = 0; i < c.nb_streams; i++) av_audio_fifo_free(c.sync_buffers[i]);
6896 av_freep(&c.sync_buffers);
6897 av_freep(&c.decoded_samples);
6898 av_freep(&c.out_);
6899 av_freep(&c.out_size);
6901 c.nb_streams = 0;
6903 av_freep(&c.channel_maps);
6904 //av_freep(&c.fdsp);
6906 return 0;
6909 int opus_decode_init (AVCtx* avctx, OpusContext* c, short cmtgain) {
6910 int ret, i, j;
6912 avctx.sample_fmt = AV_SAMPLE_FMT_FLTP;
6913 avctx.sample_rate = 48000;
6915 //c.fdsp = avpriv_float_dsp_alloc(0);
6916 //if (!c.fdsp) return AVERROR(ENOMEM);
6918 // find out the channel configuration
6919 ret = ff_opus_parse_extradata(avctx, c, cmtgain);
6920 if (ret < 0) {
6921 av_freep(&c.channel_maps);
6922 //av_freep(&c.fdsp);
6923 return ret;
6925 c.in_channels = avctx.channels;
6927 //conwriteln("c.nb_streams=", c.nb_streams);
6928 //conwriteln("chans=", c.in_channels);
6929 // allocate and init each independent decoder
6930 c.streams = av_mallocz_array!(typeof(c.streams[0]))(c.nb_streams);
6931 c.out_ = av_mallocz_array!(typeof(c.out_[0]))(c.nb_streams * 2);
6932 c.out_size = av_mallocz_array!(typeof(c.out_size[0]))(c.nb_streams);
6933 c.sync_buffers = av_mallocz_array!(typeof(c.sync_buffers[0]))(c.nb_streams);
6934 c.decoded_samples = av_mallocz_array!(typeof(c.decoded_samples[0]))(c.nb_streams);
6935 if (c.streams is null || c.sync_buffers is null || c.decoded_samples is null || c.out_ is null || c.out_size is null) {
6936 c.nb_streams = 0;
6937 ret = AVERROR(ENOMEM);
6938 goto fail;
6941 for (i = 0; i < c.nb_streams; i++) {
6942 OpusStreamContext *s = &c.streams[i];
6943 uint64_t layout;
6945 s.output_channels = (i < c.nb_stereo_streams) ? 2 : 1;
6946 //conwriteln("stream #", i, "; chans: ", s.output_channels);
6948 //s.avctx = avctx;
6950 for (j = 0; j < s.output_channels; j++) {
6951 s.silk_output[j] = s.silk_buf[j].ptr;
6952 s.celt_output[j] = s.celt_buf[j].ptr;
6953 s.redundancy_output[j] = s.redundancy_buf[j].ptr;
6956 //s.fdsp = c.fdsp;
6957 layout = (s.output_channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
6960 s.swr = swr_alloc();
6961 if (!s.swr) goto fail;
6964 av_opt_set_int(s.swr, "in_sample_fmt", avctx.sample_fmt, 0);
6965 av_opt_set_int(s.swr, "out_sample_fmt", avctx.sample_fmt, 0);
6966 av_opt_set_int(s.swr, "in_channel_layout", layout, 0);
6967 av_opt_set_int(s.swr, "out_channel_layout", layout, 0);
6968 av_opt_set_int(s.swr, "out_sample_rate", avctx.sample_rate, 0);
6969 av_opt_set_int(s.swr, "filter_size", 16, 0);
6973 s.swr = swr_alloc_set_opts(null,
6974 layout, // out_ch_layout
6975 AV_SAMPLE_FMT_FLTP, // out_sample_fmt
6976 avctx.sample_rate, // out_sample_rate
6977 layout, // in_ch_layout
6978 AV_SAMPLE_FMT_FLTP, // in_sample_fmt
6979 avctx.sample_rate, // in_sample_rate
6980 0, null);
6982 conwriteln("in_sample_fmt : ", avctx.sample_fmt);
6983 conwriteln("out_sample_fmt : ", avctx.sample_fmt);
6984 conwriteln("in_channel_layout : ", layout);
6985 conwriteln("out_channel_layout: ", layout);
6986 conwriteln("out_sample_rate : ", avctx.sample_rate);
6987 conwriteln("filter_size : ", 16);
6990 ret = ff_silk_init(/*avctx, */&s.silk, s.output_channels);
6991 if (ret < 0) goto fail;
6993 ret = ff_celt_init(/*avctx, */&s.celt, s.output_channels);
6994 if (ret < 0) goto fail;
6996 s.celt_delay = av_audio_fifo_alloc(avctx.sample_fmt, s.output_channels, 1024);
6997 if (!s.celt_delay) {
6998 ret = AVERROR(ENOMEM);
6999 goto fail;
7002 c.sync_buffers[i] = av_audio_fifo_alloc(avctx.sample_fmt, s.output_channels, 32);
7003 if (!c.sync_buffers[i]) {
7004 ret = AVERROR(ENOMEM);
7005 goto fail;
7009 return 0;
7010 fail:
7011 opus_decode_close(/*avctx*/c);
7012 return ret;
7016 int opus_decode_init_ll (OpusContext* c) {
7017 int channels = 2;
7018 c.gain_i = 0;
7019 c.gain = 0;
7020 c.nb_streams = 1;
7021 c.nb_stereo_streams = 1;
7022 c.in_channels = channels;
7023 c.channel_maps = av_mallocz_array!(typeof(c.channel_maps[0]))(channels);
7024 if (c.channel_maps is null) return AVERROR(ENOMEM);
7025 c.channel_maps[0].stream_idx = 0;
7026 c.channel_maps[0].channel_idx = 0;
7027 c.channel_maps[1].stream_idx = 0;
7028 c.channel_maps[1].channel_idx = 1;
7030 //conwriteln("c.nb_streams=", c.nb_streams);
7031 // allocate and init each independent decoder
7032 c.streams = av_mallocz_array!(typeof(c.streams[0]))(c.nb_streams);
7033 c.out_ = av_mallocz_array!(typeof(c.out_[0]))(c.nb_streams * 2);
7034 c.out_size = av_mallocz_array!(typeof(c.out_size[0]))(c.nb_streams);
7035 c.sync_buffers = av_mallocz_array!(typeof(c.sync_buffers[0]))(c.nb_streams);
7036 c.decoded_samples = av_mallocz_array!(typeof(c.decoded_samples[0]))(c.nb_streams);
7037 if (c.streams is null || c.sync_buffers is null || c.decoded_samples is null || c.out_ is null || c.out_size is null) {
7038 c.nb_streams = 0;
7039 opus_decode_close(c);
7040 return AVERROR(ENOMEM);
7043 foreach (immutable i; 0..c.nb_streams) {
7044 OpusStreamContext *s = &c.streams[i];
7045 uint64_t layout;
7047 s.output_channels = (i < c.nb_stereo_streams ? 2 : 1);
7048 //conwriteln("stream #", i, "; chans: ", s.output_channels);
7050 foreach (immutable j; 0..s.output_channels) {
7051 s.silk_output[j] = s.silk_buf[j].ptr;
7052 s.celt_output[j] = s.celt_buf[j].ptr;
7053 s.redundancy_output[j] = s.redundancy_buf[j].ptr;
7056 layout = (s.output_channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
7059 s.swr = swr_alloc_set_opts(null,
7060 layout, // out_ch_layout
7061 AV_SAMPLE_FMT_FLTP, // out_sample_fmt
7062 48000, // out_sample_rate
7063 layout, // in_ch_layout
7064 AV_SAMPLE_FMT_FLTP, // in_sample_fmt
7065 48000, // in_sample_rate
7066 0, null);
7069 if (ff_silk_init(/*avctx, */&s.silk, s.output_channels) < 0) {
7070 opus_decode_close(c);
7071 return AVERROR(ENOMEM);
7074 if (ff_celt_init(/*avctx, */&s.celt, s.output_channels) < 0) {
7075 opus_decode_close(c);
7076 return AVERROR(ENOMEM);
7079 s.celt_delay = av_audio_fifo_alloc(AV_SAMPLE_FMT_FLTP, s.output_channels, 1024);
7080 if (!s.celt_delay) {
7081 opus_decode_close(c);
7082 return AVERROR(ENOMEM);
7085 c.sync_buffers[i] = av_audio_fifo_alloc(AV_SAMPLE_FMT_FLTP, s.output_channels, 32);
7086 if (!c.sync_buffers[i]) {
7087 opus_decode_close(c);
7088 return AVERROR(ENOMEM);
7092 return 0;
7094 } // nothrow @nogc
7097 // ////////////////////////////////////////////////////////////////////////// //
7098 struct OggStream {
7099 private:
7100 enum MaxPageSize = 65025+Offsets.Lacing+255;
7101 //pragma(msg, MaxPageSize); // 65307 bytes
7102 //enum MaxPageSize = 65536;
7104 // Ogg header entry offsets
7105 enum Offsets {
7106 Capture = 0,
7107 Version = 4,
7108 Flags = 5,
7109 Granulepos = 6,
7110 Serialno = 14,
7111 Sequenceno = 18,
7112 Crc = 22,
7113 Segments = 26,
7114 Lacing = 27,
7117 private:
7118 VFile fl;
7119 //ubyte[] buf;
7120 ubyte[65536*2] buf;
7121 uint bufpos, bufused;
7122 uint serno, seqno;
7123 bool eofhit; // "end-of-stream" hit
7124 long logStreamSize;
7125 ulong bytesRead;
7126 ulong newpos;
7127 long firstpagepos;
7128 long firstdatapgofs = -1;
7129 ulong firstgranule;
7131 // current page info
7132 bool pgbos, pgeos, pgcont;
7133 ulong pggranule;
7134 ubyte segments;
7135 uint pgseqno, pgserno;
7136 uint pglength, pgdatalength;
7137 ubyte[255] seglen;
7138 uint curseg; // for packet reader
7140 PageInfo lastpage;
7142 public:
7143 bool packetBos;
7144 bool packetEos;
7145 bool packetBop; // first packet in page?
7146 bool packetEop; // last packet in page?
7147 ulong packetGranule;
7148 ubyte[] packetData;
7149 uint packetLength;
7151 private:
7152 void moveBuf () {
7153 if (bufpos >= bufused) { bufpos = bufused = 0; return; }
7154 if (bufpos > 0) {
7155 import core.stdc.string : memmove;
7156 memmove(buf.ptr, buf.ptr+bufpos, bufused-bufpos);
7157 bufused -= bufpos;
7158 bufpos = 0;
7162 bool ensureBytes (uint len) {
7163 import core.stdc.string : memmove;
7164 if (len > buf.length) assert(0, "internal OggStream error");
7165 if (bufused-bufpos >= len) return true;
7166 if (eofhit) return false;
7167 // shift bytes
7168 if (bufused-bufpos > 0) {
7169 memmove(buf.ptr, buf.ptr+bufpos, bufused-bufpos);
7170 bufused -= bufpos;
7171 bufpos = 0;
7172 } else {
7173 bufused = bufpos = 0;
7175 assert(bufpos == 0);
7176 assert(bufused < len);
7177 while (bufused < len) {
7178 auto rd = fl.rawRead(buf[bufused..len]);
7179 if (rd.length == 0) { eofhit = true; return false; }
7180 bufused += cast(uint)rd.length;
7182 return true;
7185 bool parsePageHeader () {
7186 if (!ensureBytes(Offsets.Lacing)) return false;
7187 if (!ensureBytes(Offsets.Lacing+buf.ptr[bufpos+Offsets.Segments])) return false;
7188 if (bufpos >= bufused) return false;
7189 auto p = (cast(const(ubyte)*)buf.ptr)+bufpos;
7190 if (p[0] != 'O' || p[1] != 'g' || p[2] != 'g' || p[3] != 'S') return false;
7191 if (p[Offsets.Version] != 0) return false;
7192 ubyte flags = p[Offsets.Flags];
7193 if ((flags&~0x07) != 0) return false;
7194 ulong grpos = getMemInt!ulong(p+Offsets.Granulepos);
7195 uint serialno = getMemInt!uint(p+Offsets.Serialno);
7196 uint sequenceno = getMemInt!uint(p+Offsets.Sequenceno);
7197 uint crc = getMemInt!uint(p+Offsets.Crc);
7198 ubyte segcount = p[Offsets.Segments];
7199 if (!ensureBytes(Offsets.Lacing+segcount)) return false;
7200 p = (cast(const(ubyte)*)buf.ptr)+bufpos;
7201 // calculate page size
7202 uint len = Offsets.Lacing+segcount;
7203 foreach (ubyte b; p[Offsets.Lacing..Offsets.Lacing+segcount]) len += b;
7204 if (!ensureBytes(len)) return false; // alas, invalid page
7205 //conwriteln("len=", len);
7206 p = (cast(const(ubyte)*)buf.ptr)+bufpos;
7207 // check page crc
7208 uint newcrc = crc32(p[0..Offsets.Crc]);
7209 ubyte[4] zeroes = 0;
7210 newcrc = crc32(zeroes[], newcrc); // per spec
7211 newcrc = crc32(p[Offsets.Crc+4..len], newcrc);
7212 if (newcrc != crc) return false; // bad crc
7213 // setup values for valid page
7214 pgcont = (flags&0x01 ? true : false);
7215 pgbos = (flags&0x02 ? true : false);
7216 pgeos = (flags&0x04 ? true : false);
7217 segments = segcount;
7218 if (segcount) seglen[0..segcount] = p[Offsets.Lacing..Offsets.Lacing+segcount];
7219 pggranule = grpos;
7220 pgseqno = sequenceno;
7221 pgserno = serialno;
7222 pglength = len;
7223 pgdatalength = len-Offsets.Lacing-segcount;
7224 return true;
7227 long getfpos () {
7228 return fl.tell-bufused+bufpos;
7231 // scan for page
7232 bool nextPage(bool first, bool ignoreseqno=false) (long maxbytes=long.max) {
7233 if (eofhit) return false;
7234 scope(failure) eofhit = true;
7235 curseg = 0;
7236 static if (!first) bufpos += pglength; // skip page data
7237 clearPage();
7238 while (maxbytes >= Offsets.Lacing) {
7239 //conwriteln("0: bufpos=", bufpos, "; bufused=", bufused);
7240 //{ import core.stdc.stdio; printf("0: bufpos=%u; bufused=%u\n", bufpos, bufused); }
7241 while (bufpos >= bufused || bufused-bufpos < 4) {
7242 if (eofhit) break;
7243 if (bufpos < bufused) {
7244 import core.stdc.string : memmove;
7245 memmove(buf.ptr, buf.ptr+bufpos, bufused-bufpos);
7246 bufused -= bufpos;
7247 bufpos = 0;
7248 } else {
7249 bufpos = bufused = 0;
7251 assert(bufused <= MaxPageSize);
7252 uint rdx = MaxPageSize-bufused;
7253 if (rdx > maxbytes) rdx = cast(uint)maxbytes;
7254 auto rd = fl.rawRead(buf[bufused..bufused+rdx]);
7255 if (rd.length == 0) break;
7256 bufused += cast(uint)rd.length;
7257 maxbytes -= cast(uint)rd.length;
7259 //conwriteln("1: bufpos=", bufpos, "; bufused=", bufused, "; bleft=", bufused-bufpos);
7260 //{ import core.stdc.stdio; printf("1: bufpos=%u; bufused=%u\n", bufpos, bufused); }
7261 if (bufpos >= bufused || bufused-bufpos < 4) { eofhit = true; return false; }
7262 uint bleft = bufused-bufpos;
7263 auto b = (cast(const(ubyte)*)buf.ptr)+bufpos;
7264 while (bleft >= 4) {
7265 if (b[0] == 'O' && b[1] == 'g' && b[2] == 'g' && b[3] == 'S') {
7266 bufpos = bufused-bleft;
7267 if (parsePageHeader()) {
7268 //conwriteln("1: bufpos=", bufpos, "; bufused=", bufused, "; segs: ", seglen[0..segments], "; pgseqno=", pgseqno, "; seqno=", seqno, "; pgserno=", pgserno, "; serno=", serno);
7269 eofhit = pgeos;
7270 static if (first) {
7271 firstpagepos = fl.tell-bufused+bufpos;
7272 firstdatapgofs = (pggranule && pggranule != -1 ? firstpagepos : -1);
7273 firstgranule = pggranule;
7274 serno = pgserno;
7275 seqno = pgseqno;
7276 return true;
7277 } else {
7278 if (serno == pgserno) {
7279 //conwriteln("2: bufpos=", bufpos, "; bufused=", bufused, "; segs: ", seglen[0..segments], "; pgseqno=", pgseqno, "; seqno=", seqno, "; pgserno=", pgserno, "; serno=", serno);
7280 static if (!ignoreseqno) {
7281 bool ok = (seqno+1 == pgseqno);
7282 if (ok) ++seqno;
7283 } else {
7284 enum ok = true;
7286 if (ok) {
7287 if (firstdatapgofs == -1 && pggranule && pggranule != -1) {
7288 firstdatapgofs = fl.tell-bufused+bufpos;
7289 firstgranule = pggranule;
7291 //conwriteln("3: bufpos=", bufpos, "; bufused=", bufused, "; segs: ", seglen[0..segments], "; pgseqno=", pgseqno, "; seqno=", seqno, "; pgserno=", pgserno, "; serno=", serno);
7292 return true;
7294 // alas
7295 static if (!ignoreseqno) {
7296 eofhit = true;
7297 return false;
7301 // continue
7302 } else {
7303 if (eofhit) return false;
7305 bleft = bufused-bufpos;
7306 b = (cast(const(ubyte)*)buf.ptr)+bufpos;
7308 ++b;
7309 --bleft;
7311 bufpos = bufused;
7313 return false;
7316 void clearPage () {
7317 pgbos = pgeos = pgcont = false;
7318 pggranule = 0;
7319 segments = 0;
7320 pgseqno = pgserno = 0;
7321 pglength = pgdatalength = 0;
7322 seglen[] = 0;
7325 void clearPacket () {
7326 packetBos = packetBop = packetEop = packetEos = false;
7327 packetGranule = 0;
7328 packetData[] = 0;
7329 packetLength = 0;
7332 public:
7333 void close () {
7334 fl = fl.init;
7335 lastpage = lastpage.init;
7336 bufpos = bufused = 0;
7337 curseg = 0;
7338 bytesRead = 0;
7339 eofhit = true;
7340 firstpagepos = 0;
7341 bytesRead = newpos = 0;
7342 logStreamSize = -1;
7343 clearPage();
7344 clearPacket();
7347 void setup (VFile afl) {
7348 scope(failure) close();
7349 close();
7350 //if (buf.length < MaxPageSize) buf.length = MaxPageSize;
7351 fl = afl;
7352 eofhit = false;
7353 if (!nextPage!true()) throw new Exception("can't find valid Ogg page");
7354 if (pgcont || !pgbos) throw new Exception("invalid starting Ogg page");
7355 if (!loadPacket()) throw new Exception("can't load Ogg packet");
7358 static struct PageInfo {
7359 uint seqnum;
7360 ulong granule;
7361 long pgfpos = -1;
7364 bool findLastPage (out PageInfo pi) {
7365 if (lastpage.pgfpos >= 0) {
7366 pi = lastpage;
7367 return true;
7369 enum ChunkSize = 65535;
7370 //if (buf.length-bufused < ChunkSize) buf.length = bufused+ChunkSize;
7371 moveBuf();
7372 assert(buf.length-bufused >= ChunkSize);
7373 auto lastfpos = fl.tell;
7374 scope(success) fl.seek(lastfpos);
7375 auto flsize = fl.size;
7376 if (flsize < 0) return false;
7377 // linear scan backward
7378 auto flpos = flsize-firstpagepos-ChunkSize;
7379 if (flpos < firstpagepos) flpos = firstpagepos;
7380 for (;;) {
7381 fl.seek(flpos);
7382 uint bulen = (flpos+ChunkSize <= flsize ? ChunkSize : cast(uint)(flsize-flpos));
7383 if (bulen < 27) break;
7384 //{ import core.stdc.stdio; printf("bulen=%u\n", bulen); }
7385 fl.rawReadExact(buf[bufused..bufused+bulen]);
7386 uint pos = bufused+bulen-27;
7387 uint pend = bufused+bulen;
7388 for (;;) {
7389 if (buf.ptr[pos] == 'O' && buf.ptr[pos+1] == 'g' && buf.ptr[pos+2] == 'g' && buf.ptr[pos+3] == 'S') {
7390 ulong gran = getMemInt!ulong(buf.ptr+pos+Offsets.Granulepos);
7391 if (gran > 0 && gran != -1 && buf.ptr[pos+Offsets.Version] == 0 && getMemInt!uint(buf.ptr+pos+Offsets.Serialno) == serno) {
7392 // ok, possible page found
7393 bool rereadbuf = false;
7394 auto opos = pos;
7395 // calc page size
7396 ubyte segs = buf.ptr[pos+Offsets.Segments];
7397 uint pgsize = Offsets.Lacing+segs;
7398 ubyte[4] zeroes = 0;
7399 ubyte* p;
7400 uint newcrc;
7401 //conwritefln!"0x%08x (left: %s; pgsize0=%s)"(flpos+opos-bufused, pend-pos, pgsize);
7402 if (pend-pos < pgsize) {
7403 // load page
7404 pos = pend = bufused;
7405 rereadbuf = true;
7406 fl.seek(flpos+opos-bufused);
7407 for (uint bp = 0; bp < MaxPageSize; ) {
7408 auto rd = fl.rawRead(buf.ptr[pos+bp..pos+MaxPageSize]);
7409 if (rd.length == 0) {
7410 if (bp < pgsize) goto badpage;
7411 break;
7413 bp += cast(uint)rd.length;
7414 pend += cast(uint)rd.length;
7417 foreach (ubyte ss; buf.ptr[pos+Offsets.Lacing..pos+Offsets.Lacing+segs]) pgsize += ss;
7418 //conwritefln!"0x%08x (left: %s; pgsize1=%s)"(flpos+opos-bufused, pend-pos, pgsize);
7419 if (pend-pos < pgsize) {
7420 // load page
7421 pos = bufused;
7422 rereadbuf = true;
7423 fl.seek(flpos+opos-bufused);
7424 for (uint bp = 0; bp < MaxPageSize; ) {
7425 auto rd = fl.rawRead(buf.ptr[pos+bp..pos+MaxPageSize]);
7426 if (rd.length == 0) {
7427 if (bp < pgsize) goto badpage;
7428 break;
7430 bp += cast(uint)rd.length;
7431 pend += cast(uint)rd.length;
7434 // check page CRC
7435 p = buf.ptr+pos;
7436 newcrc = crc32(p[0..Offsets.Crc]);
7437 newcrc = crc32(zeroes[], newcrc); // per spec
7438 newcrc = crc32(p[Offsets.Crc+4..pgsize], newcrc);
7439 if (newcrc != getMemInt!uint(p+Offsets.Crc)) goto badpage;
7440 pi.seqnum = getMemInt!uint(p+Offsets.Sequenceno);
7441 pi.granule = gran;
7442 pi.pgfpos = flpos+opos-bufused;
7443 lastpage = pi;
7444 return true;
7445 badpage:
7446 if (rereadbuf) {
7447 fl.seek(flpos);
7448 fl.rawReadExact(buf[bufused..bufused+ChunkSize]);
7449 pos = opos;
7450 pend = bufused+ChunkSize;
7454 if (pos == bufused) break; // prev chunk
7455 --pos;
7457 if (flpos == firstpagepos) break; // not found
7458 flpos -= ChunkSize-30;
7459 if (flpos < firstpagepos) flpos = firstpagepos;
7461 return false;
7464 // end of stream?
7465 @property bool eos () const pure nothrow @safe @nogc { pragma(inline, true); return eofhit; }
7467 // logical beginning of stream?
7468 @property bool bos () const pure nothrow @safe @nogc { pragma(inline, true); return pgbos; }
7470 bool loadPacket () {
7471 //conwritefln!"serno=0x%08x; seqno=%s"(serno, seqno);
7472 packetLength = 0;
7473 packetBos = pgbos;
7474 packetEos = pgeos;
7475 packetGranule = pggranule;
7476 packetBop = (curseg == 0);
7477 if (curseg >= segments) {
7478 if (!nextPage!false()) return false;
7479 if (pgcont || pgbos) throw new Exception("invalid starting Ogg page");
7480 packetBos = pgbos;
7481 packetBop = true;
7482 packetGranule = pggranule;
7484 for (;;) {
7485 uint copyofs = bufpos+Offsets.Lacing+segments;
7486 foreach (ubyte psz; seglen[0..curseg]) copyofs += psz;
7487 uint copylen = 0;
7488 bool endofpacket = false;
7489 while (!endofpacket && curseg < segments) {
7490 copylen += seglen[curseg];
7491 endofpacket = (seglen[curseg++] < 255);
7493 //conwriteln("copyofs=", copyofs, "; copylen=", copylen, "; eop=", eop, "; packetLength=", packetLength, "; segments=", segments, "; curseg=", curseg);
7494 if (copylen > 0) {
7495 if (packetLength+copylen > 1024*1024*32) throw new Exception("Ogg packet too big");
7496 if (packetLength+copylen > packetData.length) packetData.length = packetLength+copylen;
7497 packetData[packetLength..packetLength+copylen] = buf.ptr[copyofs..copyofs+copylen];
7498 packetLength += copylen;
7500 if (endofpacket) {
7501 packetEop = (curseg >= segments);
7502 packetEos = pgeos;
7503 return true;
7505 assert(curseg >= segments);
7506 // get next page
7507 if (!nextPage!false()) return false;
7508 if (!pgcont || pgbos) throw new Exception("invalid cont Ogg page");
7512 /* Page granularity seek (faster than sample granularity because we
7513 don't do the last bit of decode to find a specific sample).
7515 Seek to the last [granule marked] page preceding the specified pos
7516 location, such that decoding past the returned point will quickly
7517 arrive at the requested position. */
7518 // return PCM (granule) position for loaded packet
7519 public long seekPCM (long pos) {
7520 enum ChunkSize = 65535;
7521 eofhit = false;
7523 // rescales the number x from the range of [0,from] to [0,to] x is in the range [0,from] from, to are in the range [1, 1<<62-1]
7524 static long rescale64 (long x, long from, long to) {
7525 if (x >= from) return to;
7526 if (x <= 0) return 0;
7528 long frac = 0;
7529 long ret = 0;
7531 foreach (immutable _; 0..64) {
7532 if (x >= from) { frac |= 1; x -= from; }
7533 x <<= 1;
7534 frac <<= 1;
7537 foreach (immutable _; 0..64) {
7538 if (frac&1) ret += to;
7539 frac >>= 1;
7540 ret >>= 1;
7543 return ret;
7546 if (pos < 0) return -1;
7547 if (pos <= firstgranule) {
7548 bufused = bufpos = 0;
7549 pglength = 0;
7550 curseg = 0;
7551 fl.seek(firstpagepos);
7552 eofhit = false;
7553 if (!nextPage!true()) throw new Exception("can't find valid Ogg page");
7554 if (pgcont || !pgbos) throw new Exception("invalid starting Ogg page");
7555 for (;;) {
7556 if (pggranule && pggranule != -1) {
7557 curseg = 0;
7558 //for (int p = 0; p < segments; ++p) if (seglen[p] < 255) curseg = p+1;
7559 //auto rtg = pggranule;
7560 if (!loadPacket()) throw new Exception("can't load Ogg packet");
7561 return 0;
7563 if (!nextPage!false()) throw new Exception("can't find valid Ogg page");
7567 if (lastpage.pgfpos < 0) {
7568 PageInfo pi;
7569 if (!findLastPage(pi)) throw new Exception("can't find last Ogg page");
7572 if (firstdatapgofs < 0) assert(0, "internal error");
7574 if (pos > lastpage.granule) pos = lastpage.granule;
7576 //if (buf.length < ChunkSize) buf.length = ChunkSize;
7578 long total = lastpage.granule;
7580 long end = lastpage.pgfpos;
7581 long begin = firstdatapgofs;
7582 long begintime = 0/*firstgranule*/;
7583 long endtime = lastpage.granule;
7584 long target = pos;//-total+begintime;
7585 long best = -1;
7586 bool got_page = false;
7588 // if we have only one page, there will be no bisection: grab the page here
7589 if (begin == end) {
7590 bufused = bufpos = 0;
7591 pglength = 0;
7592 curseg = 0;
7593 fl.seek(begin);
7594 eofhit = false;
7595 if (!nextPage!false()) return false;
7596 if (!loadPacket()) return false;
7597 return true;
7600 // bisection loop
7601 while (begin < end) {
7602 long bisect;
7604 if (end-begin < ChunkSize) {
7605 bisect = begin;
7606 } else {
7607 // take a (pretty decent) guess
7608 bisect = begin+rescale64(target-begintime, endtime-begintime, end-begin)-ChunkSize;
7609 if (bisect < begin+ChunkSize) bisect = begin;
7610 //conwriteln("begin=", begin, "; end=", end, "; bisect=", bisect, "; rsc=", rescale64(target-begintime, endtime-begintime, end-begin));
7613 bufused = bufpos = 0;
7614 pglength = 0;
7615 curseg = 0;
7616 fl.seek(bisect);
7617 eofhit = false;
7619 // read loop within the bisection loop
7620 while (begin < end) {
7621 // hack for nextpage
7622 if (!nextPage!(false, true)(end-getfpos)) {
7623 // there is no next page!
7624 if (bisect <= begin+1) {
7625 // no bisection left to perform: we've either found the best candidate already or failed; exit loop
7626 end = begin;
7627 } else {
7628 // we tried to load a fraction of the last page; back up a bit and try to get the whole last page
7629 if (bisect == 0) throw new Exception("seek error");
7630 bisect -= ChunkSize;
7632 // don't repeat/loop on a read we've already performed
7633 if (bisect <= begin) bisect = begin+1;
7635 // seek and continue bisection
7636 bufused = bufpos = 0;
7637 pglength = 0;
7638 curseg = 0;
7639 fl.seek(bisect);
7641 } else {
7642 //conwriteln("page #", pgseqno, " (", pggranule, ") at ", getfpos);
7643 long granulepos;
7644 got_page = true;
7646 // got a page: analyze it
7647 // only consider pages from primary vorbis stream
7648 if (pgserno != serno) continue;
7650 // only consider pages with the granulepos set
7651 granulepos = pggranule;
7652 if (granulepos == -1) continue;
7653 //conwriteln("pos=", pos, "; gran=", granulepos, "; target=", target);
7655 if (granulepos < target) {
7656 // this page is a successful candidate! Set state
7657 best = getfpos; // raw offset of packet with granulepos
7658 begin = getfpos+pglength; // raw offset of next page
7659 begintime = granulepos;
7661 // if we're before our target but within a short distance, don't bisect; read forward
7662 if (target-begintime > 48000) break;
7664 bisect = begin; // *not* begin+1 as above
7665 } else {
7666 // this is one of our pages, but the granpos is post-target; it is not a bisection return candidate
7667 // the only way we'd use it is if it's the first page in the stream; we handle that case later outside the bisection
7668 if (bisect <= begin+1) {
7669 // no bisection left to perform: we've either found the best candidate already or failed; exit loop
7670 end = begin;
7671 } else {
7672 if (end == getfpos+pglength) {
7673 // bisection read to the end; use the known page boundary (result) to update bisection, back up a little bit, and try again
7674 end = getfpos;
7675 bisect -= ChunkSize;
7676 if (bisect <= begin) bisect = begin+1;
7677 bufused = bufpos = 0;
7678 pglength = 0;
7679 curseg = 0;
7680 fl.seek(bisect);
7681 eofhit = false;
7682 } else {
7683 // normal bisection
7684 end = bisect;
7685 endtime = granulepos;
7686 break;
7694 // out of bisection: did it 'fail?'
7695 if (best == -1) {
7696 bufused = bufpos = 0;
7697 pglength = 0;
7698 curseg = 0;
7699 //{ import core.stdc.stdio; printf("fpp=%lld\n", firstpagepos); }
7700 fl.seek(firstpagepos);
7701 eofhit = false;
7702 if (!nextPage!true()) throw new Exception("can't find valid Ogg page");
7703 if (pgcont || !pgbos) throw new Exception("invalid starting Ogg page");
7704 for (;;) {
7705 if (pggranule && pggranule != -1) {
7706 curseg = 0;
7707 if (!loadPacket()) throw new Exception("can't load Ogg packet");
7708 return 0;
7710 if (!nextPage!false()) throw new Exception("can't find valid Ogg page");
7712 return 0;
7715 // bisection found our page. seek to it, update pcm offset; easier case than raw_seek, don't keep packets preceding granulepos
7716 bufused = bufpos = 0;
7717 pglength = 0;
7718 curseg = 0;
7719 fl.seek(best);
7720 if (!nextPage!(false, true)()) throw new Exception("wtf?!");
7721 auto rtg = pggranule;
7722 seqno = pgseqno;
7723 // pull out all but last packet; the one right after granulepos
7724 for (int p = 0; p < segments; ++p) if (seglen[p] < 255) curseg = p+1;
7725 if (!loadPacket()) throw new Exception("wtf?!");
7726 return rtg;
7729 static:
7730 T getMemInt(T) (const(void)* pp) {
7731 static if (is(T == byte) || is(T == ubyte)) {
7732 return *cast(const(ubyte)*)pp;
7733 } else static if (is(T == short) || is(T == ushort)) {
7734 version(LittleEndian) {
7735 return *cast(const(T)*)pp;
7736 } else {
7737 auto pp = cast(const(ubyte)*)pp;
7738 return cast(T)(pp[0]|(pp[1]<<8));
7740 } else static if (is(T == int) || is(T == uint)) {
7741 version(LittleEndian) {
7742 return *cast(const(T)*)pp;
7743 } else {
7744 auto pp = cast(const(ubyte)*)pp;
7745 return cast(T)(pp[0]|(pp[1]<<8)|(pp[2]<<16)|(pp[3]<<24));
7747 } else static if (is(T == long) || is(T == ulong)) {
7748 version(LittleEndian) {
7749 return *cast(const(T)*)pp;
7750 } else {
7751 auto pp = cast(const(ubyte)*)pp;
7752 return cast(T)(
7753 (cast(ulong)pp[0])|((cast(ulong)pp[1])<<8)|((cast(ulong)pp[2])<<16)|((cast(ulong)pp[3])<<24)|
7754 ((cast(ulong)pp[4])<<32)|((cast(ulong)pp[5])<<40)|((cast(ulong)pp[6])<<48)|((cast(ulong)pp[7])<<56)
7757 } else {
7758 static assert(0, "invalid type for getMemInt: '"~T.stringof~"'");
7762 uint crc32 (const(void)[] buf, uint crc=0) nothrow @trusted @nogc {
7763 static immutable uint[256] crctable = (){
7764 // helper to initialize lookup for direct-table CRC (illustrative; we use the static init below)
7765 static uint _ogg_crc_entry (uint index) {
7766 uint r = index<<24;
7767 foreach (immutable _; 0..8) {
7768 if (r&0x80000000U) {
7769 r = (r<<1)^0x04c11db7;
7770 /* The same as the ethernet generator
7771 polynomial, although we use an
7772 unreflected alg and an init/final
7773 of 0, not 0xffffffff */
7774 } else {
7775 r <<= 1;
7778 return (r&0xffffffffU);
7780 uint[256] res;
7781 foreach (immutable idx, ref uint v; res[]) v = _ogg_crc_entry(cast(uint)idx);
7782 return res;
7783 }();
7784 foreach (ubyte b; cast(const(ubyte)[])buf) crc = (crc<<8)^crctable.ptr[((crc>>24)&0xFF)^b];
7785 return crc;
7790 // ////////////////////////////////////////////////////////////////////////// //
7791 nothrow @nogc {
7792 enum OPUS_SEEK_PREROLL_MS = 80;
7793 enum OPUS_HEAD_SIZE = 19;
7795 static int opus_header (AVCtx* avf, ref OggStream ogg) {
7796 //uint8_t *packet = os.buf + os.pstart;
7797 if (ogg.packetBos) {
7798 if (ogg.packetLength < OPUS_HEAD_SIZE || (ogg.packetData[8]&0xF0) != 0) return AVERROR_INVALIDDATA;
7799 //st.codecpar.codec_type = AVMEDIA_TYPE_AUDIO;
7800 //st.codecpar.codec_id = AV_CODEC_ID_OPUS;
7801 //st.codecpar.channels = ost.packetData[8];
7803 avf.preskip = ogg.getMemInt!ushort(ogg.packetData.ptr+10);
7804 //!!!st.codecpar.initial_padding = priv.pre_skip;
7805 /*orig_sample_rate = AV_RL32(packet + 12);*/
7806 /*gain = AV_RL16(packet + 16);*/
7807 /*channel_map = AV_RL8 (packet + 18);*/
7809 //if (ff_alloc_extradata(st.codecpar, os.psize)) return AVERROR(ENOMEM);
7810 if (avf.extradata) av_free(avf.extradata);
7811 avf.extradata = av_mallocz!ubyte(ogg.packetLength);
7812 if (avf.extradata is null) return -1;
7813 avf.extradata[0..ogg.packetLength] = ogg.packetData[0..ogg.packetLength];
7814 avf.extradata_size = cast(uint)ogg.packetLength;
7816 //st.codecpar.sample_rate = 48000;
7817 //st.codecpar.seek_preroll = av_rescale(OPUS_SEEK_PREROLL_MS, st.codecpar.sample_rate, 1000);
7818 //avpriv_set_pts_info(st, 64, 1, 48000);
7819 avf.need_comments = 1;
7820 return 2;
7823 if (avf.need_comments) {
7824 import core.stdc.string : memcmp;
7825 if (ogg.packetLength < 8 || memcmp(ogg.packetData.ptr, "OpusTags".ptr, 8) != 0) return AVERROR_INVALIDDATA;
7826 //ff_vorbis_stream_comment(avf, st, ogg.packetData.ptr + 8, ogg.packetLength - 8);
7827 --avf.need_comments;
7828 return 1;
7831 return 0;
7834 static int opus_duration (const(uint8_t)* src, int size) {
7835 uint nb_frames = 1;
7836 uint toc = src[0];
7837 uint toc_config = toc>>3;
7838 uint toc_count = toc&3;
7839 uint frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) :
7840 toc_config < 16 ? 480 << (toc_config & 1) : 120 << (toc_config & 3);
7841 if (toc_count == 3) {
7842 if (size < 2) return AVERROR_INVALIDDATA;
7843 nb_frames = src[1]&0x3F;
7844 } else if (toc_count) {
7845 nb_frames = 2;
7847 return frame_size*nb_frames;
7850 static int opus_packet (AVCtx* avf, ref OggStream ogg) {
7851 int ret;
7853 if (!ogg.packetLength) return AVERROR_INVALIDDATA;
7854 if (ogg.packetGranule > (1UL<<62)) {
7855 //av_log(avf, AV_LOG_ERROR, "Unsupported huge granule pos %"PRId64 "\n", os.granule);
7856 return AVERROR_INVALIDDATA;
7859 //if ((!ogg.lastpts || ogg.lastpts == AV_NOPTS_VALUE) && !(ogg.flags & OGG_FLAG_EOS))
7860 if (ogg.packetGranule != 0 && !ogg.packetEos) {
7862 int seg, d;
7863 int duration;
7864 uint8_t *last_pkt = os.buf + os.pstart;
7865 uint8_t *next_pkt = last_pkt;
7867 duration = 0;
7868 seg = os.segp;
7869 d = opus_duration(last_pkt, ogg.packetLength);
7870 if (d < 0) {
7871 os.pflags |= AV_PKT_FLAG_CORRUPT;
7872 return 0;
7874 duration += d;
7875 last_pkt = next_pkt = next_pkt + ogg.packetLength;
7876 for (; seg < os.nsegs; seg++) {
7877 next_pkt += os.segments[seg];
7878 if (os.segments[seg] < 255 && next_pkt != last_pkt) {
7879 int d = opus_duration(last_pkt, next_pkt - last_pkt);
7880 if (d > 0)
7881 duration += d;
7882 last_pkt = next_pkt;
7885 os.lastpts =
7886 os.lastdts = os.granule - duration;
7890 if ((ret = opus_duration(ogg.packetData.ptr, ogg.packetLength)) < 0) return ret;
7893 os.pduration = ret;
7894 if (os.lastpts != AV_NOPTS_VALUE) {
7895 if (st.start_time == AV_NOPTS_VALUE)
7896 st.start_time = os.lastpts;
7897 priv.cur_dts = os.lastdts = os.lastpts -= priv.pre_skip;
7900 priv.cur_dts += os.pduration;
7901 if ((os.flags & OGG_FLAG_EOS)) {
7902 int64_t skip = priv.cur_dts - os.granule + priv.pre_skip;
7903 skip = FFMIN(skip, os.pduration);
7904 if (skip > 0) {
7905 os.pduration = skip < os.pduration ? os.pduration - skip : 1;
7906 os.end_trimming = skip;
7907 //av_log(avf, AV_LOG_DEBUG, "Last packet was truncated to %d due to end trimming.\n", os.pduration);
7912 return 0;
7915 } // nothrow @nogc
7918 // ////////////////////////////////////////////////////////////////////////// //
7919 align(1) union TrickyFloatUnion {
7920 align(1):
7921 float f;
7922 int i;
7924 static assert(TrickyFloatUnion.i.sizeof == 4 && TrickyFloatUnion.f.sizeof == 4);
7925 // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round
7926 enum Float2IntScaled(string x, string d) =
7927 "{ TrickyFloatUnion temp = void; temp.f = ("~x~")+(1.5f*(1<<(23-15))+0.5f/(1<<15));"~
7928 "("~d~") = temp.i-(((150-15)<<23)+(1<<22));"~
7929 "if (cast(uint)(("~d~")+32768) > 65535) ("~d~") = (("~d~") < 0 ? -32768 : 32767); }";
7932 // ////////////////////////////////////////////////////////////////////////// //
7933 import iv.vfs;
7935 struct OpusFileCtx {
7936 private:
7937 AVCtx ctx;
7938 ubyte* commbuf;
7939 uint cblen;
7940 OpusContext c;
7941 OggStream ogg;
7942 OggStream.PageInfo lastpage;
7943 short[960*3*2] samples;
7944 float[960*3*2] sbuffer;
7945 bool wantNewPacket;
7946 ulong curpcm; // for page end; let's hope that nobody will create huge ogg pages
7948 void close () {
7949 av_freep(&commbuf);
7950 av_freep(&ctx.extradata);
7951 opus_decode_close(&c);
7952 ogg.close();
7955 public:
7956 enum rate = 48000; // always
7957 @property ubyte channels () const pure nothrow @safe @nogc { pragma(inline, true); return cast(ubyte)c.streams[0].output_channels; }
7958 // all timing is in milliseconds
7959 @property long duration () const pure nothrow @safe @nogc { pragma(inline, true); return (lastpage.granule/48); }
7960 @property long curtime () const pure nothrow @safe @nogc { pragma(inline, true); return (curpcm/48); }
7962 // in samples, not multiplied by channel count
7963 @property long smpduration () const pure nothrow @safe @nogc { pragma(inline, true); return lastpage.granule; }
7964 @property long smpcurtime () const pure nothrow @safe @nogc { pragma(inline, true); return curpcm; }
7966 @property const(char)[] vendor () const pure nothrow @trusted @nogc {
7967 if (commbuf is null || cblen < 4) return null;
7968 uint len = commbuf[0]|(commbuf[1]<<8)|(commbuf[2]<<16)|(commbuf[3]<<24);
7969 if (len > cblen || cblen-len < 4) return null;
7970 return cast(const(char)[])(commbuf[4..4+len]);
7973 @property uint commentCount () const pure nothrow @trusted @nogc {
7974 if (commbuf is null || cblen < 4) return 0;
7975 uint len = commbuf[0]|(commbuf[1]<<8)|(commbuf[2]<<16)|(commbuf[3]<<24);
7976 if (len > cblen || cblen-len < 4) return 0;
7977 uint cpos = 4+len;
7978 if (cpos >= cblen || cblen-cpos < 4) return 0;
7979 uint count = commbuf[cpos+0]|(commbuf[cpos+1]<<8)|(commbuf[cpos+2]<<16)|(commbuf[cpos+3]<<24);
7980 cpos += 4;
7981 uint res = 0;
7982 while (count > 0 && cpos+4 <= cblen) {
7983 len = commbuf[cpos+0]|(commbuf[cpos+1]<<8)|(commbuf[cpos+2]<<16)|(commbuf[cpos+3]<<24);
7984 cpos += 4;
7985 if (cpos > cblen || cblen-cpos < len) break;
7986 ++res;
7987 cpos += len;
7988 --count;
7990 return res;
7993 const(char)[] comment (uint cidx) const pure nothrow @trusted @nogc {
7994 if (commbuf is null || cblen < 4) return null;
7995 uint len = commbuf[0]|(commbuf[1]<<8)|(commbuf[2]<<16)|(commbuf[3]<<24);
7996 if (len > cblen || cblen-len < 4) return null;
7997 uint cpos = 4+len;
7998 if (cpos >= cblen || cblen-cpos < 4) return null;
7999 uint count = commbuf[cpos+0]|(commbuf[cpos+1]<<8)|(commbuf[cpos+2]<<16)|(commbuf[cpos+3]<<24);
8000 cpos += 4;
8001 while (count > 0 && cpos+4 <= cblen) {
8002 len = commbuf[cpos+0]|(commbuf[cpos+1]<<8)|(commbuf[cpos+2]<<16)|(commbuf[cpos+3]<<24);
8003 cpos += 4;
8004 if (cpos > cblen || cblen-cpos < len) break;
8005 if (cidx == 0) return cast(const(char)[])(commbuf[cpos..cpos+len]);
8006 --cidx;
8007 cpos += len;
8008 --count;
8010 return null;
8013 private short getGain () const pure nothrow @trusted @nogc {
8014 if (commbuf is null || cblen < 4) return 0;
8015 uint len = commbuf[0]|(commbuf[1]<<8)|(commbuf[2]<<16)|(commbuf[3]<<24);
8016 if (len > cblen || cblen-len < 4) return 0;
8017 uint cpos = 4+len;
8018 if (cpos >= cblen || cblen-cpos < 4) return 0;
8019 uint count = commbuf[cpos+0]|(commbuf[cpos+1]<<8)|(commbuf[cpos+2]<<16)|(commbuf[cpos+3]<<24);
8020 cpos += 4;
8021 while (count > 0 && cpos+4 <= cblen) {
8022 len = commbuf[cpos+0]|(commbuf[cpos+1]<<8)|(commbuf[cpos+2]<<16)|(commbuf[cpos+3]<<24);
8023 cpos += 4;
8024 if (cpos > cblen || cblen-cpos < len) break;
8026 auto cmt = cast(const(char)[])(commbuf[cpos..cpos+len]);
8027 enum GainName = "R128_TRACK_GAIN="; //-573
8028 while (cmt.length && cmt.ptr[0] <= ' ') cmt = cmt[1..$];
8029 while (cmt.length && cmt[$-1] <= ' ') cmt = cmt[0..$-1];
8030 if (cmt.length > GainName.length) {
8031 bool ok = true;
8032 foreach (immutable xidx, char ch; cmt[0..GainName.length]) {
8033 if (ch >= 'a' && ch <= 'z') ch -= 32;
8034 if (ch != GainName[xidx]) { ok = false; break; }
8036 if (ok) {
8037 bool neg = false;
8038 int v = 0;
8039 cmt = cmt[GainName.length..$];
8040 if (cmt.length && cmt[0] == '-') { neg = true; cmt = cmt[1..$]; }
8041 else if (cmt.length && cmt[0] == '+') cmt = cmt[1..$];
8042 if (cmt.length == 0) v = -1;
8043 while (cmt.length) {
8044 int c = cmt.ptr[0];
8045 cmt = cmt[1..$];
8046 if (c < '0' || c > '9') { v = -1; break; }
8047 v = v*10+c-'0';
8048 if ((neg && v > 32768) || (!neg && v > 32767)) { v = -1; break; }
8050 if (v >= 0) {
8051 if (neg) v = -v;
8052 return cast(short)v;
8057 cpos += len;
8058 --count;
8060 return 0;
8063 void seek (long newtime) {
8064 if (newtime < 0) newtime = 0;
8065 if (newtime >= duration) newtime = duration;
8066 if (newtime >= duration) {
8067 ogg.bufused = ogg.bufpos = 0;
8068 ogg.pglength = 0;
8069 ogg.curseg = 0;
8070 ogg.fl.seek(ogg.lastpage.pgfpos);
8071 //{ import core.stdc.stdio; printf("lpofs=0x%08llx\n", ogg.lastpage.pgfpos); }
8072 ogg.eofhit = false;
8073 if (!ogg.nextPage!(false, true)()) throw new Exception("can't find valid Ogg page");
8074 ogg.seqno = ogg.pgseqno;
8075 ogg.curseg = 0;
8076 for (int p = 0; p < ogg.segments; ++p) if (ogg.seglen[p] < 255) ogg.curseg = p+1;
8077 curpcm = ogg.pggranule;
8078 wantNewPacket = true;
8079 return;
8081 long np = ogg.seekPCM(newtime*48 < ctx.preskip ? 0 : newtime*48-ctx.preskip);
8082 wantNewPacket = false;
8083 if (np < ctx.preskip) {
8084 curpcm = 0;
8085 } else {
8086 curpcm = np-ctx.preskip;
8087 // skip 80 msecs, as per specs (buggy, but...)
8088 auto oldpcm = curpcm;
8089 while (curpcm-oldpcm < 3840) {
8090 if (readFrame().length == 0) break;
8091 //{ import core.stdc.stdio; printf("frdiff=%lld\n", curpcm-oldpcm); }
8096 // read and decode one sound frame; return samples or null
8097 short[] readFrame () {
8098 AVFrame frame;
8099 AVPacket pkt;
8100 ubyte*[2] eptr;
8101 float*[2] fptr;
8102 for (;;) {
8103 if (wantNewPacket) {
8104 if (!ogg.loadPacket()) return null;
8106 //if (ogg.pggranule > 0 && ogg.pggranule != -1 && ogg.pggranule >= ctx.preskip) curpcm = ogg.pggranule-ctx.preskip;
8107 wantNewPacket = true;
8108 frame.linesize[0] = sbuffer.length*sbuffer[0].sizeof;
8109 pkt.data = ogg.packetData.ptr;
8110 pkt.size = cast(uint)ogg.packetLength;
8111 eptr[0] = cast(ubyte*)&sbuffer[0];
8112 eptr[1] = cast(ubyte*)&sbuffer[sbuffer.length/2];
8113 fptr[0] = cast(float*)eptr[0];
8114 fptr[1] = cast(float*)eptr[1];
8115 frame.extended_data = eptr.ptr;
8116 int gotfrptr = 0;
8117 auto r = opus_decode_packet(&c, &frame, &gotfrptr, &pkt);
8118 if (r < 0) throw new Exception("error processing opus frame");
8119 if (!gotfrptr) continue;
8120 curpcm += r;
8121 //if (ogg.packetGranule && ogg.packetGranule != -1) lastgran = ogg.packetGranule-ctx.preskip;
8122 //conwritef!"\r%s:%02s / %s:%02s"((lastgran/48000)/60, (lastgran/48000)%60, (lastpage.granule/48000)/60, (lastpage.granule/48000)%60);
8123 short* dptr = samples.ptr;
8124 int v;
8125 foreach (immutable spos; 0..r) {
8126 foreach (immutable chn; 0..channels) {
8127 mixin(Float2IntScaled!("*fptr[chn]++", "v"));
8128 *dptr++ = cast(short)v;
8131 return samples.ptr[0..r*channels];
8137 public alias OpusFile = OpusFileCtx*;
8140 public OpusFile opusOpen (VFile fl) {
8141 OpusFile of = av_mallocz!OpusFileCtx(1);
8142 if (of is null) throw new Exception("out of memory");
8143 *of = OpusFileCtx.init; // just in case
8144 scope(failure) { av_freep(&of.commbuf); av_freep(&of.ctx.extradata); av_free(of); }
8146 fl.seek(0);
8147 of.ogg.setup(fl);
8148 scope(failure) of.ogg.close();
8150 if (!of.ogg.findLastPage(of.lastpage)) throw new Exception("can't find last page");
8152 for (;;) {
8153 auto r = opus_header(&of.ctx, of.ogg);
8154 if (r < 0) throw new Exception("can't find opus header");
8155 // current packet is tags?
8156 if (of.ogg.packetLength >= 12 && of.commbuf is null && cast(const(char)[])(of.ogg.packetData[0..8]) == "OpusTags") {
8157 of.commbuf = av_mallocz!ubyte(of.ogg.packetLength-8);
8158 if (of.commbuf !is null) {
8159 import core.stdc.string : memcpy;
8160 memcpy(of.commbuf, of.ogg.packetData.ptr+8, of.ogg.packetLength-8);
8161 of.cblen = of.ogg.packetLength-8;
8164 if (!of.ogg.loadPacket()) throw new Exception("invalid opus file");
8165 if (r == 1) break;
8168 if (of.ogg.pggranule < of.ctx.preskip) throw new Exception("invalid starting granule");
8169 if (of.lastpage.granule < of.ctx.preskip) throw new Exception("invalid ending granule");
8170 of.lastpage.granule -= of.ctx.preskip;
8172 if (opus_decode_init(&of.ctx, &of.c, of.getGain) < 0) throw new Exception("can't init opus decoder");
8173 scope(failure) opus_decode_close(&of.c);
8175 if (of.c.nb_streams != 1) throw new Exception("only mono and stereo opus streams are supported");
8176 // just in case, check the impossible
8177 if (of.c.streams[0].output_channels < 1 || of.c.streams[0].output_channels > 2) throw new Exception("only mono and stereo opus streams are supported");
8179 return of;
8183 public void opusClose (ref OpusFile of) {
8184 if (of !is null) {
8185 of.close();
8186 av_freep(&of);