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