#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",
total_samples,
block_index,
bits_per_sample,
sample_rate,
channel_count,
block_samples,
cross_channel_decorrelation,
initial_block,
final_block,
decorrelation_term_count,
decorrelation_terms,
decorrelation_deltas,
decorrelation_weights,
decorrelation_samples;
OUTPUT "a WavPack block",decorrelation_weights,decorrelation_samples;
VAR bits_per_sample "bits-per-sample";
VAR sample_rate "sample rate";
VAR initial_block "initial block";
VAR final_block "final block";
VAR block_index "block index";
VAR total_samples "total samples";
VAR channel "channel";
VAR shifted "shifted";
VAR mid_side "mid/side";
VAR block_samples "block samples";
VAR cross_channel_decorrelation "cross-channel decorrelation";
VAR channel_count "channel count";
VAR mono_output "mono output";
VAR false_stereo "false stereo";
VAR effective_channel_count "effective channel count";
VAR sub_block_count "sub block count";
VAR sub_block "sub block";
VAR sub_block_size "sub block size";
VAR total_sub_block_size "total sub block size";
VAR maximum_magnitude "maximum magnitude";
VAR wasted_bps "wasted BPS";
VAR CRC "CRC";
VAR entropies "entropies";
VAR decorrelation_term_count "term count";
VAR decorrelation_terms "terms";
VAR decorrelation_deltas "deltas";
VAR decorrelation_weights "weights";
VAR decorrelation_samples "samples";
VAR wavpack_block "WavPack block";
FUNC calculate_maximum_magnitude "calculate maximum magnitude"
"wavpack:calc_maximum_magnitude";
FUNC calculate_wasted_bps "calculated wasted bits-per-sample"
"wavpack:calc_wasted_bps";
FUNC apply_joint_stereo "apply joint stereo"
"wavpack:calc_joint_stereo";
FUNC write_block_parameters "write block parameters"
"wavpack:write_block_parameters";
FUNC write_block_header "write block header" "wavpack:write_block_header";
if (channel_count == 1) or (channel[0] == channel[1]) {
    if channel_count == 1 {
        mono_output <- 1;
        false_stereo <- 0;
    } else {
        mono_output <- 0;
        false_stereo <- 1;
    }
    effective_channel_count <- 1;
} else {
    mono_output,false_stereo <- 0;
    effective_channel_count <- 2;
}
maximum_magnitude <- calculate_maximum_magnitude(channel,
                                                 effective_channel_count,
                                                 block_samples);
wasted_bps <- calculate_wasted_bps(channel,
                                   effective_channel_count,
                                   block_samples);
for c <- 0 to effective_channel_count {
    for i <- 0 to block_samples {
        shifted[c][i] <- floor(channel[c][i] / 2 ^ wasted_bps);
    }
}
if effective_channel_count == 2 {
    mid_side <- apply_joint_stereo(shifted, block_samples);
} else {
    mid_side <- shifted;
}
sub_block_count,
sub_block_size,
sub_block,
entropies,
decorrelation_weights,
decorrelation_samples <- write_block_parameters(
    mid_side,
    effective_channel_count,
    block_samples,
    entropies,
    decorrelation_term_count,
    decorrelation_terms,
    decorrelation_deltas,
    decorrelation_weights,
    decorrelation_samples);
total_sub_block_size <- sum i <- 0 to sub_block_count - 1 {sub_block_size[i]};
write_block_header(total_sub_block_size,
                   total_samples,
                   block_index,
                   block_samples,
                   bits_per_sample,
                   mono_output,
                   effective_channel_count == 2,
                   cross_channel_decorrelation,
                   wasted_bps > 0,
                   initial_block,
                   final_block,
                   maximum_magnitude,
                   sample_rate,
                   false_stereo,
                   CRC);
for i <- 0 to sub_block_count {
    sub_block[i] -> write sub_block_size[i] bytes;
}
return wavpack_block,
decorrelation_weights,
decorrelation_samples;
