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