Пример #1
0
    void DecoderIrregular::setChannelPosition(unsigned int index, double azimuth)
    {
        long    number_of_virutal_channels;
        double  current_distance, minimum_distance;
        
        Planewaves::setChannelPosition(index, azimuth);
        
        // Sort the channels azimuth
        memcpy(m_channels_azimuth_sorted, m_channels_azimuth, m_number_of_channels * sizeof(double));
        std::sort(m_channels_azimuth_sorted, m_channels_azimuth_sorted+m_number_of_channels);

        // Get the minimum distance between the channels
        minimum_distance    = HOA_2PI + 1;
        current_distance    = distance_radian(m_channels_azimuth_sorted[0], m_channels_azimuth_sorted[m_number_of_channels-1]);
        if(current_distance < minimum_distance)
            minimum_distance    = current_distance;
        for(unsigned int i = 1; i < m_number_of_channels; i++)
        {
            current_distance  = distance_radian(m_channels_azimuth_sorted[i], m_channels_azimuth_sorted[i-1]);
            if(current_distance < minimum_distance)
                minimum_distance = current_distance;
        }
        
        // Get the optimal number of virtual channels
        // Always prefer the number of harmonics + 2
        number_of_virutal_channels = (HOA_2PI / minimum_distance);
        if(number_of_virutal_channels < m_number_of_harmonics + 2)
        {
            number_of_virutal_channels = m_number_of_harmonics + 2;
        }
        
        for(unsigned int i = 0; i < m_number_of_channels * m_number_of_harmonics; i++)
        {
            m_decoder_matrix_sorted[i]  = 0;
            m_decoder_matrix[i] = 0;
        }
        
        // Compute the decoding matrix for sorted channels
        for(unsigned int i = 0; i < number_of_virutal_channels; i++)
        {
            long   channel_index1 = 0, channel_index2 = 0;
            double factor_index1 = 0, factor_index2 = 0;
            // Get the pair of real channels corresponding to the virtual channel
            double angle = (double)i / (double)number_of_virutal_channels * HOA_2PI;
            
            for(unsigned int j = 0; j < m_number_of_channels; j++)
            {
                if(j < m_number_of_channels-1 && angle >= m_channels_azimuth_sorted[j] && angle <= m_channels_azimuth_sorted[j+1])
                {
                    channel_index1 = j;
                    channel_index2 = j+1;
                    
                    // Get the factor for the pair of real channels
                    double distance_index1 = angle - m_channels_azimuth_sorted[j];
                    double distance_index2 = m_channels_azimuth_sorted[j+1] - angle;
                    double distance_ratio = distance_index1 + distance_index2;
                    factor_index1   = cos(distance_index1 / (distance_ratio) * HOA_PI);
                    factor_index2   = cos(distance_index2 / (distance_ratio) * HOA_PI);
                    break;
                }
                else
                {
                    channel_index1 = j;
                    channel_index2 = 0;
                        
                    // Get the factor for the pair of real channels
                    double distance_index1 = angle - m_channels_azimuth_sorted[j];
                    double distance_index2 = (m_channels_azimuth_sorted[0] + HOA_2PI) - angle;
                    double distance_ratio = distance_index1 + distance_index2;
                    factor_index1   = cos(distance_index1 / (distance_ratio) * HOA_PI);
                    factor_index2   = cos(distance_index2 / (distance_ratio) * HOA_PI);
                    break;
                }
            }
            
            // Get the harmonics coefficients for virtual channel
            m_encoder->setAzimuth(angle);
            m_encoder->process(1., m_harmonics_vector);
            
            m_decoder_matrix_sorted[channel_index1 * m_number_of_harmonics] += (0.5 / (double)(m_order + 1.)) * factor_index1;
            m_decoder_matrix_sorted[channel_index2 * m_number_of_harmonics] += (0.5 / (double)(m_order + 1.)) * factor_index2;
            for(unsigned int j = 1; j < m_number_of_harmonics; j++)
            {
                m_decoder_matrix_sorted[channel_index1 * m_number_of_harmonics + j] += (m_harmonics_vector[j] / (double)(m_order + 1.)) * factor_index1;
                m_decoder_matrix_sorted[channel_index2 * m_number_of_harmonics + j] += (m_harmonics_vector[j] / (double)(m_order + 1.)) * factor_index2;
            }
        }
        
        // Copy the decoding matrix for sorted channels to the decoding matrix for unsorted channels
        for(unsigned int i = 0; i < m_number_of_channels; i++)
        {
            for(unsigned int j = 0; j < m_number_of_channels; j++)
            {
                if(m_channels_azimuth[i] == m_channels_azimuth_sorted[j])
                {
                    for(unsigned int k = 0; k < m_number_of_harmonics; k++)
                    {
                        m_decoder_matrix_float[i * m_number_of_harmonics + k] = m_decoder_matrix[i * m_number_of_harmonics + k] = m_decoder_matrix_sorted[j * m_number_of_harmonics + k];
                    }
                }
            }
        }
    }
Пример #2
0
    void DecoderIrregular::setChannelAzimuth(unsigned int index, double azimuth)
    {
        double  current_distance, minimum_distance;

        Planewaves::setChannelAzimuth(index, azimuth);

        // Get the minimum distance between the channels
        minimum_distance    = HOA_2PI + 1;
        current_distance    = distance_radian(m_channels_azimuth[0], m_channels_azimuth[m_number_of_channels-1]);
        if(current_distance < minimum_distance)
            minimum_distance    = current_distance;
        for(unsigned int i = 1; i < m_number_of_channels; i++)
        {
            current_distance  = distance_radian(m_channels_azimuth[i], m_channels_azimuth[i-1]);
            if(current_distance < minimum_distance)
                minimum_distance = current_distance;
        }

        // Get the optimal number of virtual channels
        // Always prefer the number of harmonics + 1
        if(minimum_distance > 0)
            m_number_of_virtual_channels = (HOA_2PI / minimum_distance);
        else
            m_number_of_virtual_channels = m_number_of_harmonics + 1;
        if(m_number_of_virtual_channels < m_number_of_harmonics + 1)
        {
            m_number_of_virtual_channels = m_number_of_harmonics + 1;
        }
        
        if(m_nearest_channel[0] && m_nearest_channel[1])
        {
            delete [] m_nearest_channel[0];
            delete [] m_nearest_channel[1];
        }
        m_nearest_channel[0] = new unsigned int[m_number_of_virtual_channels];
        m_nearest_channel[1] = new unsigned int[m_number_of_virtual_channels];
        
        for(unsigned int i = 0; i < m_number_of_channels * m_number_of_harmonics; i++)
        {
            m_decoder_matrix[i] = 0.;
            m_decoder_matrix_float[i] = 0.;
        }

        if(m_number_of_channels == 1)
        {
            for(unsigned int i = 0; i < m_number_of_virtual_channels; i++)
            {
                double angle = (double)i / (double)m_number_of_virtual_channels * HOA_2PI;
                m_encoder->setAzimuth(angle + m_offset);
                m_encoder->process(1., m_harmonics_vector);

                m_decoder_matrix[0] += (0.5 / (double)(m_order + 1.));
                for(unsigned int j = 1; j < m_number_of_harmonics; j++)
                {
                    m_decoder_matrix[j] += (m_harmonics_vector[j] / (double)(m_order + 1.));
                }
            }
            for(unsigned int i = 0; i < m_number_of_harmonics; i++)
            {
                m_decoder_matrix_float[i] = m_decoder_matrix[i];
            }
        }
        else if(m_number_of_channels == 2)
        {
            for(unsigned int i = 0; i < m_number_of_virtual_channels; i++)
            {
                double factor_index1 = 0, factor_index2 = 0;
                double angle = (double)i / (double)m_number_of_virtual_channels * HOA_2PI;
                m_encoder->setAzimuth(angle + m_offset);
                m_encoder->process(1., m_harmonics_vector);

                m_decoder_matrix[0] += (0.5 / (double)(m_order + 1.));
                m_decoder_matrix[m_number_of_harmonics] += (0.5 / (double)(m_order + 1.));

                factor_index1 = fabs(cos(distance_radian(angle, m_channels_azimuth[0]) / HOA_PI * HOA_PI2));
                factor_index2 = fabs(cos(distance_radian(angle, m_channels_azimuth[1]) / HOA_PI * HOA_PI2));
                for(unsigned int j = 1; j < m_number_of_harmonics; j++)
                {
                    m_decoder_matrix[j] += (m_harmonics_vector[j] / (double)(m_order + 1.)) * factor_index1;

                    m_decoder_matrix[m_number_of_harmonics + j] += (m_harmonics_vector[j] / (double)(m_order + 1.)) * factor_index2;
                }
            }


            for(unsigned int i = 0; i < m_number_of_channels * m_number_of_harmonics; i++)
            {
                m_decoder_matrix_float[i] = m_decoder_matrix[i];
            }
        }
        else
        {
            // Get the nearest channels
            for(unsigned int i = 0; i < m_number_of_virtual_channels; i++)
            {
                long   channel_index1 = 0, channel_index2 = 0;
                double distance1 = HOA_2PI, distance2 = HOA_2PI;
                double angle = (double)i / (double)m_number_of_virtual_channels * HOA_2PI;
                double factor_index1 = 0, factor_index2 = 0;
                
                for(unsigned int j = 0; j < m_number_of_channels; j++)
                {
                    if(radianClosestDistance(m_channels_azimuth[j], angle) < distance1)
                    {
                        distance1 = radianClosestDistance(m_channels_azimuth[j], angle);
                        channel_index1 = j;
                    }
                }
                
                for(unsigned int j = 0; j < m_number_of_channels; j++)
                {
                    if(radianClosestDistance(m_channels_azimuth[j], angle) < distance2 && j != channel_index1)
                    {
                        distance2 = radianClosestDistance(m_channels_azimuth[j], angle);
                        channel_index2 = j;
                    }
                }
                
                if(fabs(distance1 - distance2) < HOA_PI / (double)m_number_of_virtual_channels)
                {
                    double angle1 = m_channels_azimuth[channel_index1], angle2 = m_channels_azimuth[channel_index2];
                    double distance_index1 = radianClosestDistance(angle, angle1);
                    double distance_index2 = radianClosestDistance(angle, angle2);
                    double distance_ratio = distance_index1 + distance_index2;
                    factor_index1   = cos(distance_index1 / (distance_ratio) * HOA_PI2);
                    factor_index2   = cos(distance_index2 / (distance_ratio) * HOA_PI2);
                }
                else
                {
                    factor_index1   = 1;
                    factor_index2   = 0;
                }
                
                // Get the harmonics coefficients for the virtual channel
                m_encoder->setAzimuth(angle + m_offset);
                m_encoder->process(1., m_harmonics_vector);
                
                m_decoder_matrix[channel_index1 * m_number_of_harmonics] += (0.5 / (double)(m_order + 1.)) * factor_index1;
                m_decoder_matrix[channel_index2 * m_number_of_harmonics] += (0.5 / (double)(m_order + 1.)) * factor_index2;
                for(unsigned int j = 1; j < m_number_of_harmonics; j++)
                {
                    m_decoder_matrix[channel_index1 * m_number_of_harmonics + j] += (m_harmonics_vector[j] / (double)(m_order + 1.)) * factor_index1;
                    m_decoder_matrix[channel_index2 * m_number_of_harmonics + j] += (m_harmonics_vector[j] / (double)(m_order + 1.)) * factor_index2;
                }
            }

            for(unsigned int i = 0; i < m_number_of_channels * m_number_of_harmonics; i++)
            {
                m_decoder_matrix_float[i] = m_decoder_matrix[i];
            }
        }
    }