optimizations

This commit is contained in:
chudov
2009-12-24 16:09:20 +00:00
parent 1bd39f81b5
commit c9c6d7b545
4 changed files with 713 additions and 245 deletions

View File

@@ -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));
} }

View File

@@ -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

View File

@@ -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