Пример #1
0
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;
    }
    
    
}
Пример #2
0
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;
    }
    
    
}