#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 block_samples,correlated,decorrelation_term,decorrelation_delta,
decorrelation_weight,decorrelation_samples;
OUTPUT decorrelated;
VAR block_samples "block samples";
VAR correlated "correlated";
VAR decorrelated "decorrelated";
VAR temp "temp";
VAR decorrelation_term "decorrelation term";
VAR decorrelation_delta "decorrelation delta";
VAR decorrelation_weight "decorrelation weight";
VAR decorrelation_samples "decorrelation samples";
FUNC invalid_term "invalid decorrelation term";
FUNC update_weight "update weight" "wavpack:update_weight";
if 17 <= decorrelation_term <= 18 {
    decorrelated[-2] <- decorrelation_samples[1] /*not returned*/;
    decorrelated[-1] <- decorrelation_samples[0] /*not returned*/;
    for i <- 0 to block_samples {
        if decorrelation_term == 18 {
            temp[i] <-
                floor((3 * decorrelated[i - 1] - decorrelated[i - 2]) / 2);
        } elif decorrelation_term == 17 {
            temp[i] <- 2 * decorrelated[i - 1] - decorrelated[i - 2];
        }

        decorrelated[i] <- floor((decorrelation_weight * temp[i] + 2 ^ 9) /
                                 2 ^ 10) + correlated[i];
        decorrelation_weight <- update_weight(temp[i],
                                              correlated[i],
                                              decorrelation_weight,
                                              decorrelation_delta);
    }
} elif 1 <= decorrelation_term <= 8 {
    for i <- 0 to decorrelation_term {
        decorrelated[i - decorrelation_term] <-
            decorrelation_samples[i] /*not returned*/;
    }
    for i <- 0 to block_samples {
        decorrelated[i] <- floor((decorrelation_weight *
                                  decorrelated[i - decorrelation_term] +
                                  2 ^ 9) / 2 ^ 10) + correlated[i];
        decorrelation_weight <- update_weight(
            decorrelated[i - decorrelation_term],
            correlated[i],
            decorrelation_weight,
            decorrelation_delta);
    }
} else {
   invalid_term();
}
return decorrelated;
