diff --git a/CUETools.Codecs.FLAKE/CUETools.Codecs.FLAKE.csproj b/CUETools.Codecs.FLAKE/CUETools.Codecs.FLAKE.csproj index 418e012..226dc1f 100644 --- a/CUETools.Codecs.FLAKE/CUETools.Codecs.FLAKE.csproj +++ b/CUETools.Codecs.FLAKE/CUETools.Codecs.FLAKE.csproj @@ -59,15 +59,28 @@ + + + + + + + True True Resources.resx + + + + + + diff --git a/CUETools.Codecs.FLAKE/ChannelMode.cs b/CUETools.Codecs.FLAKE/ChannelMode.cs new file mode 100644 index 0000000..ab144cf --- /dev/null +++ b/CUETools.Codecs.FLAKE/ChannelMode.cs @@ -0,0 +1,11 @@ +namespace CUETools.Codecs.FLAKE +{ + public enum ChannelMode + { + NotStereo = 0, + LeftRight = 1, + LeftSide = 8, + RightSide = 9, + MidSide = 10 + } +} diff --git a/CUETools.Codecs.FLAKE/FlacFrame.cs b/CUETools.Codecs.FLAKE/FlacFrame.cs new file mode 100644 index 0000000..a30b72a --- /dev/null +++ b/CUETools.Codecs.FLAKE/FlacFrame.cs @@ -0,0 +1,95 @@ +namespace CUETools.Codecs.FLAKE +{ + unsafe public class FlacFrame + { + public int blocksize; + public int bs_code0, bs_code1; + public ChannelMode ch_mode; + //public int ch_order0, ch_order1; + public byte crc8; + public FlacSubframeInfo[] subframes; + public int frame_number; + public FlacSubframe current; + public float* window_buffer; + + public BitWriter writer = null; + public int writer_offset = 0; + + public FlacFrame(int subframes_count) + { + subframes = new FlacSubframeInfo[subframes_count]; + for (int ch = 0; ch < subframes_count; ch++) + subframes[ch] = new FlacSubframeInfo(); + current = new FlacSubframe(); + } + + public void InitSize(int bs, bool vbs) + { + blocksize = bs; + int i = 15; + if (!vbs) + { + for (i = 0; i < 15; i++) + { + if (bs == Flake.flac_blocksizes[i]) + { + bs_code0 = i; + bs_code1 = -1; + break; + } + } + } + if (i == 15) + { + if (blocksize <= 256) + { + bs_code0 = 6; + bs_code1 = blocksize - 1; + } + else + { + bs_code0 = 7; + bs_code1 = blocksize - 1; + } + } + } + + public void ChooseBestSubframe(int ch) + { + if (current.size >= subframes[ch].best.size) + return; + FlacSubframe tmp = subframes[ch].best; + subframes[ch].best = current; + current = tmp; + } + + public void SwapSubframes(int ch1, int ch2) + { + FlacSubframeInfo tmp = subframes[ch1]; + subframes[ch1] = subframes[ch2]; + subframes[ch2] = tmp; + } + + /// + /// Swap subframes according to channel mode. + /// It is assumed that we have 4 subframes, + /// 0 is right, 1 is left, 2 is middle, 3 is difference + /// + public void ChooseSubframes() + { + switch (ch_mode) + { + case ChannelMode.MidSide: + SwapSubframes(0, 2); + SwapSubframes(1, 3); + break; + case ChannelMode.RightSide: + SwapSubframes(0, 3); + break; + case ChannelMode.LeftSide: + SwapSubframes(1, 3); + break; + } + } + } +} diff --git a/CUETools.Codecs.FLAKE/FlacSubframe.cs b/CUETools.Codecs.FLAKE/FlacSubframe.cs new file mode 100644 index 0000000..e3ab85e --- /dev/null +++ b/CUETools.Codecs.FLAKE/FlacSubframe.cs @@ -0,0 +1,21 @@ +namespace CUETools.Codecs.FLAKE +{ + unsafe public class FlacSubframe + { + public FlacSubframe() + { + rc = new RiceContext(); + coefs = new int[lpc.MAX_LPC_ORDER]; + } + public SubframeType type; + public int order; + public int* residual; + public RiceContext rc; + public uint size; + + public int cbits; + public int shift; + public int[] coefs; + public int window; + }; +} diff --git a/CUETools.Codecs.FLAKE/FlacSubframeInfo.cs b/CUETools.Codecs.FLAKE/FlacSubframeInfo.cs new file mode 100644 index 0000000..264092a --- /dev/null +++ b/CUETools.Codecs.FLAKE/FlacSubframeInfo.cs @@ -0,0 +1,37 @@ +using System; + +namespace CUETools.Codecs.FLAKE +{ + unsafe public class FlacSubframeInfo + { + public FlacSubframeInfo() + { + best = new FlacSubframe(); + lpc_ctx = new LpcContext[lpc.MAX_LPC_WINDOWS]; + for (int i = 0; i < lpc.MAX_LPC_WINDOWS; i++) + lpc_ctx[i] = new LpcContext(); + } + + public void Init(int* s, int* r, int bps, int w) + { + if (w > bps) + throw new Exception("internal error"); + samples = s; + obits = bps - w; + wbits = w; + best.residual = r; + best.type = SubframeType.Verbatim; + best.size = AudioSamples.UINT32_MAX; + for (int iWindow = 0; iWindow < lpc.MAX_LPC_WINDOWS; iWindow++) + lpc_ctx[iWindow].Reset(); + done_fixed = 0; + } + + public FlacSubframe best; + public int obits; + public int wbits; + public int* samples; + public uint done_fixed; + public LpcContext[] lpc_ctx; + }; +} diff --git a/CUETools.Codecs.FLAKE/Flake.cs b/CUETools.Codecs.FLAKE/Flake.cs index fd69f5f..8b8522f 100644 --- a/CUETools.Codecs.FLAKE/Flake.cs +++ b/CUETools.Codecs.FLAKE/Flake.cs @@ -18,11 +18,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - using System; -using System.Collections.Generic; -using System.Text; -using CUETools.Codecs; namespace CUETools.Codecs.FLAKE { @@ -70,300 +66,4 @@ namespace CUETools.Codecs.FLAKE return (WindowFunction)(Enum.Parse(typeof(WindowFunction), name, true)); } } - - unsafe public class RiceContext - { - public RiceContext() - { - rparams = new int[Flake.MAX_PARTITIONS]; - esc_bps = new int[Flake.MAX_PARTITIONS]; - } - /// - /// partition order - /// - public int porder; - - /// - /// coding method: rice parameters use 4 bits for coding_method 0 and 5 bits for coding_method 1 - /// - public int coding_method; - - /// - /// Rice parameters - /// - public int[] rparams; - - /// - /// bps if using escape code - /// - public int[] esc_bps; - }; - - unsafe public class FlacSubframe - { - public FlacSubframe() - { - rc = new RiceContext(); - coefs = new int[lpc.MAX_LPC_ORDER]; - } - public SubframeType type; - public int order; - public int* residual; - public RiceContext rc; - public uint size; - - public int cbits; - public int shift; - public int[] coefs; - public int window; - }; - - unsafe public class FlacSubframeInfo - { - public FlacSubframeInfo() - { - best = new FlacSubframe(); - lpc_ctx = new LpcContext[lpc.MAX_LPC_WINDOWS]; - for (int i = 0; i < lpc.MAX_LPC_WINDOWS; i++) - lpc_ctx[i] = new LpcContext(); - } - - public void Init(int* s, int* r, int bps, int w) - { - if (w > bps) - throw new Exception("internal error"); - samples = s; - obits = bps - w; - wbits = w; - best.residual = r; - best.type = SubframeType.Verbatim; - best.size = AudioSamples.UINT32_MAX; - for (int iWindow = 0; iWindow < lpc.MAX_LPC_WINDOWS; iWindow++) - lpc_ctx[iWindow].Reset(); - done_fixed = 0; - } - - public FlacSubframe best; - public int obits; - public int wbits; - public int* samples; - public uint done_fixed; - public LpcContext[] lpc_ctx; - }; - - unsafe public class FlacFrame - { - public FlacFrame(int subframes_count) - { - subframes = new FlacSubframeInfo[subframes_count]; - for (int ch = 0; ch < subframes_count; ch++) - subframes[ch] = new FlacSubframeInfo(); - current = new FlacSubframe(); - } - - public void InitSize(int bs, bool vbs) - { - blocksize = bs; - int i = 15; - if (!vbs) - { - for (i = 0; i < 15; i++) - { - if (bs == Flake.flac_blocksizes[i]) - { - bs_code0 = i; - bs_code1 = -1; - break; - } - } - } - if (i == 15) - { - if (blocksize <= 256) - { - bs_code0 = 6; - bs_code1 = blocksize - 1; - } - else - { - bs_code0 = 7; - bs_code1 = blocksize - 1; - } - } - } - - public void ChooseBestSubframe(int ch) - { - if (current.size >= subframes[ch].best.size) - return; - FlacSubframe tmp = subframes[ch].best; - subframes[ch].best = current; - current = tmp; - } - - public void SwapSubframes(int ch1, int ch2) - { - FlacSubframeInfo tmp = subframes[ch1]; - subframes[ch1] = subframes[ch2]; - subframes[ch2] = tmp; - } - - /// - /// Swap subframes according to channel mode. - /// It is assumed that we have 4 subframes, - /// 0 is right, 1 is left, 2 is middle, 3 is difference - /// - public void ChooseSubframes() - { - switch (ch_mode) - { - case ChannelMode.MidSide: - SwapSubframes(0, 2); - SwapSubframes(1, 3); - break; - case ChannelMode.RightSide: - SwapSubframes(0, 3); - break; - case ChannelMode.LeftSide: - SwapSubframes(1, 3); - break; - } - } - - public int blocksize; - public int bs_code0, bs_code1; - public ChannelMode ch_mode; - //public int ch_order0, ch_order1; - public byte crc8; - public FlacSubframeInfo[] subframes; - public int frame_number; - public FlacSubframe current; - public float* window_buffer; - - public BitWriter writer = null; - public int writer_offset = 0; - } - - public enum OrderMethod - { - /// - /// Select orders based on Akaike's criteria - /// - Akaike = 0 - } - - /// - /// Type of linear prediction - /// - public enum PredictionType - { - /// - /// Verbatim - /// - None = 0, - /// - /// Fixed prediction only - /// - Fixed = 1, - /// - /// Levinson-Durbin recursion - /// - Levinson = 2, - /// - /// Exhaustive search - /// - Search = 3 - } - - public enum StereoMethod - { - Independent = 0, - Estimate = 1, - Evaluate = 2, - Search = 3 - } - - public enum WindowMethod - { - Estimate = 0, - Evaluate = 1, - Search = 2 - } - - public enum SubframeType - { - Constant = 0, - Verbatim = 1, - Fixed = 8, - LPC = 32 - }; - - public enum ChannelMode - { - NotStereo = 0, - LeftRight = 1, - LeftSide = 8, - RightSide = 9, - MidSide = 10 - } - - public enum WindowFunction - { - Welch = 1, - Tukey = 2, - Hann = 4, - Flattop = 8, - Bartlett = 16, - TukeyFlattop = 10 - } - - public struct SeekPoint - { - public long number; - public long offset; - public int framesize; - } - - public enum MetadataType - { - /// - /// STREAMINFO block - /// - StreamInfo = 0, - - /// - /// PADDING block - /// - Padding = 1, - - /// - /// APPLICATION block - /// - Application = 2, - - /// - /// SEEKTABLE block - /// - Seektable = 3, - - /// - /// VORBISCOMMENT block (a.k.a. FLAC tags) - /// - VorbisComment = 4, - - /// - /// CUESHEET block - /// - CUESheet = 5, - - /// - /// PICTURE block - /// - Picture = 6, - - /// - /// marker to denote beginning of undefined type range; this number will increase as new metadata types are added - /// - Undefined = 7 - }; } diff --git a/CUETools.Codecs.FLAKE/MetadataType.cs b/CUETools.Codecs.FLAKE/MetadataType.cs new file mode 100644 index 0000000..6122174 --- /dev/null +++ b/CUETools.Codecs.FLAKE/MetadataType.cs @@ -0,0 +1,45 @@ +namespace CUETools.Codecs.FLAKE +{ + public enum MetadataType + { + /// + /// STREAMINFO block + /// + StreamInfo = 0, + + /// + /// PADDING block + /// + Padding = 1, + + /// + /// APPLICATION block + /// + Application = 2, + + /// + /// SEEKTABLE block + /// + Seektable = 3, + + /// + /// VORBISCOMMENT block (a.k.a. FLAC tags) + /// + VorbisComment = 4, + + /// + /// CUESHEET block + /// + CUESheet = 5, + + /// + /// PICTURE block + /// + Picture = 6, + + /// + /// marker to denote beginning of undefined type range; this number will increase as new metadata types are added + /// + Undefined = 7 + } +} diff --git a/CUETools.Codecs.FLAKE/OrderMethod.cs b/CUETools.Codecs.FLAKE/OrderMethod.cs new file mode 100644 index 0000000..e691e53 --- /dev/null +++ b/CUETools.Codecs.FLAKE/OrderMethod.cs @@ -0,0 +1,10 @@ +namespace CUETools.Codecs.FLAKE +{ + public enum OrderMethod + { + /// + /// Select orders based on Akaike's criteria + /// + Akaike = 0 + } +} diff --git a/CUETools.Codecs.FLAKE/PredictionType.cs b/CUETools.Codecs.FLAKE/PredictionType.cs new file mode 100644 index 0000000..ddf0d86 --- /dev/null +++ b/CUETools.Codecs.FLAKE/PredictionType.cs @@ -0,0 +1,25 @@ +namespace CUETools.Codecs.FLAKE +{ + /// + /// Type of linear prediction + /// + public enum PredictionType + { + /// + /// Verbatim + /// + None = 0, + /// + /// Fixed prediction only + /// + Fixed = 1, + /// + /// Levinson-Durbin recursion + /// + Levinson = 2, + /// + /// Exhaustive search + /// + Search = 3 + } +} diff --git a/CUETools.Codecs.FLAKE/RiceContext.cs b/CUETools.Codecs.FLAKE/RiceContext.cs new file mode 100644 index 0000000..965ac9e --- /dev/null +++ b/CUETools.Codecs.FLAKE/RiceContext.cs @@ -0,0 +1,30 @@ +namespace CUETools.Codecs.FLAKE +{ + unsafe public class RiceContext + { + public RiceContext() + { + rparams = new int[Flake.MAX_PARTITIONS]; + esc_bps = new int[Flake.MAX_PARTITIONS]; + } + /// + /// partition order + /// + public int porder; + + /// + /// coding method: rice parameters use 4 bits for coding_method 0 and 5 bits for coding_method 1 + /// + public int coding_method; + + /// + /// Rice parameters + /// + public int[] rparams; + + /// + /// bps if using escape code + /// + public int[] esc_bps; + }; +} diff --git a/CUETools.Codecs.FLAKE/SeekPoint.cs b/CUETools.Codecs.FLAKE/SeekPoint.cs new file mode 100644 index 0000000..c4a8005 --- /dev/null +++ b/CUETools.Codecs.FLAKE/SeekPoint.cs @@ -0,0 +1,9 @@ +namespace CUETools.Codecs.FLAKE +{ + public struct SeekPoint + { + public long number; + public long offset; + public int framesize; + } +} diff --git a/CUETools.Codecs.FLAKE/StereoMethod.cs b/CUETools.Codecs.FLAKE/StereoMethod.cs new file mode 100644 index 0000000..fd511e3 --- /dev/null +++ b/CUETools.Codecs.FLAKE/StereoMethod.cs @@ -0,0 +1,11 @@ + +namespace CUETools.Codecs.FLAKE +{ + public enum StereoMethod + { + Independent = 0, + Estimate = 1, + Evaluate = 2, + Search = 3 + } +} diff --git a/CUETools.Codecs.FLAKE/SubframeType.cs b/CUETools.Codecs.FLAKE/SubframeType.cs new file mode 100644 index 0000000..0c60963 --- /dev/null +++ b/CUETools.Codecs.FLAKE/SubframeType.cs @@ -0,0 +1,10 @@ +namespace CUETools.Codecs.FLAKE +{ + public enum SubframeType + { + Constant = 0, + Verbatim = 1, + Fixed = 8, + LPC = 32 + } +} diff --git a/CUETools.Codecs.FLAKE/WindowFunction.cs b/CUETools.Codecs.FLAKE/WindowFunction.cs new file mode 100644 index 0000000..af5fb31 --- /dev/null +++ b/CUETools.Codecs.FLAKE/WindowFunction.cs @@ -0,0 +1,12 @@ +namespace CUETools.Codecs.FLAKE +{ + public enum WindowFunction + { + Welch = 1, + Tukey = 2, + Hann = 4, + Flattop = 8, + Bartlett = 16, + TukeyFlattop = 10 + } +} diff --git a/CUETools.Codecs.FLAKE/WindowMethod.cs b/CUETools.Codecs.FLAKE/WindowMethod.cs new file mode 100644 index 0000000..f05c8e1 --- /dev/null +++ b/CUETools.Codecs.FLAKE/WindowMethod.cs @@ -0,0 +1,9 @@ +namespace CUETools.Codecs.FLAKE +{ + public enum WindowMethod + { + Estimate = 0, + Evaluate = 1, + Search = 2 + } +}