#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",
max_block_size,
streaminfo_sample_rate,
streaminfo_bps;
OUTPUT "decoded PCM samples";
VAR max_block_size "maximum block size";
VAR streaminfo_sample_rate "STREAMINFO sample rate";
VAR streaminfo_bps "STREAMINFO bits-per-sample";
VAR block_size "block size";
VAR sample_rate "sample rate";
VAR bps "bits-per-sample";
VAR channel_count "channel count";
VAR channel_assignment "channel assignment";
VAR subframe "subframe";
VAR crc16 "CRC-16";
VAR samples "samples";
VAR ch8 "front left, difference";
VAR ch9 "difference, front right";
VAR ch10 "average, difference";
FUNC read_frame_header "read frame header" "flac:read_frame_header";
FUNC decode_subframe "decode subframe" "flac:decode_subframe";
FUNC byte_align "byte align the stream";
FUNC verify_checksum "verify frame's checksum" "flac:verify_crc16";
FUNC recombine_subframes "recombine subframes" "flac:recombine_subframes";

block_size,sample_rate,bps,channel_count,channel_assignment <-
read_frame_header(max_block_size,
streaminfo_sample_rate,
streaminfo_bps);
for c <- 0 to channel_count {
    /*difference channel has 1 more bit-per-sample*/;
    if (channel_assignment == ch8) and (c == 1) {
        subframe[c] <- decode_subframe(block_size,bps + 1);
    } elif (channel_assignment == ch9) and (c == 0) {
        subframe[c] <- decode_subframe(block_size,bps + 1);
    } elif (channel_assignment == ch10) and (c == 1) {
        subframe[c] <- decode_subframe(block_size,bps + 1);
    } else {
        subframe[c] <- decode_subframe(block_size,bps);
    }
}
;
byte_align();
crc16 <- read 16 unsigned;
verify_checksum(crc16);
samples <- recombine_subframes(block_size,
                               channel_count,
                               channel_assignment,
                               subframe);
return block_size,samples;
