use crate::graph::MAX_BLOCK_INPUTS;
pub fn compute_matrix(order: usize) -> [[f64; MAX_BLOCK_INPUTS]; 2] {
let mut matrix = [[0.0; MAX_BLOCK_INPUTS]; 2];
match order {
1 => compute_foa_matrix(&mut matrix),
2 => compute_soa_matrix(&mut matrix),
3 => compute_toa_matrix(&mut matrix),
_ => panic!("Ambisonic order must be 1, 2, or 3"),
}
normalize_matrix(&mut matrix, order);
matrix
}
fn compute_foa_matrix(matrix: &mut [[f64; MAX_BLOCK_INPUTS]; 2]) {
matrix[0][0] = 0.5; matrix[0][1] = 0.5; matrix[0][2] = 0.1; matrix[0][3] = 0.35;
matrix[1][0] = 0.5; matrix[1][1] = -0.5; matrix[1][2] = 0.1; matrix[1][3] = 0.35; }
fn compute_soa_matrix(matrix: &mut [[f64; MAX_BLOCK_INPUTS]; 2]) {
matrix[0][0] = 0.45; matrix[0][1] = 0.45; matrix[0][2] = 0.09; matrix[0][3] = 0.32;
matrix[1][0] = 0.45;
matrix[1][1] = -0.45;
matrix[1][2] = 0.09;
matrix[1][3] = 0.32;
matrix[0][4] = 0.25; matrix[0][5] = 0.08; matrix[0][6] = 0.05; matrix[0][7] = 0.08; matrix[0][8] = 0.15;
matrix[1][4] = -0.25; matrix[1][5] = 0.08;
matrix[1][6] = 0.05;
matrix[1][7] = 0.08;
matrix[1][8] = 0.15;
}
fn compute_toa_matrix(matrix: &mut [[f64; MAX_BLOCK_INPUTS]; 2]) {
let left: [f64; 16] = [
0.42, 0.42, 0.08, 0.30, 0.22, 0.07, 0.04, 0.07, 0.13, 0.15, 0.10, 0.05, 0.03, 0.05, 0.10, 0.10,
];
let right: [f64; 16] = [
0.42, -0.42, 0.08, 0.30, -0.22, 0.07, 0.04, 0.07, 0.13, -0.15, -0.10, 0.05, 0.03, 0.05, -0.10, 0.10,
];
matrix[0].copy_from_slice(&left);
matrix[1].copy_from_slice(&right);
}
fn normalize_matrix(matrix: &mut [[f64; MAX_BLOCK_INPUTS]; 2], order: usize) {
let energy_scale = 1.0 / 2.0_f64.sqrt();
let num_channels = (order + 1) * (order + 1);
for ear_coeffs in matrix.iter_mut() {
for coeff in ear_coeffs.iter_mut().take(num_channels) {
*coeff *= energy_scale;
}
}
}