#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 total_samples[s],quant_step_size[s],
noise_shift[s],noise_gen_seed[s],filtered[s],
max_matrix_channel[s],matrix_count[s],matrix_params[s],
bypassed_lsbs[s];
OUTPUT filtered,noise_gen_seed[s];
VAR total_samples "total samples";
VAR noise_shift "noise shift";
VAR noise_gen_seed "noise gen seed";
VAR cropped_noise "cropped noise";
VAR noise "noise";
VAR shifted "shifted";
VAR matrix_count "matrix count";
VAR matrix_params "matrix parameters";
VAR out_channel "out channel";
VAR max_matrix_channel "max matrix channel";
VAR matrix_coeff "matrix coefficient";
VAR quant_step_size "quant step size";
VAR bypassed_lsbs "bypassed LSBs";
VAR filtered "filtered";
VAR sum_ "sum";
out_channel[s],matrix_coeff[s] <- matrix_params[s];
for i <- 0 to total_samples[s] /*generate noise channels*/ {
    shifted <- floor(noise_gen_seed[s] / 2 ^ 7) % 2 ^ 16;
    cropped_noise[0][i] <- crop(floor(noise_gen_seed[s] / 2 ^ 15));
    noise[0][i] <- cropped_noise[0][i] * 2 ^ noise_shift[s];
    cropped_noise[1][i] <- crop(shifted);
    noise[1][i] <- cropped_noise[1][i] * 2 ^ noise_shift[s];
    noise_gen_seed[s] <- ((noise_gen_seed[s] * 2 ^ 16) % 2 ^ 32) xor shifted xor (shifted[i] * 2 ^ 5);
}
for m <- 0 to matrix_count[s] {
    o <- out_channel[s][m];
    for i <- 0 to total_samples[s] {
        s[0] <- noise[0][i] * matrix_coeff[s][m][(max_matrix_channel[s] + 1)];
        s[1] <- noise[1][i] * matrix_coeff[s][m][(max_matrix_channel[s] + 2)];
        ;
        sum_ <- s[0] + s[1] +
                sum c <- 0 to max_matrix_channel[s]
                {filtered[s][c][i] * matrix_coeff[s][m][c]};
        if quant_step_size[s][o] == 0 {
            filtered[s][o][i] <- floor(sum_ / 2 ^ 14) + bypassed_lsbs[s][m][i];
        } else {
            filtered[s][o][i] <- floor(
                (floor(sum_ / 2 ^ quant_step_size[s][o]) * 2 ^ quant_step_size[s][o])
              / 2 ^ 14) + bypassed_lsbs[s][m][i];
        }
    }
}
return filtered,noise_gen_seed[s];
