#This work is licensed under the
#Creative Commons Attribution-Share Alike 3.0 United States License.
#To view a copy of this license, visit
#http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
#Creative Commons,
#171 Second Street, Suite 300,
#San Francisco, California, 94105, USA.

INPUT "the FLAC file stream",block_size,subframe_bps;
OUTPUT "decoded signed PCM samples";
VAR block_size "block size";
VAR subframe_bps "subframe's bits-per-sample";
VAR type_order "subframe type and order";
VAR has_wasted_bps "has wasted BPS";
VAR wasted_bps "wasted BPS";
VAR sample "sample";
FUNC undefined_subframe_type "undefined subframe type error";
FUNC decode_constant "decode CONSTANT subframe" "flac:decode_constant";
FUNC decode_verbatim "decode VERBATIM subframe" "flac:decode_verbatim";
FUNC decode_fixed "decode FIXED subframe" "flac:decode_fixed";
FUNC decode_lpc "decode LPC subframe" "flac:decode_lpc";
skip 1;
type_order <- read 6 unsigned;
has_wasted_bps <- read 1 unsigned;
if (has_wasted_bps == 1) {
    wasted_bps <- (read unary 1) + 1;
} else {
    wasted_bps <- 0;
}
if (type_order == 0) {
    sample <- decode_constant(block_size, subframe_bps - wasted_bps);
} elif (type_order == 1) {
    sample <- decode_verbatim(block_size, subframe_bps - wasted_bps);
} elif (8 <= type_order <= 12) {
    sample <- decode_fixed(block_size,
                           subframe_bps - wasted_bps,
                           type_order - 8);
} elif (32 <= type_order <= 63) {
    sample <- decode_lpc(block_size,
                         subframe_bps - wasted_bps,
                         type_order - 31);
} else {
    undefined_subframe_type();
}
if (has_wasted_bps == 1) /*prepend wasted bits to each sample*/ {
    for i <- 0 to block_size {
        sample[i] <- sample[i] * 2 ^ wasted_bps;
    }
}
return sample;
