mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
ALAC encoder
This commit is contained in:
229
CUETools.Codecs.ALAC/ALAC.cs
Normal file
229
CUETools.Codecs.ALAC/ALAC.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* CUETools.Codecs.ALAC: pure managed ALAC audio encoder
|
||||
* Copyright (c) 2009 Gregory S. Chudov
|
||||
* Based on ffdshow ALAC audio encoder
|
||||
* Copyright (c) 2008 Jaikrishnan Menon, realityman@gmx.net
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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;
|
||||
|
||||
namespace CUETools.Codecs.ALAC
|
||||
{
|
||||
public class Alac
|
||||
{
|
||||
public const int MAX_BLOCKSIZE = 65535;
|
||||
public const int MAX_RICE_PARAM = 14;
|
||||
public const int MAX_PARTITION_ORDER = 8;
|
||||
public const int MAX_PARTITIONS = 1 << MAX_PARTITION_ORDER;
|
||||
|
||||
public const uint UINT32_MAX = 0xffffffff;
|
||||
|
||||
public static StereoMethod LookupStereoMethod(string name)
|
||||
{
|
||||
return (StereoMethod)(Enum.Parse(typeof(StereoMethod), name, true));
|
||||
}
|
||||
|
||||
public static OrderMethod LookupOrderMethod(string name)
|
||||
{
|
||||
return (OrderMethod)(Enum.Parse(typeof(OrderMethod), name, true));
|
||||
}
|
||||
|
||||
public static WindowFunction LookupWindowFunction(string name)
|
||||
{
|
||||
return (WindowFunction)(Enum.Parse(typeof(WindowFunction), name, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsafe class RiceContext
|
||||
{
|
||||
public RiceContext()
|
||||
{
|
||||
rparams = new int[Alac.MAX_PARTITIONS];
|
||||
esc_bps = new int[Alac.MAX_PARTITIONS];
|
||||
}
|
||||
/// <summary>
|
||||
/// partition order
|
||||
/// </summary>
|
||||
public int porder;
|
||||
|
||||
/// <summary>
|
||||
/// Rice parameters
|
||||
/// </summary>
|
||||
public int[] rparams;
|
||||
|
||||
/// <summary>
|
||||
/// bps if using escape code
|
||||
/// </summary>
|
||||
public int[] esc_bps;
|
||||
};
|
||||
|
||||
unsafe class ALACSubframe
|
||||
{
|
||||
public ALACSubframe()
|
||||
{
|
||||
rc = new RiceContext();
|
||||
coefs = new int[lpc.MAX_LPC_ORDER];
|
||||
}
|
||||
public int order;
|
||||
public int* residual;
|
||||
public RiceContext rc;
|
||||
public uint size;
|
||||
|
||||
public int ricemodifier;
|
||||
public int cbits;
|
||||
public int shift;
|
||||
public int[] coefs;
|
||||
public int window;
|
||||
};
|
||||
|
||||
unsafe class ALACSubframeInfo
|
||||
{
|
||||
public ALACSubframeInfo()
|
||||
{
|
||||
best = new ALACSubframe();
|
||||
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)
|
||||
{
|
||||
samples = s;
|
||||
best.residual = r;
|
||||
best.size = AudioSamples.UINT32_MAX;
|
||||
for (int iWindow = 0; iWindow < lpc.MAX_LPC_WINDOWS; iWindow++)
|
||||
lpc_ctx[iWindow].Reset();
|
||||
done_fixed = 0;
|
||||
}
|
||||
|
||||
public ALACSubframe best;
|
||||
public int* samples;
|
||||
public uint done_fixed;
|
||||
public LpcContext[] lpc_ctx;
|
||||
};
|
||||
|
||||
unsafe class ALACFrame
|
||||
{
|
||||
public ALACFrame(int subframes_count)
|
||||
{
|
||||
subframes = new ALACSubframeInfo[subframes_count];
|
||||
for (int ch = 0; ch < subframes_count; ch++)
|
||||
subframes[ch] = new ALACSubframeInfo();
|
||||
current = new ALACSubframe();
|
||||
}
|
||||
|
||||
public void InitSize(int bs)
|
||||
{
|
||||
blocksize = bs;
|
||||
type = FrameType.Verbatim;
|
||||
interlacing_shift = interlacing_leftweight = 0;
|
||||
}
|
||||
|
||||
public void ChooseBestSubframe(int ch)
|
||||
{
|
||||
if (current.size >= subframes[ch].best.size)
|
||||
return;
|
||||
ALACSubframe tmp = subframes[ch].best;
|
||||
subframes[ch].best = current;
|
||||
current = tmp;
|
||||
}
|
||||
|
||||
public void SwapSubframes(int ch1, int ch2)
|
||||
{
|
||||
ALACSubframeInfo tmp = subframes[ch1];
|
||||
subframes[ch1] = subframes[ch2];
|
||||
subframes[ch2] = tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
public void ChooseSubframes()
|
||||
{
|
||||
if (interlacing_leftweight != 0)
|
||||
{
|
||||
SwapSubframes(1, 3);
|
||||
switch (interlacing_shift)
|
||||
{
|
||||
case 0: // leftside
|
||||
break;
|
||||
case 1: // midside
|
||||
SwapSubframes(0, 2);
|
||||
break;
|
||||
case 31: // rightside
|
||||
SwapSubframes(0, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FrameType type;
|
||||
public int blocksize;
|
||||
public int interlacing_shift, interlacing_leftweight;
|
||||
public ALACSubframeInfo[] subframes;
|
||||
public ALACSubframe current;
|
||||
public double* window_buffer;
|
||||
}
|
||||
|
||||
public enum OrderMethod
|
||||
{
|
||||
Max = 0,
|
||||
Estimate = 1,
|
||||
LogFast = 2,
|
||||
LogSearch = 3,
|
||||
EstSearch2 = 4,
|
||||
Search = 5
|
||||
}
|
||||
|
||||
public enum StereoMethod
|
||||
{
|
||||
Independent = 0,
|
||||
Estimate = 1,
|
||||
Estimate2 = 2,
|
||||
Evaluate = 3,
|
||||
Search = 4
|
||||
}
|
||||
|
||||
public enum FrameType
|
||||
{
|
||||
Verbatim = 0,
|
||||
Compressed = 1
|
||||
};
|
||||
|
||||
public enum ChannelMode
|
||||
{
|
||||
NotStereo = 0,
|
||||
LeftRight = 1,
|
||||
LeftSide = 8,
|
||||
RightSide = 9,
|
||||
MidSide = 10
|
||||
}
|
||||
|
||||
public enum WindowFunction
|
||||
{
|
||||
Welch = 1,
|
||||
Tukey = 2,
|
||||
Hann = 4,
|
||||
Flattop = 8,
|
||||
TukFlat = 10
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,24 @@ namespace CUETools.Codecs.ALAC
|
||||
calculate_length();
|
||||
}
|
||||
|
||||
public ALACReader(int channels, int bps, int rice_historymult, int rice_initialhistory, int rice_kmodifier, int blocksize)
|
||||
{
|
||||
_channelCount = channels;
|
||||
_bitsPerSample = bps;
|
||||
_sampleRate = 44100;
|
||||
|
||||
setinfo_max_samples_per_frame = (uint)blocksize;
|
||||
setinfo_rice_historymult = (byte)rice_historymult;
|
||||
setinfo_rice_initialhistory = (byte)rice_initialhistory;
|
||||
setinfo_rice_kmodifier = (byte)rice_kmodifier;
|
||||
|
||||
_predicterror_buffer_a = new int[setinfo_max_samples_per_frame];
|
||||
_predicterror_buffer_b = new int[setinfo_max_samples_per_frame];
|
||||
_outputsamples_buffer_a = new int[setinfo_max_samples_per_frame];
|
||||
_outputsamples_buffer_b = new int[setinfo_max_samples_per_frame];
|
||||
_framesBuffer = new byte[65536];
|
||||
}
|
||||
|
||||
public int[,] Read(int[,] buff)
|
||||
{
|
||||
return AudioSamples.Read(this, buff);
|
||||
@@ -96,7 +114,7 @@ namespace CUETools.Codecs.ALAC
|
||||
return (uint)offset;
|
||||
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
||||
_IO.Read(_framesBuffer, 0, (int) sampleSize);
|
||||
decodeFrame(sampleDuration, sampleSize);
|
||||
decodeFrame(sampleSize);
|
||||
if (sampleDuration != _samplesInBuffer)
|
||||
throw new Exception("sample count mismatch");
|
||||
_samplesInBuffer -= _samplesBufferOffset;
|
||||
@@ -157,6 +175,8 @@ namespace CUETools.Codecs.ALAC
|
||||
_IO.Position = _saved_mdat_pos + fileOffs;
|
||||
return;
|
||||
}
|
||||
if ((int)_iSample >= _sample_byte_size.Length)
|
||||
throw new Exception("seeking past end of stream");
|
||||
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
||||
durOffs += sampleDuration;
|
||||
fileOffs += sampleSize;
|
||||
@@ -225,6 +245,8 @@ namespace CUETools.Codecs.ALAC
|
||||
while (_time_to_sample_count[duration_cur_index] + duration_index_accum <= iSample)
|
||||
{
|
||||
duration_index_accum += _time_to_sample_count[duration_cur_index];
|
||||
if (duration_cur_index == _time_to_sample_count.Length - 1)
|
||||
throw new Exception("seeking past end of stream");
|
||||
duration_cur_index ++;
|
||||
}
|
||||
sampleDuration = _time_to_sample_duration[duration_cur_index];
|
||||
@@ -250,7 +272,7 @@ namespace CUETools.Codecs.ALAC
|
||||
get_sample_info(_iSample, out sampleDuration, out sampleSize);
|
||||
InitTables();
|
||||
_IO.Read(_framesBuffer, 0, (int)sampleSize);
|
||||
decodeFrame(sampleDuration, sampleSize);
|
||||
decodeFrame(sampleSize);
|
||||
if (_samplesInBuffer < sampleDuration)
|
||||
{
|
||||
_time_to_sample_duration = new uint[2] { sample_duration_0, _samplesInBuffer };
|
||||
@@ -395,11 +417,6 @@ namespace CUETools.Codecs.ALAC
|
||||
return result;
|
||||
}
|
||||
|
||||
private static uint SIGN_EXTENDED32(uint val, int bits)
|
||||
{
|
||||
return ((val << (32 - bits)) >> (32 - bits));
|
||||
}
|
||||
|
||||
private void unreadbits(ref int pos, int bits)
|
||||
{
|
||||
int new_accumulator = (_bitaccumulator - bits);
|
||||
@@ -412,7 +429,7 @@ namespace CUETools.Codecs.ALAC
|
||||
|
||||
private static int count_leading_zeroes(uint input)
|
||||
{
|
||||
int zeroes = 1;
|
||||
int zeroes = 0;
|
||||
uint shifted_input = input >> 16;
|
||||
if (shifted_input == 0)
|
||||
zeroes += 16;
|
||||
@@ -423,22 +440,7 @@ namespace CUETools.Codecs.ALAC
|
||||
zeroes += 8;
|
||||
else
|
||||
input = shifted_input;
|
||||
shifted_input = input >> 4;
|
||||
if (shifted_input == 0)
|
||||
zeroes += 4;
|
||||
else
|
||||
input = shifted_input;
|
||||
shifted_input = input >> 2;
|
||||
if (shifted_input == 0)
|
||||
zeroes += 2;
|
||||
else
|
||||
input = shifted_input;
|
||||
shifted_input = input >> 1;
|
||||
if (shifted_input == 0)
|
||||
zeroes ++;
|
||||
else
|
||||
input = shifted_input;
|
||||
return zeroes - (int)input;
|
||||
return zeroes + BitReader.byte_to_unary_table[input];
|
||||
}
|
||||
|
||||
private unsafe void readPredictor(ref int pos, ref predictor_t predictor_info)
|
||||
@@ -462,30 +464,14 @@ namespace CUETools.Codecs.ALAC
|
||||
|
||||
private unsafe int decode_scalar(byte * buff, ref int pos, int k, int limit, int readsamplesize)
|
||||
{
|
||||
int x = 0;
|
||||
uint next = peekbits_9(buff, pos);
|
||||
if (next == 0x1ff) /* RICE THRESHOLD 9 bits */
|
||||
int x = (next >> 8 == 0) ? 0 :
|
||||
1 + BitReader.byte_to_unary_table[(~next) & 0xff];
|
||||
if (x == 9) /* RICE THRESHOLD 9 bits */
|
||||
{
|
||||
skipbits(ref pos, 9);
|
||||
return (int)readbits(buff, ref pos, readsamplesize);
|
||||
}
|
||||
if ((next & 0x1e0) == 0x1e0)
|
||||
{
|
||||
x += 4;
|
||||
next <<= 4;
|
||||
}
|
||||
if ((next & 0x180) == 0x180)
|
||||
{
|
||||
x += 2;
|
||||
next <<= 2;
|
||||
}
|
||||
if ((next & 0x100) == 0x100)
|
||||
{
|
||||
x += 1;
|
||||
next <<= 1;
|
||||
}
|
||||
x += (int) (next & 0x100) >> 8;
|
||||
//x = count_leading_zeroes((~next) & 0x1ff) - 23;
|
||||
skipbits(ref pos, x + 1);
|
||||
if (k >= limit)
|
||||
k = limit;
|
||||
@@ -637,7 +623,7 @@ namespace CUETools.Codecs.ALAC
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void deinterlace(int[,] samplesBuffer, uint offset, uint sampleCount)
|
||||
internal unsafe void deinterlace(int[,] samplesBuffer, uint offset, uint sampleCount)
|
||||
{
|
||||
if (sampleCount <= 0 || sampleCount > _samplesInBuffer)
|
||||
return;
|
||||
@@ -670,17 +656,18 @@ namespace CUETools.Codecs.ALAC
|
||||
}
|
||||
|
||||
/* otherwise basic interlacing took place */
|
||||
for (i = 0; i < sampleCount; i++)
|
||||
{
|
||||
int a = buf_a[i];
|
||||
int b = buf_b[i];
|
||||
buf_s[i * 2] = a;
|
||||
buf_s[i * 2 + 1] = b;
|
||||
}
|
||||
AudioSamples.Interlace(buf_s, buf_a, buf_b, (int)sampleCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void decodeFrame(ulong sampleDuration, uint sampleSize)
|
||||
internal int DecodeFrame(byte[] buffer, int pos, int len)
|
||||
{
|
||||
Array.Copy(buffer, pos, _framesBuffer, 0, len);
|
||||
decodeFrame((uint)len);
|
||||
return len; // pos
|
||||
}
|
||||
|
||||
private void decodeFrame(uint sampleSize)
|
||||
{
|
||||
_bitaccumulator = 0;
|
||||
int pos = 0;
|
||||
@@ -723,8 +710,6 @@ namespace CUETools.Codecs.ALAC
|
||||
else
|
||||
{
|
||||
/* not compressed, easy case */
|
||||
if (_bitsPerSample != 16)
|
||||
throw new Exception("Not 16 bit");
|
||||
for (int i = 0; i < outputSamples; i++)
|
||||
{
|
||||
_outputsamples_buffer_a[i] = extend_sign32((int)readbits(_framesBuffer, ref pos, _bitsPerSample), _bitsPerSample);
|
||||
@@ -735,8 +720,8 @@ namespace CUETools.Codecs.ALAC
|
||||
_interlacing_leftweight = 0;
|
||||
}
|
||||
|
||||
if (_bitsPerSample != 16)
|
||||
throw new Exception("Not 16 bit");
|
||||
if (readbits(_framesBuffer, ref pos, 3) != 7)
|
||||
throw new Exception("Invalid frame.");
|
||||
|
||||
_samplesInBuffer = outputSamples;
|
||||
}
|
||||
|
||||
1725
CUETools.Codecs.ALAC/ALACWriter.cs
Normal file
1725
CUETools.Codecs.ALAC/ALACWriter.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -84,6 +84,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ALACDotNet.cs" />
|
||||
<Compile Include="ALACWriter.cs" />
|
||||
<Compile Include="ALAC.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -35,12 +35,9 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BitReader.cs" />
|
||||
<Compile Include="BitWriter.cs" />
|
||||
<Compile Include="Flake.cs" />
|
||||
<Compile Include="FlakeReader.cs" />
|
||||
<Compile Include="FlakeWriter.cs" />
|
||||
<Compile Include="lpc.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using CUETools.Codecs;
|
||||
|
||||
namespace CUETools.Codecs.FLAKE
|
||||
{
|
||||
@@ -32,8 +33,6 @@ namespace CUETools.Codecs.FLAKE
|
||||
public const int MAX_PARTITION_ORDER = 8;
|
||||
public const int MAX_PARTITIONS = 1 << MAX_PARTITION_ORDER;
|
||||
|
||||
public const uint UINT32_MAX = 0xffffffff;
|
||||
|
||||
public const int FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
|
||||
public const int FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
|
||||
public const int FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
|
||||
@@ -46,25 +45,6 @@ namespace CUETools.Codecs.FLAKE
|
||||
public static readonly int[] flac_blocksizes = new int[15] { 0, 192, 576, 1152, 2304, 4608, 0, 0, 256, 512, 1024, 2048, 4096, 8192, 16384 };
|
||||
public static readonly int[] flac_bitdepths = new int[8] { 0, 8, 12, 0, 16, 20, 24, 0 };
|
||||
|
||||
public static int log2i(int v)
|
||||
{
|
||||
return log2i((uint)v);
|
||||
}
|
||||
public static int log2i(uint v)
|
||||
{
|
||||
//int i;
|
||||
int n = 0;
|
||||
if (0 != (v & 0xffff0000)) { v >>= 16; n += 16; }
|
||||
if (0 != (v & 0xff00)) { v >>= 8; n += 8; }
|
||||
if (0 != v) return n + 7 - BitReader.byte_to_unary_table[v];
|
||||
//for (i = 2; i < 256; i <<= 1)
|
||||
//{
|
||||
// if (v >= i) n++;
|
||||
// else break;
|
||||
//}
|
||||
return n;
|
||||
}
|
||||
|
||||
public static PredictionType LookupPredictionType(string name)
|
||||
{
|
||||
return (PredictionType)(Enum.Parse(typeof(PredictionType), name, true));
|
||||
@@ -84,45 +64,6 @@ namespace CUETools.Codecs.FLAKE
|
||||
{
|
||||
return (WindowFunction)(Enum.Parse(typeof(WindowFunction), name, true));
|
||||
}
|
||||
|
||||
unsafe public static bool memcmp(int* res, int* smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
if (*(res++) != *(smp++))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
unsafe public static void memcpy(int* res, int* smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = *(smp++);
|
||||
}
|
||||
unsafe public static void memcpy(byte* res, byte* smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = *(smp++);
|
||||
}
|
||||
unsafe public static void memset(int* res, int smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = smp;
|
||||
}
|
||||
unsafe public static void interlace(int* res, int* src1, int* src2, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
{
|
||||
*(res++) = *(src1++);
|
||||
*(res++) = *(src2++);
|
||||
}
|
||||
}
|
||||
unsafe public static void deinterlace(int* dst1, int* dst2, int* src, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
{
|
||||
*(dst1++) = *(src++);
|
||||
*(dst2++) = *(src++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe class RiceContext
|
||||
@@ -186,7 +127,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
wbits = w;
|
||||
best.residual = r;
|
||||
best.type = SubframeType.Verbatim;
|
||||
best.size = Flake.UINT32_MAX;
|
||||
best.size = AudioSamples.UINT32_MAX;
|
||||
for (int iWindow = 0; iWindow < lpc.MAX_LPC_WINDOWS; iWindow++)
|
||||
lpc_ctx[iWindow].Reset();
|
||||
done_fixed = 0;
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
if (channels == 2)
|
||||
{
|
||||
fixed (int* res = &buff[offset, 0], src = &samplesBuffer[_samplesBufferOffset])
|
||||
Flake.interlace(res, src, src + Flake.MAX_BLOCKSIZE, count);
|
||||
AudioSamples.Interlace(res, src, src + Flake.MAX_BLOCKSIZE, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -280,7 +280,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
else if (_framesBufferLength < _framesBuffer.Length / 2 && _framesBufferOffset >= _framesBuffer.Length / 2)
|
||||
{
|
||||
fixed (byte* buff = _framesBuffer)
|
||||
Flake.memcpy(buff, buff + _framesBufferOffset, _framesBufferLength);
|
||||
AudioSamples.MemCpy(buff, buff + _framesBufferOffset, _framesBufferLength);
|
||||
_framesBufferOffset = 0;
|
||||
}
|
||||
while (_framesBufferLength < _framesBuffer.Length / 2)
|
||||
@@ -495,7 +495,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
{
|
||||
FlacSubframeInfo sub = frame.subframes[ch];
|
||||
|
||||
Flake.memcpy(sub.samples, sub.best.residual, sub.best.order);
|
||||
AudioSamples.MemCpy(sub.samples, sub.best.residual, sub.best.order);
|
||||
int* data = sub.samples + sub.best.order;
|
||||
int* residual = sub.best.residual + sub.best.order;
|
||||
int data_len = frame.blocksize - sub.best.order;
|
||||
@@ -503,7 +503,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
switch (sub.best.order)
|
||||
{
|
||||
case 0:
|
||||
Flake.memcpy(data, residual, data_len);
|
||||
AudioSamples.MemCpy(data, residual, data_len);
|
||||
break;
|
||||
case 1:
|
||||
s1 = data[-1];
|
||||
@@ -559,10 +559,10 @@ namespace CUETools.Codecs.FLAKE
|
||||
switch (frame.subframes[ch].best.type)
|
||||
{
|
||||
case SubframeType.Constant:
|
||||
Flake.memset(frame.subframes[ch].samples, frame.subframes[ch].best.residual[0], frame.blocksize);
|
||||
AudioSamples.MemSet(frame.subframes[ch].samples, frame.subframes[ch].best.residual[0], frame.blocksize);
|
||||
break;
|
||||
case SubframeType.Verbatim:
|
||||
Flake.memcpy(frame.subframes[ch].samples, frame.subframes[ch].best.residual, frame.blocksize);
|
||||
AudioSamples.MemCpy(frame.subframes[ch].samples, frame.subframes[ch].best.residual, frame.blocksize);
|
||||
break;
|
||||
case SubframeType.Fixed:
|
||||
restore_samples_fixed(frame, ch);
|
||||
|
||||
@@ -25,7 +25,7 @@ using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Security.Cryptography;
|
||||
using System.Runtime.InteropServices;
|
||||
//using System.Runtime.InteropServices;
|
||||
using CUETools.Codecs;
|
||||
|
||||
namespace CUETools.Codecs.FLAKE
|
||||
@@ -161,10 +161,10 @@ namespace CUETools.Codecs.FLAKE
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern bool GetThreadTimes(IntPtr hThread, out long lpCreationTime, out long lpExitTime, out long lpKernelTime, out long lpUserTime);
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern IntPtr GetCurrentThread();
|
||||
//[DllImport("kernel32.dll")]
|
||||
//static extern bool GetThreadTimes(IntPtr hThread, out long lpCreationTime, out long lpExitTime, out long lpKernelTime, out long lpUserTime);
|
||||
//[DllImport("kernel32.dll")]
|
||||
//static extern IntPtr GetCurrentThread();
|
||||
|
||||
void DoClose()
|
||||
{
|
||||
@@ -196,9 +196,9 @@ namespace CUETools.Codecs.FLAKE
|
||||
inited = false;
|
||||
}
|
||||
|
||||
long fake, KernelStart, UserStart;
|
||||
GetThreadTimes(GetCurrentThread(), out fake, out fake, out KernelStart, out UserStart);
|
||||
_userProcessorTime = new TimeSpan(UserStart);
|
||||
//long fake, KernelStart, UserStart;
|
||||
//GetThreadTimes(GetCurrentThread(), out fake, out fake, out KernelStart, out UserStart);
|
||||
//_userProcessorTime = new TimeSpan(UserStart);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@@ -481,7 +481,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
fixed (int* fsamples = samplesBuffer, src = &samples[pos, 0])
|
||||
{
|
||||
if (channels == 2)
|
||||
Flake.deinterlace(fsamples + samplesInBuffer, fsamples + Flake.MAX_BLOCKSIZE + samplesInBuffer, src, block);
|
||||
AudioSamples.Deinterlace(fsamples + samplesInBuffer, fsamples + Flake.MAX_BLOCKSIZE + samplesInBuffer, src, block);
|
||||
else
|
||||
for (int ch = 0; ch < channels; ch++)
|
||||
{
|
||||
@@ -557,7 +557,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
|
||||
unsafe void encode_residual_verbatim(int* res, int* smp, uint n)
|
||||
{
|
||||
Flake.memcpy(res, smp, (int) n);
|
||||
AudioSamples.MemCpy(res, smp, (int) n);
|
||||
}
|
||||
|
||||
unsafe void encode_residual_fixed(int* res, int* smp, int n, int order)
|
||||
@@ -567,7 +567,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
switch (order)
|
||||
{
|
||||
case 0:
|
||||
Flake.memcpy(res, smp, n);
|
||||
AudioSamples.MemCpy(res, smp, n);
|
||||
return;
|
||||
case 1:
|
||||
*(res++) = s1 = *(smp++);
|
||||
@@ -678,7 +678,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
calc_sums(pmin, pmax, udata, n, pred_order, sums);
|
||||
|
||||
int opt_porder = pmin;
|
||||
uint opt_bits = Flake.UINT32_MAX;
|
||||
uint opt_bits = AudioSamples.UINT32_MAX;
|
||||
for (int i = pmin; i <= pmax; i++)
|
||||
{
|
||||
uint bits = calc_optimal_rice_params(ref tmp_rc, i, sums + i * Flake.MAX_PARTITIONS, n, pred_order);
|
||||
@@ -697,9 +697,9 @@ namespace CUETools.Codecs.FLAKE
|
||||
|
||||
static int get_max_p_order(int max_porder, int n, int order)
|
||||
{
|
||||
int porder = Math.Min(max_porder, Flake.log2i(n ^ (n - 1)));
|
||||
int porder = Math.Min(max_porder, BitReader.log2i(n ^ (n - 1)));
|
||||
if (order > 0)
|
||||
porder = Math.Min(porder, Flake.log2i(n / order));
|
||||
porder = Math.Min(porder, BitReader.log2i(n / order));
|
||||
return porder;
|
||||
}
|
||||
|
||||
@@ -752,7 +752,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
fixed (int* coefs = frame.current.coefs)
|
||||
{
|
||||
lpc.quantize_lpc_coefs(lpcs + (frame.current.order - 1) * lpc.MAX_LPC_ORDER,
|
||||
frame.current.order, cbits, coefs, out frame.current.shift);
|
||||
frame.current.order, cbits, coefs, out frame.current.shift, 15, 0);
|
||||
|
||||
if (frame.current.shift < 0 || frame.current.shift > 15)
|
||||
throw new Exception("negative shift");
|
||||
@@ -1201,11 +1201,11 @@ namespace CUETools.Codecs.FLAKE
|
||||
unsafe uint measure_frame_size(FlacFrame frame, bool do_midside)
|
||||
{
|
||||
// crude estimation of header/footer size
|
||||
uint total = (uint)(32 + ((Flake.log2i(frame_count) + 4) / 5) * 8 + (eparams.variable_block_size != 0 ? 16 : 0) + 16);
|
||||
uint total = (uint)(32 + ((BitReader.log2i(frame_count) + 4) / 5) * 8 + (eparams.variable_block_size != 0 ? 16 : 0) + 16);
|
||||
|
||||
if (do_midside)
|
||||
{
|
||||
uint bitsBest = Flake.UINT32_MAX;
|
||||
uint bitsBest = AudioSamples.UINT32_MAX;
|
||||
ChannelMode modeBest = ChannelMode.LeftRight;
|
||||
|
||||
if (bitsBest > frame.subframes[2].best.size + frame.subframes[3].best.size)
|
||||
@@ -1244,7 +1244,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
case StereoMethod.Estimate:
|
||||
for (int ch = 0; ch < channels; ch++)
|
||||
{
|
||||
frame.subframes[ch].best.size = Flake.UINT32_MAX;
|
||||
frame.subframes[ch].best.size = AudioSamples.UINT32_MAX;
|
||||
encode_residual_onepass(frame, ch);
|
||||
}
|
||||
break;
|
||||
@@ -1389,7 +1389,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
{
|
||||
fixed (int* s = verifyBuffer, r = samplesBuffer)
|
||||
for (int ch = 0; ch < channels; ch++)
|
||||
Flake.memcpy(s + ch * Flake.MAX_BLOCKSIZE, r + ch * Flake.MAX_BLOCKSIZE, eparams.block_size);
|
||||
AudioSamples.MemCpy(s + ch * Flake.MAX_BLOCKSIZE, r + ch * Flake.MAX_BLOCKSIZE, eparams.block_size);
|
||||
}
|
||||
|
||||
int fs, bs;
|
||||
@@ -1427,7 +1427,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
fixed (int* s = verifyBuffer, r = verify.Samples)
|
||||
{
|
||||
for (int ch = 0; ch < channels; ch++)
|
||||
if (Flake.memcmp(s + ch * Flake.MAX_BLOCKSIZE, r + ch * Flake.MAX_BLOCKSIZE, bs))
|
||||
if (AudioSamples.MemCmp(s + ch * Flake.MAX_BLOCKSIZE, r + ch * Flake.MAX_BLOCKSIZE, bs))
|
||||
throw new Exception("validation failed!");
|
||||
}
|
||||
}
|
||||
@@ -1436,7 +1436,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
{
|
||||
fixed (int* s = samplesBuffer)
|
||||
for (int ch = 0; ch < channels; ch++)
|
||||
Flake.memcpy(s + ch * Flake.MAX_BLOCKSIZE, s + bs + ch * Flake.MAX_BLOCKSIZE, eparams.block_size - bs);
|
||||
AudioSamples.MemCpy(s + ch * Flake.MAX_BLOCKSIZE, s + bs + ch * Flake.MAX_BLOCKSIZE, eparams.block_size - bs);
|
||||
}
|
||||
|
||||
samplesInBuffer -= bs;
|
||||
@@ -1771,11 +1771,6 @@ namespace CUETools.Codecs.FLAKE
|
||||
// if set to less than 0, defaults to 4096
|
||||
public int padding_size;
|
||||
|
||||
// maximum encoded frame size
|
||||
// this is set by flake_encode_init based on input audio format
|
||||
// it can be used by the user to allocate an output buffer
|
||||
public int max_frame_size;
|
||||
|
||||
// minimum LPC order
|
||||
// set by user prior to calling flake_encode_init
|
||||
// if set to less than 0, it is chosen based on compression.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* CUETools.Flake: pure managed FLAC audio encoder
|
||||
* CUETools.Codecs: common audio encoder/decoder routines
|
||||
* Copyright (c) 2009 Gregory S. Chudov
|
||||
* Based on Flake encoder, http://flake-enc.sourceforge.net/
|
||||
* Copyright (c) 2006-2009 Justin Ruggles
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,15 +21,28 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CUETools.Codecs.FLAKE
|
||||
namespace CUETools.Codecs
|
||||
{
|
||||
unsafe class BitReader
|
||||
unsafe public class BitReader
|
||||
{
|
||||
byte* buffer;
|
||||
int pos, len;
|
||||
int _bitaccumulator;
|
||||
uint cache;
|
||||
|
||||
public static int log2i(int v)
|
||||
{
|
||||
return log2i((uint)v);
|
||||
}
|
||||
|
||||
public static int log2i(uint v)
|
||||
{
|
||||
int n = 0;
|
||||
if (0 != (v & 0xffff0000)) { v >>= 16; n += 16; }
|
||||
if (0 != (v & 0xff00)) { v >>= 8; n += 8; }
|
||||
return n + byte_to_log2_table[v];
|
||||
}
|
||||
|
||||
public static readonly byte[] byte_to_unary_table = new byte[]
|
||||
{
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
@@ -52,6 +63,26 @@ namespace CUETools.Codecs.FLAKE
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
public static readonly byte[] byte_to_log2_table = new byte[]
|
||||
{
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
||||
public int Position
|
||||
{
|
||||
get { return pos; }
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* CUETools.Flake: pure managed FLAC audio encoder
|
||||
* CUETools.Codecs: common audio encoder/decoder routines
|
||||
* Copyright (c) 2009 Gregory S. Chudov
|
||||
* Based on Flake encoder, http://flake-enc.sourceforge.net/
|
||||
* Copyright (c) 2006-2009 Justin Ruggles
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,9 +21,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CUETools.Codecs.FLAKE
|
||||
namespace CUETools.Codecs
|
||||
{
|
||||
class BitWriter
|
||||
public class BitWriter
|
||||
{
|
||||
uint bit_buf;
|
||||
int bit_left;
|
||||
@@ -44,6 +42,24 @@ namespace CUETools.Codecs.FLAKE
|
||||
eof = false;
|
||||
}
|
||||
|
||||
public void writebytes(int bytes, byte c)
|
||||
{
|
||||
for (; bytes > 0; bytes--)
|
||||
writebits(8, c);
|
||||
}
|
||||
|
||||
public void write(params char [] chars)
|
||||
{
|
||||
foreach (char c in chars)
|
||||
writebits(8, (byte)c);
|
||||
}
|
||||
|
||||
public void write(string s)
|
||||
{
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
writebits(8, (byte)s[i]);
|
||||
}
|
||||
|
||||
public void writebits_signed(int bits, int val)
|
||||
{
|
||||
writebits(bits, val & ((1 << bits) - 1));
|
||||
@@ -148,7 +164,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
writebits(8, val);
|
||||
return;
|
||||
}
|
||||
int bytes = (Flake.log2i(val) + 4) / 5;
|
||||
int bytes = (BitReader.log2i(val) + 4) / 5;
|
||||
int shift = (bytes - 1) * 6;
|
||||
writebits(8, (256U - (256U >> bytes)) | (val >> shift));
|
||||
while (shift >= 6)
|
||||
@@ -276,6 +292,11 @@ namespace CUETools.Codecs.FLAKE
|
||||
{
|
||||
return buf_ptr - buf_start;
|
||||
}
|
||||
set
|
||||
{
|
||||
flush();
|
||||
buf_ptr = buf_start + value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -82,11 +83,14 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BitReader.cs" />
|
||||
<Compile Include="BitWriter.cs" />
|
||||
<Compile Include="Codecs.cs" />
|
||||
<Compile Include="CRCs\CRC16.cs" />
|
||||
<Compile Include="CRCs\CRC16CCITT.cs" />
|
||||
<Compile Include="CRCs\CRC32.cs" />
|
||||
<Compile Include="CRCs\CRC8.cs" />
|
||||
<Compile Include="LPC.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/**
|
||||
* CUETools.Codecs: common audio encoder/decoder routines
|
||||
* Copyright (c) 2009 Gregory S. Chudov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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.IO;
|
||||
using System.Text;
|
||||
@@ -177,6 +196,52 @@ namespace CUETools.Codecs
|
||||
if (samplesRead != toRead) throw new Exception("samples read != requested");
|
||||
return buff;
|
||||
}
|
||||
|
||||
unsafe public static void Interlace(int* res, int* src1, int* src2, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
{
|
||||
*(res++) = *(src1++);
|
||||
*(res++) = *(src2++);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe public static void Deinterlace(int* dst1, int* dst2, int* src, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
{
|
||||
*(dst1++) = *(src++);
|
||||
*(dst2++) = *(src++);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe public static bool MemCmp(int* res, int* smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
if (*(res++) != *(smp++))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsafe public static void MemCpy(int* res, int* smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = *(smp++);
|
||||
}
|
||||
|
||||
unsafe public static void MemCpy(byte* res, byte* smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = *(smp++);
|
||||
}
|
||||
|
||||
unsafe public static void MemSet(int* res, int smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = smp;
|
||||
}
|
||||
|
||||
public const uint UINT32_MAX = 0xffffffff;
|
||||
}
|
||||
|
||||
public class DummyWriter : IAudioDest
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* CUETools.Flake: pure managed FLAC audio encoder
|
||||
* CUETools.Codecs: common audio encoder/decoder routines
|
||||
* Copyright (c) 2009 Gregory S. Chudov
|
||||
* Based on Flake encoder, http://flake-enc.sourceforge.net/
|
||||
* Copyright (c) 2006-2009 Justin Ruggles
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,9 +21,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CUETools.Codecs.FLAKE
|
||||
namespace CUETools.Codecs
|
||||
{
|
||||
class lpc
|
||||
public class lpc
|
||||
{
|
||||
public const int MAX_LPC_ORDER = 32;
|
||||
public const int MAX_LPC_WINDOWS = 4;
|
||||
@@ -223,7 +221,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
*/
|
||||
public static unsafe void
|
||||
quantize_lpc_coefs(double* lpc_in, int order, uint precision, int* lpc_out,
|
||||
out int shift)
|
||||
out int shift, int max_shift, int zero_shift)
|
||||
{
|
||||
int i;
|
||||
double d, cmax, error;
|
||||
@@ -242,16 +240,16 @@ namespace CUETools.Codecs.FLAKE
|
||||
cmax = d;
|
||||
}
|
||||
// if maximum value quantizes to zero, return all zeros
|
||||
if (cmax * (1 << 15) < 1.0)
|
||||
if (cmax * (1 << max_shift) < 1.0)
|
||||
{
|
||||
shift = 0;
|
||||
shift = zero_shift;
|
||||
for (i = 0; i < order; i++)
|
||||
lpc_out[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate level shift which scales max coeff to available bits
|
||||
sh = 15;
|
||||
sh = max_shift;
|
||||
while ((cmax * (1 << sh) > qmax) && (sh > 0))
|
||||
{
|
||||
sh--;
|
||||
@@ -282,25 +280,6 @@ namespace CUETools.Codecs.FLAKE
|
||||
shift = sh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate LPC coefficients for multiple orders
|
||||
*/
|
||||
public static unsafe uint
|
||||
calc_coefs(/*const*/ int* samples, uint blocksize, uint max_order, OrderMethod omethod, double* lpcs, double* window)
|
||||
{
|
||||
double* autoc = stackalloc double[MAX_LPC_ORDER + 1];
|
||||
|
||||
compute_autocorr(samples, blocksize, 0, max_order, autoc, window);
|
||||
|
||||
uint opt_order = max_order;
|
||||
if (omethod == OrderMethod.Estimate)
|
||||
opt_order = compute_lpc_coefs_est(autoc, max_order, lpcs);
|
||||
else
|
||||
compute_lpc_coefs(autoc, max_order, null, lpcs);
|
||||
|
||||
return opt_order;
|
||||
}
|
||||
|
||||
public static unsafe void
|
||||
encode_residual(int* res, int* smp, int n, int order,
|
||||
int* coefs, int shift)
|
||||
@@ -808,7 +787,7 @@ namespace CUETools.Codecs.FLAKE
|
||||
/// <summary>
|
||||
/// Context for LPC coefficients calculation and order estimation
|
||||
/// </summary>
|
||||
unsafe class LpcContext
|
||||
unsafe public class LpcContext
|
||||
{
|
||||
public LpcContext()
|
||||
{
|
||||
@@ -875,6 +854,14 @@ namespace CUETools.Codecs.FLAKE
|
||||
double[] reflection_coeffs;
|
||||
int autocorr_order;
|
||||
|
||||
public double[] Reflection
|
||||
{
|
||||
get
|
||||
{
|
||||
return reflection_coeffs;
|
||||
}
|
||||
}
|
||||
|
||||
public uint[] done_lpcs;
|
||||
}
|
||||
|
||||
@@ -45,28 +45,7 @@ namespace CUETools.Converter
|
||||
#endif
|
||||
{
|
||||
IAudioSource audioSource = AudioReadWrite.GetAudioSource(sourceFile, null, config);
|
||||
IAudioDest audioDest;
|
||||
FlakeWriter flake = null;
|
||||
if (destFile == "$flaketest$")
|
||||
{
|
||||
flake = new FlakeWriter("", audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate, new NullStream());
|
||||
//((FlakeWriter)audioDest).CompressionLevel = 6;
|
||||
flake.PredictionType = Flake.LookupPredictionType(args[2]);
|
||||
flake.StereoMethod = Flake.LookupStereoMethod(args[3]);
|
||||
flake.OrderMethod = Flake.LookupOrderMethod(args[4]);
|
||||
flake.WindowFunction = Flake.LookupWindowFunction(args[5]);
|
||||
flake.MinPartitionOrder = Int32.Parse(args[6]);
|
||||
flake.MaxPartitionOrder = Int32.Parse(args[7]);
|
||||
flake.MinLPCOrder = Int32.Parse(args[8]);
|
||||
flake.MaxLPCOrder = Int32.Parse(args[9]);
|
||||
flake.MinFixedOrder = Int32.Parse(args[10]);
|
||||
flake.MaxFixedOrder = Int32.Parse(args[11]);
|
||||
flake.MaxPrecisionSearch = Int32.Parse(args[12]);
|
||||
flake.BlockSize = Int32.Parse(args[13]);
|
||||
audioDest = new BufferedWriter(flake, 512 * 1024);
|
||||
}
|
||||
else
|
||||
audioDest = AudioReadWrite.GetAudioDest(AudioEncoderType.Lossless, destFile, (long)audioSource.Length, audioSource.BitsPerSample, audioSource.SampleRate, 8192, config);
|
||||
IAudioDest audioDest = AudioReadWrite.GetAudioDest(AudioEncoderType.Lossless, destFile, (long)audioSource.Length, audioSource.BitsPerSample, audioSource.SampleRate, 8192, config);
|
||||
int[,] buff = new int[0x4000, audioSource.ChannelCount];
|
||||
|
||||
Console.WriteLine("Filename : {0}", sourceFile);
|
||||
@@ -99,39 +78,14 @@ namespace CUETools.Converter
|
||||
audioSource.Close();
|
||||
audioDest.Close();
|
||||
|
||||
if (destFile != "$flaketest$")
|
||||
TagLib.UserDefined.AdditionalFileTypes.Config = config;
|
||||
TagLib.File sourceInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(sourceFile));
|
||||
TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile));
|
||||
if (Tagging.UpdateTags(destInfo, Tagging.Analyze(sourceInfo), config))
|
||||
{
|
||||
TagLib.UserDefined.AdditionalFileTypes.Config = config;
|
||||
TagLib.File sourceInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(sourceFile));
|
||||
TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile));
|
||||
if (Tagging.UpdateTags(destInfo, Tagging.Analyze(sourceInfo), config))
|
||||
{
|
||||
sourceInfo.Tag.CopyTo(destInfo.Tag, true);
|
||||
destInfo.Tag.Pictures = sourceInfo.Tag.Pictures;
|
||||
destInfo.Save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.SetOut(stdout);
|
||||
//Console.Out.WriteLine("{0}\t{6}\t{1}\t{2}\t{3}\t{4}\t{5}",
|
||||
// "Size ", "MaxPart", "MaxPred", "Pred ", "Stereo", "Order", "Time ");
|
||||
Console.Out.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}..{7}\t{8}..{9}\t{10}..{11}\t{12}\t{13}",
|
||||
flake.TotalSize,
|
||||
flake.UserProcessorTime.TotalSeconds,
|
||||
flake.PredictionType.ToString().PadRight(15),
|
||||
flake.StereoMethod.ToString().PadRight(15),
|
||||
flake.OrderMethod.ToString().PadRight(15),
|
||||
flake.WindowFunction,
|
||||
flake.MinPartitionOrder,
|
||||
flake.MaxPartitionOrder,
|
||||
flake.MinLPCOrder,
|
||||
flake.MaxLPCOrder,
|
||||
flake.MinFixedOrder,
|
||||
flake.MaxFixedOrder,
|
||||
flake.MaxPrecisionSearch,
|
||||
flake.BlockSize
|
||||
);
|
||||
sourceInfo.Tag.CopyTo(destInfo.Tag, true);
|
||||
destInfo.Tag.Pictures = sourceInfo.Tag.Pictures;
|
||||
destInfo.Save();
|
||||
}
|
||||
}
|
||||
#if !DEBUG
|
||||
|
||||
@@ -94,6 +94,18 @@ namespace CUETools.Processor
|
||||
case "WAVWriter":
|
||||
dest = new WAVWriter(path, bitsPerSample, channelCount, sampleRate, null);
|
||||
break;
|
||||
case "FlakeWriter":
|
||||
dest = new FlakeWriter(path, bitsPerSample, channelCount, sampleRate, null);
|
||||
((FlakeWriter)dest).PaddingLength = padding;
|
||||
((FlakeWriter)dest).CompressionLevel = encoder.DefaultModeIndex;
|
||||
dest = new BufferedWriter(dest, 128 * 1024);
|
||||
break;
|
||||
case "ALACWriter":
|
||||
dest = new ALACWriter(path, bitsPerSample, channelCount, sampleRate, null);
|
||||
((ALACWriter)dest).PaddingLength = padding;
|
||||
((ALACWriter)dest).CompressionLevel = encoder.DefaultModeIndex;
|
||||
//dest = new BufferedWriter(dest, 128 * 1024);
|
||||
break;
|
||||
#if !MONO
|
||||
case "FLACWriter":
|
||||
dest = new FLACWriter(path, bitsPerSample, channelCount, sampleRate);
|
||||
@@ -102,12 +114,6 @@ namespace CUETools.Processor
|
||||
((FLACWriter)dest).Verify = config.flacVerify;
|
||||
((FLACWriter)dest).DisableAsm = config.disableAsm;
|
||||
break;
|
||||
case "FlakeWriter":
|
||||
dest = new FlakeWriter(path, bitsPerSample, channelCount, sampleRate, null);
|
||||
((FlakeWriter)dest).PaddingLength = padding;
|
||||
((FlakeWriter)dest).CompressionLevel = encoder.DefaultModeIndex;
|
||||
dest = new BufferedWriter(dest, 128 * 1024);
|
||||
break;
|
||||
case "WavPackWriter":
|
||||
dest = new WavPackWriter(path, bitsPerSample, channelCount, sampleRate);
|
||||
((WavPackWriter)dest).CompressionMode = encoder.DefaultModeIndex;
|
||||
|
||||
@@ -911,11 +911,12 @@ namespace CUETools.Processor
|
||||
encoders = new CUEToolsUDCList();
|
||||
#if !MONO
|
||||
encoders.Add(new CUEToolsUDC("libFLAC", "flac", true, "0 1 2 3 4 5 6 7 8", "5", "FLACWriter"));
|
||||
encoders.Add(new CUEToolsUDC("libFlake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11", "7", "FlakeWriter"));
|
||||
encoders.Add(new CUEToolsUDC("libwavpack", "wv", true, "fast normal high high+", "normal", "WavPackWriter"));
|
||||
encoders.Add(new CUEToolsUDC("MAC_SDK", "ape", true, "fast normal high extra insane", "high", "APEWriter"));
|
||||
encoders.Add(new CUEToolsUDC("ttalib", "tta", true, "", "", "TTAWriter"));
|
||||
#endif
|
||||
encoders.Add(new CUEToolsUDC("libFlake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11", "7", "FlakeWriter"));
|
||||
encoders.Add(new CUEToolsUDC("libALAC", "m4a", true, "0 1 2 3 4 5 6 7 8", "3", "ALACWriter"));
|
||||
encoders.Add(new CUEToolsUDC("builtin wav", "wav", true, "", "", "WAVWriter"));
|
||||
encoders.Add(new CUEToolsUDC("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11", "10", "flake.exe", "-%M - -o %O -p %P"));
|
||||
encoders.Add(new CUEToolsUDC("takc", "tak", true, "0 1 2 2e 2m 3 3e 3m 4 4e 4m", "2", "takc.exe", "-e -p%M -overwrite - %O"));
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<ApplicationIcon>cue2.ico</ApplicationIcon>
|
||||
<ManifestCertificateThumbprint>611F49E043614FEDCFF1B128868CC8DC0B6656C5</ManifestCertificateThumbprint>
|
||||
<ManifestKeyFile>CUETools_TemporaryKey.pfx</ManifestKeyFile>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
<SignManifests>true</SignManifests>
|
||||
<IsWebBootstrapper>true</IsWebBootstrapper>
|
||||
<PublishUrl>ftp://cuetools.net/cuetools.net/install/cuetools/</PublishUrl>
|
||||
@@ -33,6 +33,7 @@
|
||||
<WebPage>publish.htm</WebPage>
|
||||
<ApplicationVersion>2.0.3.%2a</ApplicationVersion>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -279,6 +280,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CUETools_TemporaryKey.pfx" />
|
||||
<BaseApplicationManifest Include="Properties\app.manifest" />
|
||||
<None Include="Properties\DataSources\CUETools.Processor.CUEConfig.datasource" />
|
||||
<None Include="Resources\accuraterip.jpg" />
|
||||
<Content Include="cue2.ico" />
|
||||
|
||||
@@ -93,6 +93,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flake", "..\flake\flake.vcp
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Flake", "..\CUETools.Flake\CUETools.Flake.csproj", "{2379BAAF-A406-4477-BF53-2D6A326C24C8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.ALACEnc", "..\CUETools.ALACEnc\CUETools.ALACEnc.csproj", "{8E6E1763-39AE-491D-A10F-44C8844ABA5B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -291,8 +293,8 @@ Global
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|Win32.ActiveCfg = Debug|x86
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|x64.Build.0 = Debug|x64
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Debug|x86.Build.0 = Debug|x86
|
||||
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -309,8 +311,8 @@ Global
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|Win32.ActiveCfg = Debug|x86
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|x64.Build.0 = Debug|x64
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Debug|x86.Build.0 = Debug|x86
|
||||
{F2EC7193-D5E5-4252-9803-5CEB407E910F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -650,6 +652,7 @@ Global
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{082D6B9E-326E-4D15-9798-EDAE9EDE70A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -666,7 +669,7 @@ Global
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{F53335A2-C013-4354-98CC-83E612EAEB60}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
@@ -682,6 +685,7 @@ Global
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Debug|x86.Build.0 = Debug|x86
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -693,6 +697,22 @@ Global
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Release|x86.ActiveCfg = Release|x86
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8}.Release|x86.Build.0 = Release|x86
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -714,6 +734,7 @@ Global
|
||||
{A5A8D8FA-9E32-4010-8AAF-AE580C5AF728} = {4B59E09C-A51F-4B80-91BE-987904DCEF7D}
|
||||
{115CC5B0-0385-41CD-8A23-6A7EA4C51926} = {4B59E09C-A51F-4B80-91BE-987904DCEF7D}
|
||||
{2379BAAF-A406-4477-BF53-2D6A326C24C8} = {4B59E09C-A51F-4B80-91BE-987904DCEF7D}
|
||||
{8E6E1763-39AE-491D-A10F-44C8844ABA5B} = {4B59E09C-A51F-4B80-91BE-987904DCEF7D}
|
||||
{B75FA7AD-968E-4990-B342-1B4B17C850DF} = {B36BE134-D85A-437E-AB61-2DA1CCDE06C1}
|
||||
{F2DFEB00-BB35-4665-85EA-CB8C7729A6B7} = {B36BE134-D85A-437E-AB61-2DA1CCDE06C1}
|
||||
{A05B6AA6-0EC3-495D-BCC4-ECE1210071A8} = {B36BE134-D85A-437E-AB61-2DA1CCDE06C1}
|
||||
|
||||
Reference in New Issue
Block a user