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

View File

@@ -593,7 +593,7 @@ namespace CUETools.Codecs.FLAKE
AudioSamples.MemCpy(res, smp, (int) n); 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 i;
int s0, s1, s2; int s0, s1, s2;
@@ -1928,8 +1928,8 @@ new int[] { // 30
bitwriter.writebits(24, 18 * seek_table.Length); bitwriter.writebits(24, 18 * seek_table.Length);
for (int i = 0; i < seek_table.Length; i++) 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.writebits(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_STREAM_OFFSET_LEN, (ulong)seek_table[i].offset);
bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, seek_table[i].framesize); bitwriter.writebits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, seek_table[i].framesize);
} }
bitwriter.flush(); bitwriter.flush();

View File

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