void Ambix_directional_loudnessAudioProcessor::calcParams() { if (!_initialized) { sph_h.Init(AMBI_ORDER); const String t_design_txt (t_design::des_3_240_21_txt); // std::cout << t_design_txt << std::endl; String::CharPointerType lineChar = t_design_txt.getCharPointer(); int n = 0; // how many characters been read int numsamples = 0; int i = 0; int curr_n = 0; int max_n = lineChar.length(); while (curr_n < max_n) { // check how many coordinates we have double value; sscanf(lineChar, "%lf\n%n", &value, &n); lineChar += n; curr_n += n; numsamples++; } // end parse numbers numsamples = numsamples/3; // xyz Carth_coord.resize(numsamples,3); // positions in cartesian coordinates curr_n = 0; lineChar = t_design_txt.getCharPointer(); // parse line for numbers again and copy to carth coordinate matrix while (i < numsamples) { double x,y,z; sscanf(lineChar, "%lf%lf%lf%n", &x, &y, &z, &n); Carth_coord(i,0) = x; Carth_coord(i,1) = y; Carth_coord(i,2) = z; lineChar += n; curr_n += n; i++; } // end parse numbers // std::cout << "Coordinate size: " << Carth_coord.rows() << " x " << Carth_coord.cols() << std::endl; // std::cout << Carth_coord << std::endl; Sph_coord.resize(numsamples,2); // positions in spherical coordinates Sh_matrix.setZero(numsamples,AMBI_CHANNELS); for (int i=0; i < numsamples; i++) { Eigen::VectorXd Ymn(AMBI_CHANNELS); // Ymn result Sph_coord(i,0) = atan2(Carth_coord(i,1),Carth_coord(i,0)); // azimuth Sph_coord(i,1) = atan2(Carth_coord(i,2),sqrt(Carth_coord(i,0)*Carth_coord(i,0) + Carth_coord(i,1)*Carth_coord(i,1))); // elevation sph_h.Calc(Sph_coord(i,0),Sph_coord(i,1)); // phi theta sph_h.Get(Ymn); // std::cout << "Size: " << Ymn.size() << ": " << Ymn << std::endl; //Sh_matrix.row(i) = Ymn; Sh_matrix.block(i,0,1,AMBI_CHANNELS) = Ymn.transpose(); // std::cout << "Size: " << Sh_matrix.block(i,0,1,in_ambi_channels).size() << ": " << Sh_matrix.block(i,0,1,in_ambi_channels) << std::endl; } // Sh_matrix_inv.setZero(); //Sh_matrix_inv = (Sh_matrix.transpose()*Sh_matrix).inverse()*Sh_matrix.transpose(); // not working for dynamic input order // if input order is different a better solving has to be used for the inverse: Sh_matrix_inv = (Sh_matrix.transpose()*Sh_matrix).colPivHouseholderQr().inverse()*Sh_matrix.transpose(); // std::cout << "Size: " << Sh_matrix_inv.rows() << " x " << Sh_matrix_inv.cols() << std::endl; // std::cout << Sh_matrix_inv << std::endl; _initialized = true; } if (_param_changed) { // convert parameters to values for the filter // ArrayIntParam _shape = shape; ArrayParam _width = width * (float)M_PI; // 0...pi ArrayParam _height = height * (float)M_PI; ArrayParam _gain; for (int i=0; i < gain.rows();i++) { _gain(i) = ParamToRMS(gain(i)); } SphCoordParam _center_sph = (center_sph - 0.5f)*2.f*(float)M_PI; // std::cout << _center_sph << std::endl; CarthCoordParam _center_carth; // convert center spherical coordinates to carthesian for (int i=0; i < _center_sph.rows(); i++) { _center_carth(i,0) = cos(_center_sph(i,0))*cos(_center_sph(i,1)); // x _center_carth(i,1) = sin(_center_sph(i,0))*cos(_center_sph(i,1)); // y _center_carth(i,2) = sin(_center_sph(i,1)); // z } // scale the SH_matrix and save as Sh_matrix_mod Sh_matrix_mod = Sh_matrix; // iterate over all sample points for (int i=0; i < Sh_matrix_mod.rows(); i++) { double multipl = 1.f; // iterate over all filters for (int k=0; k < NUM_FILTERS; k++) { Eigen::Vector2d Sph_coord_vec = Sph_coord.row(i); Eigen::Vector2d _center_sph_vec = _center_sph.row(k); multipl *= (double)sph_filter.GetWeight(&Sph_coord_vec, Carth_coord.row(i), &_center_sph_vec, _center_carth.row(k), (int)shape(k), _width(k), _height(k), _gain(k), (window(k) > 0.5f), transition(k)); } Sh_matrix_mod.row(i) *= multipl; } // calculate new transformation matrix Sh_transf = Sh_matrix_inv * Sh_matrix_mod; // threshold coefficients for (int i = 0; i < Sh_transf.size(); i++) { if (abs(Sh_transf(i)) < 0.00001f) Sh_transf(i) = 0.f; } _param_changed = false; } }
void Ambix_vmicAudioProcessor::calcParams() { if (!_initialized) { sph_h.Init(AMBI_ORDER); const String t_design_txt (t_design::des_3_240_21_txt); // std::cout << t_design_txt << std::endl; String::CharPointerType lineChar = t_design_txt.getCharPointer(); int n = 0; // how many characters been read int numsamples = 0; int i = 0; int curr_n = 0; int max_n = lineChar.length(); while (curr_n < max_n) { // check how many coordinates we have double value; sscanf(lineChar, "%lf\n%n", &value, &n); lineChar += n; curr_n += n; numsamples++; } // end parse numbers numsamples = numsamples/3; // xyz Carth_coord.resize(numsamples,3); // positions in cartesian coordinates curr_n = 0; lineChar = t_design_txt.getCharPointer(); // parse line for numbers again and copy to carth coordinate matrix while (i < numsamples) { double x,y,z; sscanf(lineChar, "%lf%lf%lf%n", &x, &y, &z, &n); Carth_coord(i,0) = x; Carth_coord(i,1) = y; Carth_coord(i,2) = z; lineChar += n; curr_n += n; i++; } // end parse numbers // std::cout << "Coordinate size: " << Carth_coord.rows() << " x " << Carth_coord.cols() << std::endl; // std::cout << Carth_coord << std::endl; Sph_coord.resize(numsamples,2); // positions in spherical coordinates Sh_matrix.setZero(numsamples,AMBI_CHANNELS); for (int i=0; i < numsamples; i++) { Eigen::VectorXd Ymn(AMBI_CHANNELS); // Ymn result Sph_coord(i,0) = atan2(Carth_coord(i,1),Carth_coord(i,0)); // azimuth Sph_coord(i,1) = atan2(Carth_coord(i,2),sqrt(Carth_coord(i,0)*Carth_coord(i,0) + Carth_coord(i,1)*Carth_coord(i,1))); // elevation sph_h.Calc(Sph_coord(i,0),Sph_coord(i,1)); // phi theta sph_h.Get(Ymn); Sh_matrix.block(i,0,1,AMBI_CHANNELS) = Ymn.transpose(); } _initialized = true; } if (_param_changed) { // convert parameters to values for the filter // ArrayIntParam _shape = shape; ArrayParam _width = width * (float)M_PI; // 0...pi ArrayParam _height = height * (float)M_PI; ArrayParam _gain; for (int i=0; i < gain.rows();i++) { _gain(i) = ParamToRMS(gain(i)); } SphCoordParam _center_sph = (center_sph - 0.5f)*2.f*M_PI; // std::cout << _center_sph << std::endl; CarthCoordParam _center_carth; // convert center spherical coordinates to carthesian for (int i=0; i < _center_sph.rows(); i++) { _center_carth(i,0) = cos(_center_sph(i,0))*cos(_center_sph(i,1)); // x _center_carth(i,1) = sin(_center_sph(i,0))*cos(_center_sph(i,1)); // y _center_carth(i,2) = sin(_center_sph(i,1)); // z } Sh_matrix_mod.setZero(); // iterate over all filters for (int k=0; k < NUM_FILTERS_VMIC; k++) { // copy the SH_matrix to Eigen::MatrixXd Sh_matrix_temp = Sh_matrix; // iterate over all sample points for (int i=0; i < Sh_matrix_temp.rows(); i++) { Eigen::Vector2d Sph_coord_vec = Sph_coord.row(i); Eigen::Vector2d _center_sph_vec = _center_sph.row(k); double multipl = sph_filter.GetWeight(&Sph_coord_vec, Carth_coord.row(i), &_center_sph_vec, _center_carth.row(k), (int)floor(shape(k)+0.5f), _width(k), _height(k), 1, true, transition(k)); if (multipl < 0.f) // -1.f in case of outside region multipl = 0.f; Sh_matrix_temp.row(i) *= multipl; } // Sh_matrix_mod row is the sum over the columns Sh_matrix_mod.row(k) = Sh_matrix_temp.colwise().sum(); // normalize and apply gain if (Sh_matrix_mod.row(k)(0) > 0.f) Sh_matrix_mod.row(k) *= 1/Sh_matrix_mod.row(k)(0)*_gain(k); } // std::cout << "Size Sh_matrix_mod : " << Sh_matrix_mod.rows() << " x " << Sh_matrix_mod.cols() << std::endl; // std::cout << Sh_matrix_mod << std::endl; // this is the new transformation matrix Sh_transf = Sh_matrix_mod; // threshold coefficients for (int i = 0; i < Sh_transf.size(); i++) { if (abs(Sh_transf(i)) < 0.00001f) Sh_transf(i) = 0.f; } _param_changed = false; } }