Somewhat optimized Flake encoder

This commit is contained in:
Grigory Chudov
2013-03-25 22:33:21 -04:00
parent d080406f82
commit 55af6e181a
3 changed files with 98 additions and 121 deletions

View File

@@ -867,9 +867,11 @@ namespace CUETools.Codecs.FLACCL
unsafe int measure_residual(FlacFrame frame, FlacSubframeInfo sub, int pos, int cnt, int k)
{
int q = 0;
for (int i = pos; i < pos + cnt; i++)
int* r = sub.best.residual + pos;
int* fin = r + cnt;
while (r < fin)
{
int v = sub.best.residual[i];
int v = *(r++);
uint uv = (uint)((v << 1) ^ (v >> 31));
q += (int)(uv >> k);
}
@@ -2097,8 +2099,8 @@ namespace CUETools.Codecs.FLACCL
bitwriter.writebits(24, 18 * seek_table.Length);
for (int i = 0; i < seek_table.Length; i++)
{
bitwriter.writebits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, (ulong)seek_table[i].number);
bitwriter.writebits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, (ulong)seek_table[i].offset);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, (ulong)seek_table[i].number);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, (ulong)seek_table[i].offset);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, seek_table[i].framesize);
}
bitwriter.flush();
@@ -2698,10 +2700,7 @@ namespace CUETools.Codecs.FLACCL
frame.writer = new BitWriter(outputBuffer, 0, outputBuffer.Length);
if (writer._settings.DoVerify)
{
verify = new FlakeReader(new AudioPCMConfig((int)bits_per_sample, channels, 44100));
verify.DoCRC = false;
}
}
public void Dispose()

View File

@@ -593,7 +593,7 @@ namespace CUETools.Codecs.FLAKE
AudioSamples.MemCpy(res, smp, (int) n);
}
unsafe void encode_residual_fixed(int* res, int* smp, int n, int order)
unsafe static void encode_residual_fixed(int* res, int* smp, int n, int order)
{
int i;
int s0, s1, s2;
@@ -1928,8 +1928,8 @@ new int[] { // 30
bitwriter.writebits(24, 18 * seek_table.Length);
for (int i = 0; i < seek_table.Length; i++)
{
bitwriter.writebits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, (ulong)seek_table[i].number);
bitwriter.writebits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, (ulong)seek_table[i].offset);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, (ulong)seek_table[i].number);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, (ulong)seek_table[i].offset);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, seek_table[i].framesize);
}
bitwriter.flush();

View File

@@ -4,10 +4,10 @@ namespace CUETools.Codecs
{
public class BitWriter
{
private uint bit_buf;
private int bit_left;
private ulong bit_buf_m;
private int bit_left_m;
private byte[] buffer;
private int buf_start, buf_ptr, buf_end;
private int buf_start, buf_ptr_m, buf_end;
private bool eof;
public byte[] Buffer
@@ -22,12 +22,12 @@ namespace CUETools.Codecs
{
get
{
return buf_ptr - buf_start;
return buf_ptr_m - buf_start;
}
set
{
flush();
buf_ptr = buf_start + value;
buf_ptr_m = buf_start + value;
}
}
@@ -35,7 +35,7 @@ namespace CUETools.Codecs
{
get
{
return buf_ptr * 8 + 32 - bit_left;
return buf_ptr_m * 8 + 64 - bit_left_m;
}
}
@@ -43,18 +43,18 @@ namespace CUETools.Codecs
{
buffer = buf;
buf_start = pos;
buf_ptr = pos;
buf_ptr_m = pos;
buf_end = pos + len;
bit_left = 32;
bit_buf = 0;
bit_left_m = 64;
bit_buf_m = 0;
eof = false;
}
public void Reset()
{
buf_ptr = buf_start;
bit_left = 32;
bit_buf = 0;
buf_ptr_m = buf_start;
bit_left_m = 64;
bit_buf_m = 0;
eof = false;
}
@@ -78,7 +78,7 @@ namespace CUETools.Codecs
fixed (byte* buf1 = &buffer[0])
AudioSamples.MemCpy(buf1 + start, buf + start1, end - start);
buffer[start] |= start_val;
buf_ptr = end;
buf_ptr_m = end;
if ((old_pos + len) % 8 != 0)
writebits((old_pos + len) % 8, buf[end1] >> (8 - ((old_pos + len) % 8)));
}
@@ -107,63 +107,52 @@ namespace CUETools.Codecs
public void writebits(int bits, int val)
{
writebits(bits, (uint)val);
writebits(bits, (ulong)val);
}
public void writebits(DateTime val)
{
TimeSpan span = val.ToUniversalTime() - new DateTime(1904, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
writebits(32, (uint)span.TotalSeconds);
}
public void writebits64(int bits, ulong val)
{
if (bits > 32)
{
writebits(bits - 32, (uint)(val >> 32));
val &= 0xffffffffL;
bits = 32;
}
writebits(bits, (uint)val);
writebits(32, (ulong)span.TotalSeconds);
}
public void writebits(int bits, uint val)
{
writebits(bits, (ulong)val);
}
public void writebits(int bits, ulong val)
{
//assert(bits == 32 || val < (1U << bits));
if (bits == 0 || eof) return;
if ((buf_ptr + 3) >= buf_end)
if ((buf_ptr_m + 3) >= buf_end)
{
eof = true;
return;
}
if (bits < bit_left)
if (bits <= bit_left_m)
{
bit_buf = (bit_buf << bits) | val;
bit_left -= bits;
bit_left_m -= bits;
bit_buf_m |= val << bit_left_m;
}
else
{
uint bb = 0;
if (bit_left == 32)
{
//assert(bits == 32);
bb = val;
}
else
{
bb = (bit_buf << bit_left) | (val >> (bits - bit_left));
bit_left += (32 - bits);
}
ulong bb = bit_buf_m | (val >> (bits - bit_left_m));
if (buffer != null)
{
buffer[buf_ptr + 3] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr + 2] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr + 1] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr + 0] = (byte)(bb & 0xFF);
buffer[buf_ptr_m + 7] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 6] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 5] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 4] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 3] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 2] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 1] = (byte)(bb & 0xFF); bb >>= 8;
buffer[buf_ptr_m + 0] = (byte)(bb & 0xFF);
buf_ptr_m += 8;
}
buf_ptr += 4;
bit_buf = val;
bit_left_m = 64 + bit_left_m - bits;
bit_buf_m = val << bit_left_m;
}
}
@@ -259,95 +248,84 @@ namespace CUETools.Codecs
public unsafe void write_rice_block_signed(byte* fixedbuf, int k, int* residual, int count)
{
byte* buf = &fixedbuf[buf_ptr];
//fixed (byte* fixbuf = &buffer[buf_ptr])
byte* buf = &fixedbuf[buf_ptr_m];
ulong bit_buf = bit_buf_m;
int bit_left = bit_left_m;
for (int i = count; i > 0; i--)
{
//byte* buf = fixbuf;
for (int i = count; i > 0; i--)
int v = *(residual++);
v = (v << 1) ^ (v >> 31);
// write quotient in unary
int q = (v >> k) + 1;
int bits = k + q;
while (bits > 56)
{
int v = *(residual++);
v = (v << 1) ^ (v >> 31);
// write quotient in unary
int q = (v >> k) + 1;
int bits = k + q;
while (bits > 31)
#if DEBUG
if (buf + 1 > fixedbuf + buf_end)
{
#if DEBUG
if (buf + 3 >= fixedbuf + buf_end)
{
eof = true;
return;
}
#endif
int b = Math.Min(bits - 31, 31);
if (b < bit_left)
{
bit_buf = (bit_buf << b);
bit_left -= b;
}
else
{
uint bb = bit_buf << bit_left;
bit_buf = 0;
bit_left += (32 - b);
*(buf++) = (byte)(bb >> 24);
*(buf++) = (byte)(bb >> 16);
*(buf++) = (byte)(bb >> 8);
*(buf++) = (byte)(bb);
}
bits -= b;
eof = true;
return;
}
#endif
*(buf++) = (byte)(bit_buf >> 56);
bit_buf <<= 8;
bits -= 8;
}
// write remainder in binary using 'k' bits
//writebits_fast(k + q, (uint)((v & ((1 << k) - 1)) | (1 << k)), ref buf);
ulong val = (uint)((v & ((1 << k) - 1)) | (1 << k));
if (bits <= bit_left)
{
bit_left -= bits;
bit_buf |= val << bit_left;
}
else
{
ulong bb = bit_buf | (val >> (bits - bit_left));
#if DEBUG
if (buf + 3 >= fixedbuf + buf_end)
if (buf + 8 > fixedbuf + buf_end)
{
eof = true;
return;
}
#endif
// write remainder in binary using 'k' bits
//writebits_fast(k + q, (uint)((v & ((1 << k) - 1)) | (1 << k)), ref buf);
uint val = (uint)((v & ((1 << k) - 1)) | (1 << k));
if (bits < bit_left)
{
bit_buf = (bit_buf << bits) | val;
bit_left -= bits;
}
else
{
uint bb = (bit_buf << bit_left) | (val >> (bits - bit_left));
bit_buf = val;
bit_left += (32 - bits);
*(buf++) = (byte)(bb >> 24);
*(buf++) = (byte)(bb >> 16);
*(buf++) = (byte)(bb >> 8);
*(buf++) = (byte)(bb);
}
*(buf++) = (byte)(bb >> 56);
*(buf++) = (byte)(bb >> 48);
*(buf++) = (byte)(bb >> 40);
*(buf++) = (byte)(bb >> 32);
*(buf++) = (byte)(bb >> 24);
*(buf++) = (byte)(bb >> 16);
*(buf++) = (byte)(bb >> 8);
*(buf++) = (byte)(bb);
bit_left = 64 + bit_left - bits;
bit_buf = val << bit_left;
}
buf_ptr = (int)(buf - fixedbuf);
}
buf_ptr_m = (int)(buf - fixedbuf);
bit_buf_m = bit_buf;
bit_left_m = bit_left;
}
public void flush()
{
bit_buf <<= bit_left;
while (bit_left < 32 && !eof)
while (bit_left_m < 64 && !eof)
{
if (buf_ptr >= buf_end)
if (buf_ptr_m >= buf_end)
{
eof = true;
break;
}
if (buffer != null)
buffer[buf_ptr] = (byte)(bit_buf >> 24);
buf_ptr++;
bit_buf <<= 8;
bit_left += 8;
buffer[buf_ptr_m] = (byte)(bit_buf_m >> 56);
buf_ptr_m++;
bit_buf_m <<= 8;
bit_left_m += 8;
}
bit_left = 32;
bit_buf = 0;
bit_left_m = 64;
bit_buf_m = 0;
}
}
}