1 /****************************************************************************
3 * Copyright (C) 2014, Andrew Ward <afward@gmail.com> *
5 * See COPYING for license terms (Ms-PL). *
7 ***************************************************************************/
15 const float M_PI = 3.1415926539f; //(float)Math.PI;
16 const float M_PI2 = M_PI / 2;
18 internal static VorbisMode Init(VorbisStreamDecoder vorbis, DataPacket packet)
20 var mode = new VorbisMode(vorbis);
21 mode.BlockFlag = packet.ReadBit();
22 mode.WindowType = (int)packet.ReadBits(16);
23 mode.TransformType = (int)packet.ReadBits(16);
24 var mapping = (int)packet.ReadBits(8);
26 if (mode.WindowType != 0 || mode.TransformType != 0 || mapping >= vorbis.Maps.Length) throw new InvalidDataException();
28 mode.Mapping = vorbis.Maps[mapping];
29 mode.BlockSize = mode.BlockFlag ? vorbis.Block1Size : vorbis.Block0Size;
31 // now pre-calc the window(s)...
35 mode._windows = new float[4][];
36 mode._windows[0] = new float[vorbis.Block1Size];
37 mode._windows[1] = new float[vorbis.Block1Size];
38 mode._windows[2] = new float[vorbis.Block1Size];
39 mode._windows[3] = new float[vorbis.Block1Size];
44 mode._windows = new float[1][];
45 mode._windows[0] = new float[vorbis.Block0Size];
52 VorbisStreamDecoder _vorbis;
56 private VorbisMode(VorbisStreamDecoder vorbis)
63 // 0: prev = s, next = s || BlockFlag = false
64 // 1: prev = l, next = s
65 // 2: prev = s, next = l
66 // 3: prev = l, next = l
68 for (int idx = 0; idx < _windows.Length; idx++)
70 var array = _windows[idx];
72 var left = ((idx & 1) == 0 ? _vorbis.Block0Size : _vorbis.Block1Size) / 2;
74 var right = ((idx & 2) == 0 ? _vorbis.Block0Size : _vorbis.Block1Size) / 2;
76 var leftbegin = wnd / 4 - left / 2;
77 var rightbegin = wnd - wnd / 4 - right / 2;
79 for (int i = 0; i < left; i++)
81 var x = (float)Math.Sin((i + .5) / left * M_PI2);
83 array[leftbegin + i] = (float)Math.Sin(x * M_PI2);
86 for (int i = leftbegin + left; i < rightbegin; i++)
91 for (int i = 0; i < right; i++)
93 var x = (float)Math.Sin((right - i - .5) / right * M_PI2);
95 array[rightbegin + i] = (float)Math.Sin(x * M_PI2);
100 internal bool BlockFlag;
101 internal int WindowType;
102 internal int TransformType;
103 internal VorbisMapping Mapping;
104 internal int BlockSize;
106 internal float[] GetWindow(bool prev, bool next)
112 if (prev) return _windows[3];