#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 "\"mdat\" atom data",
sample_count,channel_count,bits_per_sample,uncompressed_LSBs,
decoding_parameters;
OUTPUT "1 or 2 channels of PCM data";
VAR sample_count "sample count";
VAR channel_count "channel count";
VAR bits_per_sample "bits-per-sample";
VAR uncompressed_LSBs "uncompressed LSBs";
VAR decoding_parameters "decoding parameters";
VAR sample_size "sample size";
VAR interlacing_shift "interlacing shift";
VAR interlacing_leftweight "interlacing leftweight";
VAR LSB "LSB";
VAR QLP_shift "QLP shift needed";
VAR QLP_coeff_count "QLP coefficient count";
VAR QLP_coeff "QLP coefficient";
VAR residuals "residual";
VAR subframe "subframe";
VAR channel "channel";
FUNC read_subframe_header "read subframe header" "alac:read_subframe_header";
FUNC read_residual "read residual block" "alac:read_residual_block";
FUNC decode_subframe "decode subframe" "alac:decode_subframe";
FUNC decorrelate_channels "decorrelate channels" "alac:decorrelate_channels";
sample_size <- bits_per_sample - (uncompressed_LSBs * 8) + (channel_count - 1);
interlacing_shift <- read 8 unsigned;
interlacing_leftweight <- read 8 unsigned;
for c <- 0 to channel_count {
    QLP_shift[c],QLP_coeff_count[c],QLP_coeff[c] <- read_subframe_header();
}
if uncompressed_LSBs > 0 {
    for i <- 0 to sample_count {
        for c <- 0 to channel_count {
             LSB[c][i] <- read (uncompressed_LSBs * 8) unsigned;
        }
    }
}
for c <- 0 to channel_count {
    residuals[c] <- read_residual(sample_size,
                                  sample_count,
                                  decoding_parameters);
    subframe[c] <- decode_subframe(QLP_shift[c],
                                   QLP_coeff_count[c],
                                   QLP_coeff[c],
                                   residuals[c],
                                   sample_size,
                                   sample_count);
}
if (channel_count == 2) and (interlacing_leftweight > 0) {
     channel[0],channel[1] <- decorrelate_channels(subframe[0],
                                                   subframe[1],
                                                   sample_count,
                                                   interlacing_shift,
                                                   interlacing_leftweight);
} else {
    for c <- 0 to channel_count {
        channel[c] <- subframe[c];
    }
}
if uncompressed_LSBs > 0 {
    for i <- 0 to sample_count {
        for c <- 0 to channel_count {
             channel[c][i] <-
                 (channel[c][i] * 2 ^ uncompressed_LSBs) + LSB[c][i];
        }
    }
}
return channel;
