#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 "1 or 2 channels of PCM data",
channel_count, sample_count, bits_per_sample, encoding_parameters;
OUTPUT "uncompressed ALAC frame, frame's size in bits";
VAR encoding_parameters "encoding parameters";
VAR channel "channel";
VAR channel_count "channel count";
VAR sample_count "sample count";
VAR bits_per_sample "bits-per-sample";
VAR minimum_leftweight "minimum leftweight";
VAR maximum_leftweight "maximum leftweight";
VAR interlacing_shift "interlacing shift";
VAR compressed_frame "compressed frame";
VAR compressed_frame_size "compressed frame size";
VAR LSB "LSB";
VAR uncompressed_LSBs "uncompressed LSBs";
VAR shift "shift";
VAR shifted "shifted";
VAR noninterlaced_frame "non-interlaced frame";
VAR noninterlaced_frame_size "non-interlaced frame size";
VAR interlaced_frame "interlaced frame";
VAR interlaced_frame_size "interlaced frame size";
VAR best_interlaced_frame "best interlaced frame";
VAR best_interlaced_frame_size "best interlaced frame size";
FUNC encode_noninterlaced_frame "encode non-interlaced frame"
"alac:write_non_interlaced_frame";
FUNC encode_interlaced_frame "encode interlaced frame"
"alac:write_interlaced_frame";
if bits_per_sample <= 16 {
    uncompressed_LSBs <- 0;
    shifted <- channel;
} else /*if bits-per-sample > 16*/ {
    uncompressed_LSBs <- 1;
    shift <- 2 ^ (bits_per_sample - 16);
    for i <- 0 to sample_count /*store lower bits uncompressed*/ {
        for c <- 0 to channel_count {
            LSB[i * channel_count + c] <- channel[c][i] % shift;
            shifted[c][i] <- floor(channel[c][i] / shift);
        }
    }
}
if channel_count == 1 {
    noninterlaced_frame,noninterlaced_frame_size <-
    encode_noninterlaced_frame(shifted,
                               sample_count,
                               bits_per_sample,
                               uncompressed_LSBs,
                               LSB,
                               encoding_parameters);
    return noninterlaced_frame,noninterlaced_frame_size;
} else {
    minimum_leftweight,
    maximum_leftweight,
    interlacing_shift <- encoding_parameters;
    best_interlaced_frame_size <- infinity;
    for l <- minimum_leftweight to maximum_leftweight + 1 {
        interlaced_frame[l],interlaced_frame_size[l] <-
        encode_interlaced_frame(shifted,
                                sample_count,
                                bits_per_sample,
                                interlacing_shift,
                                l,
                                uncompressed_LSBs,
                                LSB,
                                encoding_parameters);
        if interlaced_frame_size[l] < best_interlaced_frame_size {
            best_interlaced_frame <- interlaced_frame[l];
            best_interlaced_frame_size <- interlaced_frame_size[l];
        }
    }
    return best_interlaced_frame,best_interlaced_frame_size;
}
