#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 "previously decoded samples",offset,command,block_length;
OUTPUT samples;
VAR command "command";
VAR block_length "block length";
VAR samples "samples";
VAR energy "energy";
VAR residual "residual";
VAR offset "offset";
FUNC read_unsigned "read unsigned" "shorten:read_unsigned";
FUNC read_signed "read signed" "shorten:read_signed";
FUNC process_qlpc_command "process QLPC command"
"shorten:process_qlpc_command";
switch command {
    case 0 /*DIFF0 command*/ {
        energy <- read_unsigned(3);
        for i <- 0 to block_length {
            residual[i] <- read_signed(energy);
            samples[i] <- offset + residual[i];
        }
    }
    case 1 /*DIFF1 command*/ {
        energy <- read_unsigned(3);
        for i <- 0 to block_length {
            residual[i] <- read_signed(energy);
            samples[i] <- samples[i - 1] + residual[i];
        }
    }
    case 2 /*DIFF2 command*/ {
        energy <- read_unsigned(3);
        for i <- 0 to block_length {
            residual[i] <- read_signed(energy);
            samples[i] <- (2 * samples[i - 1]) - samples[i - 2] + residual[i];
        }
    }
    case 3 /*DIFF3 command*/ {
        energy <- read_unsigned(3);
        for i <- 0 to block_length {
            residual[i] <- read_signed(energy);
            samples[i] <- (3 * (samples[i - 1] - samples[i - 2])) +
                          samples[i - 3] + residual[i];
        }
    }
    case 7 /*QLPC command*/ {
        samples <- process_qlpc_command(samples,
                                        offset,
                                        block_length);
    }
    case 8 /*ZERO command*/ {
        for i <- 0 to block_length {
            samples[i] <- 0;
        }
    }
}
return samples;
