mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
optimizations
This commit is contained in:
@@ -96,7 +96,21 @@ namespace CUETools.Codecs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BitReader()
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
pos = 0;
|
||||||
|
len = 0;
|
||||||
|
_bitaccumulator = 0;
|
||||||
|
cache = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public BitReader(byte* _buffer, int _pos, int _len)
|
public BitReader(byte* _buffer, int _pos, int _len)
|
||||||
|
{
|
||||||
|
Reset(_buffer, _pos, _len);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset(byte* _buffer, int _pos, int _len)
|
||||||
{
|
{
|
||||||
buffer = _buffer;
|
buffer = _buffer;
|
||||||
pos = _pos;
|
pos = _pos;
|
||||||
@@ -126,6 +140,16 @@ namespace CUETools.Codecs
|
|||||||
cache = peek4();
|
cache = peek4();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* skip up to 16 bits */
|
||||||
|
public void skipbits16(int bits)
|
||||||
|
{
|
||||||
|
cache <<= bits;
|
||||||
|
int new_accumulator = (_bitaccumulator + bits);
|
||||||
|
pos += (new_accumulator >> 3);
|
||||||
|
_bitaccumulator = (new_accumulator & 7);
|
||||||
|
cache |= ((((uint)buffer[pos + 2] << 8) + (uint)buffer[pos + 3]) << _bitaccumulator);
|
||||||
|
}
|
||||||
|
|
||||||
/* skip up to 8 bits */
|
/* skip up to 8 bits */
|
||||||
public void skipbits8(int bits)
|
public void skipbits8(int bits)
|
||||||
{
|
{
|
||||||
@@ -288,6 +312,7 @@ namespace CUETools.Codecs
|
|||||||
{
|
{
|
||||||
fixed (byte* unary_table = byte_to_unary_table)
|
fixed (byte* unary_table = byte_to_unary_table)
|
||||||
{
|
{
|
||||||
|
uint mask = (1U << k) - 1;
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
for (int i = n; i > 0; i--)
|
for (int i = n; i > 0; i--)
|
||||||
*(r++) = read_unary_signed();
|
*(r++) = read_unary_signed();
|
||||||
@@ -303,9 +328,26 @@ namespace CUETools.Codecs
|
|||||||
bits = unary_table[cache >> 24];
|
bits = unary_table[cache >> 24];
|
||||||
msbs += bits;
|
msbs += bits;
|
||||||
}
|
}
|
||||||
skipbits8((int)(msbs & 7) + 1);
|
int btsk = k + (int)bits + 1;
|
||||||
uint uval = (msbs << k) | (cache >> (32 - k));
|
uint uval = (msbs << k) | ((cache >> (32 - btsk)) & mask);
|
||||||
skipbits8(k);
|
skipbits16(btsk);
|
||||||
|
*(r++) = (int)(uval >> 1 ^ -(int)(uval & 1));
|
||||||
|
}
|
||||||
|
else if (k <= 16)
|
||||||
|
for (int i = n; i > 0; i--)
|
||||||
|
{
|
||||||
|
//*(r++) = read_rice_signed((int)k);
|
||||||
|
uint bits = unary_table[cache >> 24];
|
||||||
|
uint msbs = bits;
|
||||||
|
while (bits == 8)
|
||||||
|
{
|
||||||
|
skipbits8(8);
|
||||||
|
bits = unary_table[cache >> 24];
|
||||||
|
msbs += bits;
|
||||||
|
}
|
||||||
|
int btsk = k + (int)bits + 1;
|
||||||
|
uint uval = (msbs << k) | ((cache >> (32 - btsk)) & mask);
|
||||||
|
skipbits(btsk);
|
||||||
*(r++) = (int)(uval >> 1 ^ -(int)(uval & 1));
|
*(r++) = (int)(uval >> 1 ^ -(int)(uval & 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -321,7 +363,7 @@ namespace CUETools.Codecs
|
|||||||
msbs += bits;
|
msbs += bits;
|
||||||
}
|
}
|
||||||
skipbits8((int)(msbs & 7) + 1);
|
skipbits8((int)(msbs & 7) + 1);
|
||||||
uint uval = (msbs << k) | (cache >> (32 - k));
|
uint uval = (msbs << k) | ((cache >> (32 - k)));
|
||||||
skipbits(k);
|
skipbits(k);
|
||||||
*(r++) = (int)(uval >> 1 ^ -(int)(uval & 1));
|
*(r++) = (int)(uval >> 1 ^ -(int)(uval & 1));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,14 @@ namespace CUETools.Codecs
|
|||||||
eof = false;
|
eof = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
buf_ptr = buf_start;
|
||||||
|
bit_left = 32;
|
||||||
|
bit_buf = 0;
|
||||||
|
eof = false;
|
||||||
|
}
|
||||||
|
|
||||||
public void writebytes(int bytes, byte c)
|
public void writebytes(int bytes, byte c)
|
||||||
{
|
{
|
||||||
for (; bytes > 0; bytes--)
|
for (; bytes > 0; bytes--)
|
||||||
@@ -133,6 +141,13 @@ namespace CUETools.Codecs
|
|||||||
/// <param name="val"></param>
|
/// <param name="val"></param>
|
||||||
unsafe void writebits_fast(int bits, uint val, ref byte * buf)
|
unsafe void writebits_fast(int bits, uint val, ref byte * buf)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if ((buf_ptr + 3) >= buf_end)
|
||||||
|
{
|
||||||
|
eof = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (bits < bit_left)
|
if (bits < bit_left)
|
||||||
{
|
{
|
||||||
bit_buf = (bit_buf << bits) | val;
|
bit_buf = (bit_buf << bits) | val;
|
||||||
@@ -209,21 +224,29 @@ namespace CUETools.Codecs
|
|||||||
writebits(k + q, (v & ((1 << k) - 1)) | (1 << k));
|
writebits(k + q, (v & ((1 << k) - 1)) | (1 << k));
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void write_rice_block_signed(int k, int* residual, int count)
|
public unsafe void write_rice_block_signed(byte * fixedbuf, int k, int* residual, int count)
|
||||||
{
|
{
|
||||||
fixed (byte* fixbuf = &buffer[buf_ptr])
|
byte* buf = &fixedbuf[buf_ptr];
|
||||||
|
//fixed (byte* fixbuf = &buffer[buf_ptr])
|
||||||
{
|
{
|
||||||
byte* buf = fixbuf;
|
//byte* buf = fixbuf;
|
||||||
for (int i = count; i > 0; i--)
|
for (int i = count; i > 0; i--)
|
||||||
{
|
{
|
||||||
int v = -2 * *(residual++) - 1;
|
int v = *(residual++);
|
||||||
v ^= (v >> 31);
|
v = (v << 1) ^ (v >> 31);
|
||||||
|
|
||||||
// write quotient in unary
|
// write quotient in unary
|
||||||
int q = (v >> k) + 1;
|
int q = (v >> k) + 1;
|
||||||
int bits = k + q;
|
int bits = k + q;
|
||||||
while (bits > 31)
|
while (bits > 31)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if (buf + 3 >= fixedbuf + buf_end)
|
||||||
|
{
|
||||||
|
eof = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int b = Math.Min(bits - 31, 31);
|
int b = Math.Min(bits - 31, 31);
|
||||||
if (b < bit_left)
|
if (b < bit_left)
|
||||||
{
|
{
|
||||||
@@ -243,6 +266,14 @@ namespace CUETools.Codecs
|
|||||||
bits -= b;
|
bits -= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (buf + 3 >= fixedbuf + buf_end)
|
||||||
|
{
|
||||||
|
eof = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// write remainder in binary using 'k' bits
|
// write remainder in binary using 'k' bits
|
||||||
//writebits_fast(k + q, (uint)((v & ((1 << k) - 1)) | (1 << k)), ref buf);
|
//writebits_fast(k + q, (uint)((v & ((1 << k) - 1)) | (1 << k)), ref buf);
|
||||||
uint val = (uint)((v & ((1 << k) - 1)) | (1 << k));
|
uint val = (uint)((v & ((1 << k) - 1)) | (1 << k));
|
||||||
@@ -262,7 +293,7 @@ namespace CUETools.Codecs
|
|||||||
*(buf++) = (byte)(bb);
|
*(buf++) = (byte)(bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf_ptr += (int)(buf - fixbuf);
|
buf_ptr = (int)(buf - fixedbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,6 +317,14 @@ namespace CUETools.Codecs
|
|||||||
bit_buf = 0;
|
bit_buf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] Buffer
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int Length
|
public int Length
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@@ -223,12 +223,24 @@ namespace CUETools.Codecs
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe public static void MemCpy(uint* res, uint* smp, int n)
|
||||||
|
{
|
||||||
|
for (int i = n; i > 0; i--)
|
||||||
|
*(res++) = *(smp++);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe public static void MemCpy(int* res, int* smp, int n)
|
unsafe public static void MemCpy(int* res, int* smp, int n)
|
||||||
{
|
{
|
||||||
for (int i = n; i > 0; i--)
|
for (int i = n; i > 0; i--)
|
||||||
*(res++) = *(smp++);
|
*(res++) = *(smp++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe public static void MemCpy(short* res, short* smp, int n)
|
||||||
|
{
|
||||||
|
for (int i = n; i > 0; i--)
|
||||||
|
*(res++) = *(smp++);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe public static void MemCpy(byte* res, byte* smp, int n)
|
unsafe public static void MemCpy(byte* res, byte* smp, int n)
|
||||||
{
|
{
|
||||||
for (int i = n; i > 0; i--)
|
for (int i = n; i > 0; i--)
|
||||||
@@ -383,8 +395,8 @@ namespace CUETools.Codecs
|
|||||||
{
|
{
|
||||||
Stream _IO;
|
Stream _IO;
|
||||||
BinaryReader _br;
|
BinaryReader _br;
|
||||||
ulong _dataOffset, _dataLen;
|
ulong _dataOffset, _samplePos, _sampleLen;
|
||||||
ulong _samplePos, _sampleLen;
|
long _dataLen;
|
||||||
int _bitsPerSample, _channelCount, _sampleRate, _blockAlign;
|
int _bitsPerSample, _channelCount, _sampleRate, _blockAlign;
|
||||||
bool _largeFile;
|
bool _largeFile;
|
||||||
string _path;
|
string _path;
|
||||||
@@ -398,7 +410,23 @@ namespace CUETools.Codecs
|
|||||||
|
|
||||||
ParseHeaders();
|
ParseHeaders();
|
||||||
|
|
||||||
_sampleLen = _dataLen / (uint)_blockAlign;
|
if (_dataLen < 0)
|
||||||
|
//_sampleLen = 0;
|
||||||
|
throw new Exception("WAVE stream length unknown");
|
||||||
|
else
|
||||||
|
_sampleLen = (ulong)(_dataLen / _blockAlign);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WAVReader(Stream IO)
|
||||||
|
{
|
||||||
|
_path = "";
|
||||||
|
_IO = IO;
|
||||||
|
_br = new BinaryReader(_IO);
|
||||||
|
ParseHeaders();
|
||||||
|
if (_dataLen < 0)
|
||||||
|
_sampleLen = 0;
|
||||||
|
else
|
||||||
|
_sampleLen = (ulong)(_dataLen / _blockAlign);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
@@ -473,14 +501,15 @@ namespace CUETools.Codecs
|
|||||||
_dataOffset = (ulong)pos;
|
_dataOffset = (ulong)pos;
|
||||||
if (!_IO.CanSeek || _IO.Length <= maxFileSize)
|
if (!_IO.CanSeek || _IO.Length <= maxFileSize)
|
||||||
{
|
{
|
||||||
if (ckSize == 0x7fffffff)
|
if (ckSize >= 0x7fffffff)
|
||||||
throw new Exception("WAVE stream length unknown");
|
_dataLen = -1;
|
||||||
_dataLen = ckSize;
|
else
|
||||||
|
_dataLen = (long)ckSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_largeFile = true;
|
_largeFile = true;
|
||||||
_dataLen = ((ulong)_IO.Length) - _dataOffset;
|
_dataLen = _IO.Length - pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,14 +546,10 @@ namespace CUETools.Codecs
|
|||||||
{
|
{
|
||||||
ulong seekPos;
|
ulong seekPos;
|
||||||
|
|
||||||
if (value > _sampleLen)
|
if (_sampleLen != 0 && value > _sampleLen)
|
||||||
{
|
|
||||||
_samplePos = _sampleLen;
|
_samplePos = _sampleLen;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
_samplePos = value;
|
_samplePos = value;
|
||||||
}
|
|
||||||
|
|
||||||
seekPos = _dataOffset + (_samplePos * (uint)_blockAlign);
|
seekPos = _dataOffset + (_samplePos * (uint)_blockAlign);
|
||||||
_IO.Seek((long)seekPos, SeekOrigin.Begin);
|
_IO.Seek((long)seekPos, SeekOrigin.Begin);
|
||||||
@@ -581,7 +606,7 @@ namespace CUETools.Codecs
|
|||||||
|
|
||||||
public uint Read(int[,] buff, uint sampleCount)
|
public uint Read(int[,] buff, uint sampleCount)
|
||||||
{
|
{
|
||||||
if (sampleCount > Remaining)
|
if (_sampleLen > 0 && sampleCount > Remaining)
|
||||||
sampleCount = (uint)Remaining;
|
sampleCount = (uint)Remaining;
|
||||||
|
|
||||||
if (sampleCount == 0)
|
if (sampleCount == 0)
|
||||||
@@ -594,7 +619,13 @@ namespace CUETools.Codecs
|
|||||||
{
|
{
|
||||||
int len = _IO.Read(_sampleBuffer, pos, (int)byteCount - pos);
|
int len = _IO.Read(_sampleBuffer, pos, (int)byteCount - pos);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
|
{
|
||||||
|
if ((pos % BlockAlign) != 0 || _sampleLen > 0)
|
||||||
throw new Exception("Incomplete file read.");
|
throw new Exception("Incomplete file read.");
|
||||||
|
sampleCount = (uint)(pos / BlockAlign);
|
||||||
|
_sampleLen = _samplePos + sampleCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
pos += len;
|
pos += len;
|
||||||
} while (pos < byteCount);
|
} while (pos < byteCount);
|
||||||
AudioSamples.BytesToFLACSamples(_sampleBuffer, 0, buff, 0,
|
AudioSamples.BytesToFLACSamples(_sampleBuffer, 0, buff, 0,
|
||||||
@@ -1516,7 +1547,7 @@ namespace CUETools.Codecs
|
|||||||
|
|
||||||
// public bool ReadSource(IAudioSource input)
|
// public bool ReadSource(IAudioSource input)
|
||||||
|
|
||||||
public void Write(int[,] samples, int offset, int count)
|
public unsafe void Write(int[,] samples, int offset, int count)
|
||||||
{
|
{
|
||||||
int pos, chunk;
|
int pos, chunk;
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
@@ -1535,7 +1566,9 @@ namespace CUETools.Codecs
|
|||||||
chunk = Math.Min(FreeSpace, _size - pos);
|
chunk = Math.Min(FreeSpace, _size - pos);
|
||||||
chunk = Math.Min(chunk, count);
|
chunk = Math.Min(chunk, count);
|
||||||
}
|
}
|
||||||
Array.Copy(samples, offset * Channels, _buffer, pos * Channels, chunk * Channels);
|
fixed (int* src = &samples[offset, 0], dst = &_buffer[pos, 0])
|
||||||
|
AudioSamples.MemCpy(dst, src, chunk * Channels);
|
||||||
|
//Array.Copy(samples, offset * Channels, _buffer, pos * Channels, chunk * Channels);
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
_end += chunk;
|
_end += chunk;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user