///|
// 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()
}