///|
/// Whole-frame and whole-stream decoding, producing interleaved PCM samples.
/// One decoded audio frame: its header plus the per-channel samples in
/// standard channel order (left, right, ...).
pub struct DecodedFrame {
header : FrameHeader
channels : Array[Array[Int]]
}
/// Decode the frame starting at byte `offset` of `data`, returning the frame
/// and the byte offset of the next frame (just past the CRC-16).
pub fn decode_frame(data : Bytes, offset : Int, info : StreamInfo) -> (DecodedFrame, Int) raise DecodeError {
let reader = BitReader::new(data).skip(offset * 8)
let (header, r1) = reader.read_frame_header(info)
let block_size = header.block_size
let planar = Array::make(header.channels, Array::make(0, 0))
let mut r = r1
for c in 0.. Pcm {
{ sample_rate: sample_rate, channels: channels, bits_per_sample: bits_per_sample, samples: samples }
}
/// Decode a whole FLAC stream into interleaved PCM, stopping at the end of the
/// audio (or at the first non-frame byte, e.g. trailing tags).
pub fn decode(data : Bytes) -> Pcm raise DecodeError {
let meta = parse_metadata(data)
let info = meta.info
let total = info.total_samples
let mut offset = meta.frame_offset
let samples = Array::make(0, 0)
let mut decoded : Int64 = 0L
while offset + 2 <= data.length() && (total == 0L || decoded < total) {
let word = (data[offset].to_int() << 8) | data[offset + 1].to_int()
if (word & 0xFFFC) != 0xFFF8 {
break
}
let (frame, next) = decode_frame(data, offset, info)
let n = frame.header.block_size
let out_channels = frame.channels.length()
for i in 0.. 0L {
(total * Int64::from_int(info.channels)).to_int()
} else {
samples.length()
}
let trimmed = if want == samples.length() {
samples
} else {
let out = Array::make(want, 0)
for i in 0.. Bool raise DecodeError {
let meta = parse_metadata(data)
let pcm = decode(data)
md5(pcm.to_data()) == Bytes::from_array(meta.info.md5)
}