///|
// Fixed order0..4 on already validated signed33-bit-or-narrower PCM.
// The complete finite-difference coefficient absolute sum is at most16:
// every product/partial sum fits Int64 with magnitude at most2^36.
// Separating 128 values of arithmetic from checks permits integer SIMD;
// output is committed only in the same ascending validated prefix as before.
fn encoder_fixed_integer_tiles(
samples : Array[Int64],
order : Int32,
residual : Array[Int64],
tile : FixedArray[Int64],
) -> Bool {
let size = samples.length()
for start = order; start < size; start = start + 128 {
let count = if size - start < 128 { size - start } else { 128 }
match order {
0 =>
for i = 0; i < count; i = i + 1 {
tile.unsafe_set(i, samples.unsafe_get(start + i))
}
1 =>
for i = 0; i < count; i = i + 1 {
tile.unsafe_set(
i,
samples.unsafe_get(start + i) - samples.unsafe_get(start + i - 1),
)
}
2 =>
for i = 0; i < count; i = i + 1 {
tile.unsafe_set(
i,
samples.unsafe_get(start + i) -
2L * samples.unsafe_get(start + i - 1) +
samples.unsafe_get(start + i - 2),
)
}
3 =>
for i = 0; i < count; i = i + 1 {
tile.unsafe_set(
i,
samples.unsafe_get(start + i) -
3L * samples.unsafe_get(start + i - 1) +
3L * samples.unsafe_get(start + i - 2) -
samples.unsafe_get(start + i - 3),
)
}
_ =>
for i = 0; i < count; i = i + 1 {
tile.unsafe_set(
i,
samples.unsafe_get(start + i) -
4L * samples.unsafe_get(start + i - 1) +
6L * samples.unsafe_get(start + i - 2) -
4L * samples.unsafe_get(start + i - 3) +
samples.unsafe_get(start + i - 4),
)
}
}
for i = 0; i < count; i = i + 1 {
let value = tile.unsafe_get(i)
if value <= -2147483648L || value >= 2147483648L {
return false
}
residual.unsafe_set(start + i, value)
}
}
true
}
// Exact integer frame serialization and cost-based subframe selection, RFC 9639 搂9.
///|
priv struct EncoderBits {
mut buffer : FixedArray[Byte]
mut length : Int32
mut word : UInt64
mut used : Int32
}
///|
fn EncoderBits::new() -> EncoderBits {
{ buffer: FixedArray::make(16, 0), length: 0, word: 0UL, used: 0, }
}
///|
fn EncoderBits::reserve(self : EncoderBits, capacity : Int32) -> Unit {
if capacity != self.buffer.length() {
let next = FixedArray::make(capacity, (0).to_byte())
for i = 0; i < self.length; i = i + 1 {
next.unsafe_set(i, self.buffer.unsafe_get(i))
}
self.buffer = next
}
}
///|
fn EncoderBits::ensure(self : EncoderBits, extra : Int32) -> Unit {
let required = self.length + extra
if required > self.buffer.length() {
let grown = self.buffer.length() * 2
self.reserve(if required > grown { required } else { grown })
}
}
///|
fn EncoderBits::emit_word(self : EncoderBits, value : UInt64) -> Unit {
self.ensure(8)
self.buffer.unsafe_write_uint64_be(self.length, value)
self.length += 8
}
///|
fn EncoderBits::write(self : EncoderBits, value : Int64, width : Int32) -> Unit {
if width == 0 {
return
}
let bits = value.reinterpret_as_uint64()
let room = 64 - self.used
if width < room {
self.word = (self.word << width) | (bits & ((1UL << width) - 1UL))
self.used += width
} else {
let left = width - room
// room==64 implies used==0; never shift by64 (backend masks differ).
let complete = if room == 64 {
bits
} else {
(self.word << room) | ((bits >> left) & ((1UL << room) - 1UL))
}
self.emit_word(complete)
self.used = left
self.word = if left == 0 { 0UL } else { bits & ((1UL << left) - 1UL) }
}
}
///|
fn EncoderBits::unary(self : EncoderBits, zeros : Int64) -> Unit {
let mut left = zeros
while left >= 64L {
self.write(0L, 64)
left -= 64L
}
self.write(0L, left.to_int())
self.write(1L, 1)
}
///|
fn EncoderBits::align(self : EncoderBits) -> Unit {
let partial = self.used % 8
if partial != 0 {
self.write(0L, 8 - partial)
}
}
///|
/// Materialize complete bytes only; preserve the low pending partial byte.
fn EncoderBits::materialize(self : EncoderBits) -> Unit {
let count = self.used / 8
self.ensure(count)
for i = 0; i < count; i = i + 1 {
self.buffer.unsafe_set(
self.length + i,
(self.word >> (self.used - (i + 1) * 8)).to_byte(),
)
}
self.length += count
self.used %= 8
self.word = self.word & ((1UL << self.used) - 1UL)
}
///|
fn EncoderBits::crc(self : EncoderBits, width : Int32) -> Int32 {
self.materialize()
let mut crc = 0
for i = 0; i < self.length; i = i + 1 {
let byte = self.buffer.unsafe_get(i).to_int()
crc = if width == 8 {
frame_crc8_table.unsafe_get(crc ^ byte)
} else {
((crc << 8) & 65535) ^ frame_crc16_table.unsafe_get((crc >> 8) ^ byte)
}
}
crc
}
///|
/// Freeze only after all writes. Detach the mutable owner before returning.
fn EncoderBits::finish(self : EncoderBits) -> Bytes {
self.align()
self.materialize()
if self.buffer.length() != self.length {
self.reserve(self.length)
}
let completed = self.buffer
self.buffer = FixedArray::make(0, 0)
self.length = 0
completed.unsafe_reinterpret_as_bytes()
}
///|
fn encoder_number(
out : EncoderBits,
number : Int64,
variable : Bool,
) -> Unit raise FlacError {
if number < 0L || number > (if variable { 68719476735L } else { 2147483647L }) {
raise Invalid(0L, "encoded frame/sample number exceeds format range")
}
if number < 128L {
out.write(number, 8)
return
}
let limits = [2048L, 65536L, 2097152L, 67108864L, 2147483648L, 68719476736L]
let mut count = 2
while number >= limits[count - 2] {
count += 1
}
let prefix = (256 - (1 << (8 - count))).to_int64()
out.write(prefix | (number >> ((count - 1) * 6)), 8)
for i = count - 2; i >= 0; i = i - 1 {
out.write(128L | ((number >> (i * 6)) & 63L), 8)
}
}
///|
priv struct EncoderPartition {
parameter : Int32
width : Int32
count : Int32
}
///|
priv struct EncoderResidual {
order : Int32
rice2 : Bool
parts : Array[EncoderPartition]
bits : Int64
}
// Quotient sums permit all Rice parameters and partition levels to be costed
// without writing speculative unary strings. Nodes are merged bottom-up.
///|
priv struct EncoderRiceNode {
quotients : Array[Int64]
mut count : Int32
mut width : Int32
}
///|
fn encoder_signed_width(value : Int64) -> Int32 {
if value == 0L {
return 0
}
// For negative values, complement removes the redundant sign extension.
65 - (if value < 0L { value.lnot() } else { value }).clz()
}
///|
fn encoder_rice_parameter(node : EncoderRiceNode, maximum : Int32) -> Int32 {
// Bit lengths give a conservative lower bound within one of the original
// repeated-doubling bound. No quotient division or approximate cost is used.
let bound = node.count.to_int64().clz() - node.quotients[0].clz() - 2
let mut parameter = if bound < 0 {
0
} else if bound > maximum {
maximum
} else {
bound
}
// For every skipped k, sum(ceil((u >> k)/2)) > count follows
// from sum(u) > count * 2^(k+2). Thus C(k+1) < C(k) strictly.
// The bound is conservative for arbitrary residual distributions.
while parameter < maximum &&
node.quotients[0] > node.count.to_int64() << (parameter + 2) {
parameter += 1
}
let mut cost = node.quotients[parameter] +
node.count.to_int64() * (parameter + 1).to_int64()
for k = parameter + 1; k <= maximum; k = k + 1 {
let candidate = node.quotients[k] +
node.count.to_int64() * (k + 1).to_int64()
if candidate < cost {
cost = candidate
parameter = k
} else {
// C(k+1)-C(k) = count - sum(ceil((u >> k)/2)). This
// difference is nondecreasing, so the first non-improvement is final.
// Keeping the earlier parameter also preserves the existing tie rule.
break
}
}
parameter
}
///|
fn encoder_partition(
node : EncoderRiceNode,
rice2 : Bool,
) -> (EncoderPartition, Int64) {
let parameter_bits = if rice2 { 5 } else { 4 }
let maximum = if rice2 { 30 } else { 14 }
let parameter = encoder_rice_parameter(node, maximum)
let cost = node.quotients[parameter] +
node.count.to_int64() * (parameter + 1).to_int64() +
parameter_bits.to_int64()
if node.width <= 31 {
let escaped = (parameter_bits + 5).to_int64() +
node.count.to_int64() * node.width.to_int64()
if escaped < cost {
return (
{
parameter: (1 << parameter_bits) - 1,
width: node.width,
count: node.count,
},
escaped,
)
}
}
({ parameter, width: -1, count: node.count, }, cost)
}
///|
fn encoder_residual_plan(
samples : Array[Int64],
predictor : Int32,
max_partition : Int32,
workspace~ : Array[Array[Int64]] = [],
) -> EncoderResidual {
let size = samples.length()
if predictor < size {
let value = samples[predictor]
let mut constant = true
for i = predictor + 1; i < size; i = i + 1 {
if samples[i] != value {
constant = false
break
}
}
if constant {
// Each partition has the same Rice slope and escape width. Splitting
// adds parameter/escape headers and cannot improve the minimum of those
// two affine costs. Partition zero wins all ties.
let count = size - predictor
let folded = if value < 0L { -value * 2L - 1L } else { value * 2L }
let node : EncoderRiceNode = {
quotients: Array::makei(31, k => (folded >> k) * count.to_int64()),
count,
width: encoder_signed_width(value),
}
let (part0, cost0) = encoder_partition(node, false)
let (part1, cost1) = encoder_partition(node, true)
return if cost1 < cost0 {
{ order: 0, rice2: true, parts: [part1], bits: 6L + cost1, }
} else {
{ order: 0, rice2: false, parts: [part0], bits: 6L + cost0, }
}
}
}
let mut order = 0
while order < max_partition &&
size % (1 << (order + 1)) == 0 &&
size >> (order + 1) > predictor {
order += 1
}
let partition_size = size >> order
let nodes : Array[EncoderRiceNode] = []
for p = 0; p < 1 << order; p = p + 1 {
let start = if p == 0 { predictor } else { p * partition_size }
let end = (p + 1) * partition_size
// Scratch belongs to one subframe search. Plans retain only scalar records,
// never these arrays, so later candidates may clear and reuse every slot.
if p == workspace.length() {
workspace.push(Array::make(31, 0L))
}
let quotients = workspace[p]
for k = 0; k < 31; k = k + 1 {
quotients[k] = 0L
}
let mut width = 0
for i = start; i < end; i = i + 1 {
let value = samples[i]
let w = encoder_signed_width(value)
if w > width {
width = w
}
let mut folded = if value < 0L { -value * 2L - 1L } else { value * 2L }
let mut k = 0
while folded != 0L && k <= 30 {
quotients[k] += folded
folded = folded >> 1
k += 1
}
}
nodes.push({ quotients, count: end - start, width, })
}
// Store compact scalar choices for all levels, materializing records only
// after the global winning level is known. Total tree nodes are < 2 * leaves.
let choices0 = Array::make(nodes.length() * 2, 0)
let choices1 = Array::make(nodes.length() * 2, 0)
let mut active = nodes.length()
let mut offset = 0
let mut best_offset = 0
let mut best_order = 0
let mut best_rice2 = false
let mut best_bits = 9223372036854775807L
while true {
let mut bits0 = 6L
let mut bits1 = 6L
for i = 0; i < active; i = i + 1 {
let node = nodes[i]
let k1 = encoder_rice_parameter(node, 30)
let k0 = if k1 > 14 { 14 } else { k1 }
let count = node.count.to_int64()
let cost0 = node.quotients[k0] + count * (k0 + 1).to_int64() + 4L
let cost1 = node.quotients[k1] + count * (k1 + 1).to_int64() + 5L
let escape0 = 9L + count * node.width.to_int64()
if node.width <= 31 && escape0 < cost0 {
choices0[offset + i] = 32 + node.width
bits0 += escape0
} else {
choices0[offset + i] = k0
bits0 += cost0
}
if node.width <= 31 && escape0 + 1L < cost1 {
choices1[offset + i] = 32 + node.width
bits1 += escape0 + 1L
} else {
choices1[offset + i] = k1
bits1 += cost1
}
}
// The earliest convex minimum clamped to 14 is the Rice minimum.
// Rice wins method ties; later iterations have lower partition orders.
let rice2 = bits1 < bits0
let bits = if rice2 { bits1 } else { bits0 }
if bits <= best_bits {
best_bits = bits
best_offset = offset
best_order = order
best_rice2 = rice2
}
offset += active
if order == 0 {
break
}
// Compact the tree in place. Every parent consumes two nodes before its
// slot is overwritten; the quotient arrays can be reused without aliasing.
for i = 0; i < active; i = i + 2 {
let a = nodes[i]
let b = nodes[i + 1]
let width = if a.width > b.width { a.width } else { b.width }
let columns = if width < 31 { width } else { 31 }
// Folded residuals have at most `width` bits; higher columns are zero.
for k = 0; k < columns; k = k + 1 {
a.quotients[k] += b.quotients[k]
}
a.count += b.count
a.width = width
nodes[i / 2] = a
}
active = active / 2
order -= 1
}
let choices = if best_rice2 { choices1 } else { choices0 }
let count = size >> best_order
let parts = Array::makei(1 << best_order, i => {
let choice = choices[best_offset + i]
{
parameter: if choice >= 32 {
if best_rice2 {
31
} else {
15
}
} else {
choice
},
width: if choice >= 32 {
choice - 32
} else {
-1
},
count: if i == 0 {
count - predictor
} else {
count
},
}
})
{ order: best_order, rice2: best_rice2, parts, bits: best_bits, }
}
///|
priv struct EncoderSubframe {
kind : Int32
wasted : Int32
depth : Int32
samples : Array[Int64]
coefficients : Array[Int64]
shift : Int32
precision : Int32
residual : Array[Int64]
plan : EncoderResidual?
bits : Int64
}
///|
fn encoder_fixed_coefficients(order : Int32) -> Array[Int64] {
match order {
0 => []
1 => [1L]
2 => [2L, -1L]
3 => [3L, -3L, 1L]
_ => [4L, -6L, 4L, -1L]
}
}
///|
fn encoder_predictor(
samples : Array[Int64],
coefficients : Array[Int64],
shift : Int32,
) -> Array[Int64]? {
let residual = Array::make(samples.length(), 0L)
if encoder_predict_into(samples, coefficients, shift, residual) {
Some(residual)
} else {
None
}
}
///|
fn encoder_predict_into(
samples : Array[Int64],
coefficients : Array[Int64],
shift : Int32,
residual : Array[Int64],
) -> Bool {
let order = coefficients.length()
for i = order; i < samples.length(); i = i + 1 {
let mut prediction = 0L
for j = 0; j < order; j = j + 1 {
// j> shift)
if value <= -2147483648L || value >= 2147483648L {
return false
}
residual.unsafe_set(i, value)
}
true
}
///|
/// For fixed order p>=1 and signed b-bit samples, positive and negative
/// finite-difference weights each sum to 2^(p-1). Thus |residual| is at most
/// 2^(p-1)*(2^b-1). If b+p<=32, that is strictly below 2^31, including the
/// asymmetric two's-complement extrema. No per-sample residual check is needed.
/// The caller proves sample depth and chooses the generic path otherwise.
fn encoder_fixed_predict_into(
samples : Array[Int64],
order : Int32,
residual : Array[Int64],
) -> Unit {
let size = samples.length()
match order {
1 =>
for i = 1; i < size; i = i + 1 {
residual.unsafe_set(
i,
samples.unsafe_get(i) - samples.unsafe_get(i - 1),
)
}
2 =>
for i = 2; i < size; i = i + 1 {
residual.unsafe_set(
i,
samples.unsafe_get(i) -
2L * samples.unsafe_get(i - 1) +
samples.unsafe_get(i - 2),
)
}
3 =>
for i = 3; i < size; i = i + 1 {
residual.unsafe_set(
i,
samples.unsafe_get(i) -
3L * samples.unsafe_get(i - 1) +
3L * samples.unsafe_get(i - 2) -
samples.unsafe_get(i - 3),
)
}
_ =>
for i = 4; i < size; i = i + 1 {
residual.unsafe_set(
i,
samples.unsafe_get(i) -
4L * samples.unsafe_get(i - 1) +
6L * samples.unsafe_get(i - 2) -
4L * samples.unsafe_get(i - 3) +
samples.unsafe_get(i - 4),
)
}
}
}
///|
fn EncoderPlanScratch::predict_fixed(
self : EncoderPlanScratch,
samples : Array[Int64],
coefficients : Array[Int64],
depth : Int32,
) -> Bool {
let order = coefficients.length()
if order >= 0 &&
order <= 4 &&
depth >= 1 &&
depth <= 33 &&
((order == 0 && depth >= 32) || depth + order > 32) {
let size = samples.length()
if self.residual.length() != size {
self.residual = Array::make(size, 0L)
}
if self.fixed_tile.length() == 0 {
self.fixed_tile = FixedArray::make(128, 0L)
}
for i = 0; i < order && i < size; i = i + 1 {
self.residual.unsafe_set(i, 0L)
}
return encoder_fixed_integer_tiles(
samples,
order,
self.residual,
self.fixed_tile,
)
}
if order < 1 || order > 4 || depth < 1 || depth + order > 32 {
return self.predict(samples, coefficients, 0)
}
let size = samples.length()
if self.residual.length() != size {
self.residual = Array::make(size, 0L)
}
for i = 0; i < order && i < size; i = i + 1 {
self.residual.unsafe_set(i, 0L)
}
encoder_fixed_predict_into(samples, order, self.residual)
true
}
///|
/// Cache one exactly converted, bounds-validated plane per wasted-bit choice.
fn encoder_lpc_double_signal(
samples : Array[Int64],
depth : Int32,
) -> FixedArray[Double]? {
if depth < 1 || depth > 33 {
return None
}
let bound = 1L << (depth - 1)
let signal = FixedArray::make(samples.length(), 0.0)
for i = 0; i < samples.length(); i = i + 1 {
let value = samples.unsafe_get(i)
if value < -bound || value >= bound {
return None
}
signal.unsafe_set(i, value.to_double())
}
Some(signal)
}
///|
/// Integer-valued IEEE754 arithmetic: |sample|<=2^32, |coefficient|<=2^14,
/// and at most32 taps imply every product/partial sum has magnitude<=2^51.
/// All are exactly representable in Double. The dyadic difference is exact;
/// ceil(x-P/2^shift) equals x-(P>>shift). Bias rounding plus a comparison
/// corrects downward rounding to ceil around the legal residual interval.
fn encoder_predict_double_into(
samples : Array[Int64],
signal : FixedArray[Double],
coefficients : FixedArray[Double],
shift : Int32,
residual : Array[Int64],
tile : FixedArray[Double],
) -> Bool {
let order = coefficients.length()
let size = samples.length()
let scale = 1.0 / (1L << shift).to_double()
for start = order; start < size; start = start + 128 {
let count = if size - start < 128 { size - start } else { 128 }
if size <= 65535 {
let grouped = count / 16 * 16
for i = 0; i < grouped; i = i + 16 {
let mut a0 = 0.0
let mut a1 = 0.0
let mut a2 = 0.0
let mut a3 = 0.0
let mut a4 = 0.0
let mut a5 = 0.0
let mut a6 = 0.0
let mut a7 = 0.0
let mut a8 = 0.0
let mut a9 = 0.0
let mut a10 = 0.0
let mut a11 = 0.0
let mut a12 = 0.0
let mut a13 = 0.0
let mut a14 = 0.0
let mut a15 = 0.0
for j = 0; j < order; j = j + 1 {
let coefficient = coefficients.unsafe_get(j)
// Identity on proven nonnegative legal FLAC indices.
let base = (start + i - j - 1) & 65535
a0 += coefficient * signal.unsafe_get(base + 0)
a1 += coefficient * signal.unsafe_get(base + 1)
a2 += coefficient * signal.unsafe_get(base + 2)
a3 += coefficient * signal.unsafe_get(base + 3)
a4 += coefficient * signal.unsafe_get(base + 4)
a5 += coefficient * signal.unsafe_get(base + 5)
a6 += coefficient * signal.unsafe_get(base + 6)
a7 += coefficient * signal.unsafe_get(base + 7)
a8 += coefficient * signal.unsafe_get(base + 8)
a9 += coefficient * signal.unsafe_get(base + 9)
a10 += coefficient * signal.unsafe_get(base + 10)
a11 += coefficient * signal.unsafe_get(base + 11)
a12 += coefficient * signal.unsafe_get(base + 12)
a13 += coefficient * signal.unsafe_get(base + 13)
a14 += coefficient * signal.unsafe_get(base + 14)
a15 += coefficient * signal.unsafe_get(base + 15)
}
tile.unsafe_set(i + 0, a0)
tile.unsafe_set(i + 1, a1)
tile.unsafe_set(i + 2, a2)
tile.unsafe_set(i + 3, a3)
tile.unsafe_set(i + 4, a4)
tile.unsafe_set(i + 5, a5)
tile.unsafe_set(i + 6, a6)
tile.unsafe_set(i + 7, a7)
tile.unsafe_set(i + 8, a8)
tile.unsafe_set(i + 9, a9)
tile.unsafe_set(i + 10, a10)
tile.unsafe_set(i + 11, a11)
tile.unsafe_set(i + 12, a12)
tile.unsafe_set(i + 13, a13)
tile.unsafe_set(i + 14, a14)
tile.unsafe_set(i + 15, a15)
}
for i = grouped; i < count; i = i + 1 {
let mut value = 0.0
for j = 0; j < order; j = j + 1 {
value += coefficients.unsafe_get(j) *
signal.unsafe_get(start + i - j - 1)
}
tile.unsafe_set(i, value)
}
} else {
for i = 0; i < count; i = i + 1 {
tile.unsafe_set(i, 0.0)
}
for j = 0; j < order; j = j + 1 {
let coefficient = coefficients.unsafe_get(j)
for i = 0; i < count; i = i + 1 {
// j= 0xffffffffUL {
return false
}
residual.unsafe_set(start + i, bits.to_int().to_int64())
}
}
true
}
///|
/// Only validated LPC models use this route; all unproven cases stay integer.
fn EncoderPlanScratch::predict_lpc_double(
self : EncoderPlanScratch,
samples : Array[Int64],
signal : FixedArray[Double]?,
coefficients : Array[Int64],
shift : Int32,
) -> Bool {
let order = coefficients.length()
if order < 1 || order > 32 || shift < 0 || shift > 15 {
return self.predict(samples, coefficients, shift)
}
let signal = match signal {
Some(signal) => signal
None => return self.predict(samples, coefficients, shift)
}
if signal.length() != samples.length() {
return self.predict(samples, coefficients, shift)
}
for coefficient in coefficients {
if coefficient < -16384L || coefficient > 16383L {
return self.predict(samples, coefficients, shift)
}
}
let size = samples.length()
if self.residual.length() != size {
self.residual = Array::make(size, 0L)
}
if self.double_tile.length() == 0 {
self.double_tile = FixedArray::make(128, 0.0)
}
for i = 0; i < order && i < size; i = i + 1 {
self.residual.unsafe_set(i, 0L)
}
let converted = FixedArray::makei(order, i => {
coefficients.unsafe_get(i).to_double()
})
encoder_predict_double_into(
samples,
signal,
converted,
shift,
self.residual,
self.double_tile,
)
}
///|
fn encoder_subframe(
samples : Array[Int64],
width : Int32,
effort : Int32,
plan_scratch~ : EncoderPlanScratch = EncoderPlanScratch::new(),
) -> EncoderSubframe {
let size = samples.length()
let workspace : Array[Array[Int64]] = []
let mut wasted = width - 1
let mut constant_input = true
for sample in samples {
if sample != samples[0] {
constant_input = false
}
if sample != 0L {
let mut zeros = 0
while zeros < wasted && (sample & (1L << zeros)) == 0L {
zeros += 1
}
if zeros < wasted {
wasted = zeros
}
}
}
let mut best : EncoderSubframe = {
kind: 1,
wasted: 0,
depth: width,
samples,
coefficients: [],
shift: 0,
precision: 0,
residual: [],
plan: None,
bits: 8L + size.to_int64() * width.to_int64(),
}
let choices = if wasted == 0 { [0] } else { [0, wasted] }
for wasted in choices {
let depth = width - wasted
let shifted = if wasted == 0 {
samples
} else {
samples.map(x => x >> wasted)
}
let header_bits = 8L + wasted.to_int64()
let constant = constant_input
if constant && header_bits + depth.to_int64() < best.bits {
best = {
..best,
kind: 0,
wasted,
depth,
samples: shifted,
bits: header_bits + depth.to_int64(),
}
}
let verbatim = header_bits + size.to_int64() * depth.to_int64()
if verbatim < best.bits {
best = {
..best,
kind: 1,
wasted,
depth,
samples: shifted,
plan: None,
bits: verbatim,
}
}
if effort == 0 {
continue
}
// A constant signal can still be cheaper as fixed order zero (notably
// wide-depth zero blocks with escape width zero). Higher predictors need
// a warm-up at least as expensive as the entire constant sample field.
let max_partition = if constant {
0
} else if effort == 8 {
ENCODER_PARTITION_CAP
} else {
effort
}
let max_fixed = if constant { 0 } else { 4 }
let fixed_orders = if effort == 8 && size > 256 && !constant {
encoder_fixed_ordering(shifted, depth)
} else {
Array::makei(if max_fixed < size { max_fixed + 1 } else { size }, i => i)
}
for order in fixed_orders {
let coefficients = encoder_fixed_coefficients(order)
let residual = if order == 0 && depth < 32 {
// All values at this depth are legal residuals, with no warm-ups.
Some(shifted)
} else if plan_scratch.predict_fixed(shifted, coefficients, depth) {
Some(plan_scratch.residual)
} else {
None
}
if residual is Some(residual) {
// Restore original ascending-order priority only within this wasted
// choice's fixed candidates. Earlier categories/choices keep ties.
let replace_fixed_tie = best.wasted == wasted &&
best.kind >= 8 &&
best.kind <= 12 &&
order < best.kind - 8
let plan = if !constant && effort == 8 {
match
encoder_budget_residual_plan(
residual,
order,
best.bits -
header_bits -
(order * depth).to_int64() +
(if replace_fixed_tie { 1L } else { 0L }),
plan_scratch,
) {
Some(plan) => plan
None => continue
}
} else {
encoder_residual_plan(residual, order, max_partition, workspace~)
}
let cost = header_bits + (order * depth).to_int64() + plan.bits
if cost < best.bits || (replace_fixed_tie && cost == best.bits) {
best = {
kind: order + 8,
wasted,
depth,
samples: shifted,
coefficients,
shift: 0,
precision: 0,
// Later predictors reuse scratch; the winner owns its samples.
residual: residual.copy(),
plan: Some(plan),
bits: cost,
}
}
}
}
if constant {
continue
}
let limits = [0, 0, 2, 4, 8, 12, 16, 24, 32]
let max_order = if limits[effort] < size {
limits[effort]
} else {
size - 1
}
// A short block already fits within the sampling budget. Evaluate its
// complete model pool in original order: a width proxy can badly rank
// shared Rice costs, and offers no sampling reduction at this size.
// A winning deeply partitioned fixed candidate proves that local residual
// distributions matter. Global sampled-width ranking is unsuitable there.
let deep_partitions = match best.plan {
Some(plan) => size >> plan.order <= 8
None => false
}
// Irregular blocks rank stratified exact integer residual probes by
// shared Rice costs, including all edge samples around warm-ups.
let rice_irregular = effort == 8 &&
size > ENCODER_LPC_PROBES &&
size % (1 << ENCODER_PARTITION_CAP) != 0 &&
!deep_partitions
let shortlist = effort == 8 &&
size > ENCODER_LPC_PROBES &&
size % (1 << ENCODER_PARTITION_CAP) == 0 &&
!deep_partitions
let variances : Array[Double?] = []
let models = encoder_lpc_models(
shifted,
max_order,
variances=if shortlist { Some(variances) } else { None },
)
let candidates = if rice_irregular {
encoder_lpc_rice_ranking(shifted, models, depth)
} else if shortlist {
// Rank the full pool so an illegal full residual does not consume a
// finalist slot. Sampled legality cannot establish whole-frame legality.
encoder_lpc_variance_ranking(shifted, models, variances, depth)
} else {
models
}
let mut double_signal : FixedArray[Double]? = None
let mut double_signal_ready = false
let mut valid_candidates = 0
for model in candidates {
if (shortlist || rice_irregular) &&
valid_candidates >= ENCODER_LPC_SHORTLIST {
break
}
let order = model.coefficients.length()
if order > 0 &&
order <= max_order &&
model.shift >= 0 &&
model.shift <= 15 &&
model.precision >= 1 &&
model.precision <= 15 {
if !double_signal_ready {
double_signal = encoder_lpc_double_signal(shifted, depth)
double_signal_ready = true
}
if plan_scratch.predict_lpc_double(
shifted,
double_signal,
model.coefficients,
model.shift,
) {
let residual = plan_scratch.residual
valid_candidates += 1
let plan = if effort == 8 {
match
encoder_budget_residual_plan(
residual,
order,
best.bits -
header_bits -
(order * depth + 9 + order * model.precision).to_int64(),
plan_scratch,
) {
Some(plan) => plan
None => continue
}
} else {
encoder_residual_plan(residual, order, max_partition, workspace~)
}
let cost = header_bits +
(order * depth + 9 + order * model.precision).to_int64() +
plan.bits
if cost < best.bits {
best = {
kind: order + 31,
wasted,
depth,
samples: shifted,
coefficients: model.coefficients,
shift: model.shift,
precision: model.precision,
residual: residual.copy(),
plan: Some(plan),
bits: cost,
}
}
}
}
}
}
best
}
///|
fn encoder_write_subframe(out : EncoderBits, sub : EncoderSubframe) -> Unit {
out.write(
((sub.kind << 1) | (if sub.wasted > 0 { 1 } else { 0 })).to_int64(),
8,
)
if sub.wasted > 0 {
out.unary((sub.wasted - 1).to_int64())
}
if sub.kind == 0 {
out.write(sub.samples[0], sub.depth)
return
}
if sub.kind == 1 {
for sample in sub.samples {
out.write(sample, sub.depth)
}
return
}
let order = sub.coefficients.length()
for i = 0; i < order; i = i + 1 {
out.write(sub.samples[i], sub.depth)
}
if sub.kind >= 32 {
out.write((sub.precision - 1).to_int64(), 4)
out.write(sub.shift.to_int64(), 5)
for coefficient in sub.coefficients {
out.write(coefficient, sub.precision)
}
}
if sub.plan is Some(plan) {
out.write(if plan.rice2 { 1L } else { 0L }, 2)
out.write(plan.order.to_int64(), 4)
let mut cursor = order
for part in plan.parts {
out.write(part.parameter.to_int64(), if plan.rice2 { 5 } else { 4 })
if part.width >= 0 {
out.write(part.width.to_int64(), 5)
}
for i = 0; i < part.count; i = i + 1 {
let value = sub.residual[cursor]
if part.width >= 0 {
out.write(value, part.width)
} else {
let folded = if value < 0L { -value * 2L - 1L } else { value * 2L }
out.unary(folded >> part.parameter)
out.write(folded, part.parameter)
}
cursor += 1
}
}
}
}
///|
fn encode_frame(
format : PcmFormat,
planes : Array[Array[Int32]],
number : Int64,
variable_block : Bool,
effort : Int32,
) -> Bytes raise FlacError {
if format.channels < 1 ||
format.channels > 8 ||
format.bits_per_sample < 4 ||
format.bits_per_sample > 32 ||
format.sample_rate < 0 ||
format.sample_rate > 1048575 ||
planes.length() != format.channels ||
effort < 0 ||
effort > 8 {
raise Invalid(0L, "invalid encoder frame format or effort")
}
let size = planes[0].length()
if size < 1 || size > 65535 {
raise Invalid(0L, "encoder block size must be 1..65535")
}
let bound = 1L << (format.bits_per_sample - 1)
for plane in planes {
if plane.length() != size {
raise Invalid(0L, "encoder channel lengths differ")
}
for value in plane {
if value.to_int64() < -bound || value.to_int64() >= bound {
raise Invalid(0L, "input PCM exceeds declared bit depth")
}
}
}
encode_frame_validated(format, planes, number, variable_block, effort)
}
///|
/// Internal path for Encoder's validated, owned PCM. Its caller proves format,
/// effort, channel count, equal nonempty lengths <=65535 and scalar range.
/// The checked encode_frame wrapper remains the entry for other callers.
fn encode_frame_validated(
format : PcmFormat,
planes : Array[Array[Int32]],
number : Int64,
variable_block : Bool,
effort : Int32,
plan_scratch~ : EncoderPlanScratch = EncoderPlanScratch::new(),
) -> Bytes raise FlacError {
let size = planes[0].length()
let original = planes.map(plane => plane.map(x => x.to_int64()))
let mut assignment = format.channels - 1
let mut chosen = original.map(samples => {
encoder_subframe(samples, format.bits_per_sample, effort, plan_scratch~)
})
let mut cost = 0L
for sub in chosen {
cost += sub.bits
}
if format.channels == 2 && effort > 0 {
let left = original[0]
let right = original[1]
let side = Array::makei(size, i => left[i] - right[i])
let side_sub = encoder_subframe(
side,
format.bits_per_sample + 1,
effort,
plan_scratch~,
)
let mid = Array::makei(size, i => (left[i] + right[i]) >> 1)
let mid_sub = encoder_subframe(
mid,
format.bits_per_sample,
effort,
plan_scratch~,
)
let combinations = [
[chosen[0], side_sub],
[side_sub, chosen[1]],
[mid_sub, side_sub],
]
for i = 0; i < 3; i = i + 1 {
let candidate = combinations[i]
let bits = candidate[0].bits + candidate[1].bits
if bits < cost {
assignment = i + 8
chosen = candidate
cost = bits
}
}
}
let out = EncoderBits::new()
out.write(if variable_block { 0xFFF9L } else { 0xFFF8L }, 16)
out.write(if size <= 256 { 6L } else { 7L }, 4)
out.write(0L, 4) // STREAMINFO carries the full 20-bit sample-rate domain.
out.write(assignment.to_int64(), 4)
let depth_code = match format.bits_per_sample {
8 => 1
12 => 2
16 => 4
20 => 5
24 => 6
32 => 7
_ => 0
}
out.write(depth_code.to_int64(), 3)
out.write(0L, 1)
encoder_number(out, number, variable_block)
out.write((size - 1).to_int64(), if size <= 256 { 8 } else { 16 })
let header_crc = out.crc(8)
let final_size = out.length + 1 + ((cost + 7L) / 8L).to_int() + 2
// Chosen cost never exceeds independent verbatim: at most8 planes,
// 65535 samples and33 bits/sample, under2.2MiB including headers.
out.reserve(final_size)
out.write(header_crc.to_int64(), 8)
for sub in chosen {
encoder_write_subframe(out, sub)
}
out.align()
out.write(out.crc(16).to_int64(), 16)
out.materialize()
if out.length != final_size {
raise Invalid(0L, "internal encoded frame size differs from exact cost")
}
out.finish()
}