Commit 17f468a6 authored by Dominik Weckbecker's avatar Dominik Weckbecker 💬
Browse files

optimize DirAC parameter estimation in the encoder

parent 724771bf
Loading
Loading
Loading
Loading
+122 −71
Original line number Diff line number Diff line
@@ -867,7 +867,7 @@ void calculate_hodirac_sector_parameters(
{
    int16_t i_sec, i_bin, i_band;

    float p_real, p_imag, normI, energy, theta, phi, tmp_diff;
    float p_real, p_imag, normI, energy, tmp_diff;
    float sec_w_real[NUM_ANA_SECTORS];
    float sec_x_real[NUM_ANA_SECTORS];
    float sec_y_real[NUM_ANA_SECTORS];
@@ -907,115 +907,166 @@ void calculate_hodirac_sector_parameters(
        float *p_sec_y_imag = &sec_y_imag[i_sec];
        float *p_sec_z_imag = &sec_z_imag[i_sec];

        float *p_sec_I_vec_x = &sec_I_vec_x[i_sec];
        float *p_sec_I_vec_y = &sec_I_vec_y[i_sec];
        float *p_sec_I_vec_z = &sec_I_vec_z[i_sec];

        const float *p_c_weights = c_weights;

        float *p_ImagBuffer_0 = ImagBuffer[0];
        float *p_ImagBuffer_1 = ImagBuffer[1];
        float *p_ImagBuffer_2 = ImagBuffer[2];
        float *p_ImagBuffer_3 = ImagBuffer[3];
        float *p_ImagBuffer_4 = ImagBuffer[4];
        float *p_ImagBuffer_5 = ImagBuffer[5];
        float *p_ImagBuffer_6 = ImagBuffer[6];
        float *p_ImagBuffer_8 = ImagBuffer[8];

        float *p_RealBuffer_0 = RealBuffer[0];
        float *p_RealBuffer_1 = RealBuffer[1];
        float *p_RealBuffer_2 = RealBuffer[2];
        float *p_RealBuffer_3 = RealBuffer[3];
        float *p_RealBuffer_4 = RealBuffer[4];
        float *p_RealBuffer_5 = RealBuffer[5];
        float *p_RealBuffer_6 = RealBuffer[6];
        float *p_RealBuffer_8 = RealBuffer[8];

        for ( i_band = enc_param_start_band; i_band < N_bands; i_band++ )
        {
            sec_I_vec_x[i_sec] = 0.f;
            sec_I_vec_y[i_sec] = 0.f;
            sec_I_vec_z[i_sec] = 0.f;
            float *p_azi = &azi[i_sec * N_bands + i_band];
            float *p_ele = &ele[i_sec * N_bands + i_band];
            float *p_ene = &ene[i_sec * N_bands + i_band];

            float *p_diff = &diff[i_sec * N_bands + i_band];
            float *p_azi_prev = &azi_prev[i_sec * N_bands + i_band];
            float *p_ele_prev = &ele_prev[i_sec * N_bands + i_band];

            float *p_energy_smth = &energy_smth[i_sec][i_band];
            float *p_sec_I_vec_smth_x = &sec_I_vec_smth_x[i_sec][i_band];
            float *p_sec_I_vec_smth_y = &sec_I_vec_smth_y[i_sec][i_band];
            float *p_sec_I_vec_smth_z = &sec_I_vec_smth_z[i_sec][i_band];

            *p_sec_I_vec_x = 0.f;
            *p_sec_I_vec_y = 0.f;
            *p_sec_I_vec_z = 0.f;
            energy = 0.f;

            for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
            {
            if ( i_sec == 0 )
            {
                    *p_sec_w_imag = 1.772454f * ImagBuffer[0][i_bin] + 1.772454f * ImagBuffer[1][i_bin];
                    *p_sec_x_imag = 1.772454f * ImagBuffer[3][i_bin] + 1.023326f * ImagBuffer[4][i_bin];
                    *p_sec_y_imag = 0.590818f * ImagBuffer[0][i_bin] + 1.772454f * ImagBuffer[1][i_bin] - 0.590817f * ImagBuffer[6][i_bin] - 1.023326f * ImagBuffer[8][i_bin];
                    *p_sec_z_imag = 1.772454f * ImagBuffer[2][i_bin] + 1.023326f * ImagBuffer[5][i_bin];
                for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
                {
                    float w = *( p_c_weights++ );


                    *p_sec_w_imag = 1.772454f * *( p_ImagBuffer_0 ) + 1.772454f * *( p_ImagBuffer_1 );
                    *p_sec_x_imag = 1.772454f * *( p_ImagBuffer_3++ ) + 1.023326f * *( p_ImagBuffer_4++ );
                    *p_sec_y_imag = 0.590818f * *( p_ImagBuffer_0++ ) + 1.772454f * *( p_ImagBuffer_1++ ) - 0.590817f * *( p_ImagBuffer_6++ ) - 1.023326f * *( p_ImagBuffer_8++ );
                    *p_sec_z_imag = 1.772454f * *( p_ImagBuffer_2++ ) + 1.023326f * *( p_ImagBuffer_5++ );

                    *p_sec_w_real = 1.772454f * *( p_RealBuffer_0 ) + 1.772454f * *( p_RealBuffer_1 );
                    *p_sec_x_real = 1.772454f * *( p_RealBuffer_3++ ) + 1.023326f * *( p_RealBuffer_4++ );
                    *p_sec_y_real = 0.590818f * *( p_RealBuffer_0++ ) + 1.772454f * *( p_RealBuffer_1++ ) - 0.590817f * *( p_RealBuffer_6++ ) - 1.023326f * *( p_RealBuffer_8++ );
                    *p_sec_z_real = 1.772454f * *( p_RealBuffer_2++ ) + 1.023326f * *( p_RealBuffer_5++ );

                    p_real = *p_sec_w_real * w;
                    p_imag = *p_sec_w_imag * w;

                    *p_sec_I_vec_x += p_real * *p_sec_x_real + p_imag * *p_sec_x_imag;
                    *p_sec_I_vec_y += p_real * *p_sec_y_real + p_imag * *p_sec_y_imag;
                    *p_sec_I_vec_z += p_real * *p_sec_z_real + p_imag * *p_sec_z_imag;

                    *p_sec_w_real = 1.772454f * RealBuffer[0][i_bin] + 1.772454f * RealBuffer[1][i_bin];
                    *p_sec_x_real = 1.772454f * RealBuffer[3][i_bin] + 1.023326f * RealBuffer[4][i_bin];
                    *p_sec_y_real = 0.590818f * RealBuffer[0][i_bin] + 1.772454f * RealBuffer[1][i_bin] - 0.590817f * RealBuffer[6][i_bin] - 1.023326f * RealBuffer[8][i_bin];
                    *p_sec_z_real = 1.772454f * RealBuffer[2][i_bin] + 1.023326f * RealBuffer[5][i_bin];
                    energy += 0.5f * ( p_real * p_real + p_imag * p_imag + *p_sec_x_real * *p_sec_x_real + *p_sec_x_imag * *p_sec_x_imag +
                                       *p_sec_y_real * *p_sec_y_real + *p_sec_y_imag * *p_sec_y_imag +
                                       *p_sec_z_real * *p_sec_z_real + *p_sec_z_imag * *p_sec_z_imag );
                }
            }
            else
            {
                    *p_sec_w_imag = 1.772454f * ImagBuffer[0][i_bin] - 1.772454f * ImagBuffer[1][i_bin];
                    *p_sec_x_imag = 1.772454f * ImagBuffer[3][i_bin] - 1.023326f * ImagBuffer[4][i_bin];
                    *p_sec_y_imag = -0.590818f * ImagBuffer[0][i_bin] + 1.772454f * ImagBuffer[1][i_bin] + 0.590817f * ImagBuffer[6][i_bin] + 1.023326f * ImagBuffer[8][i_bin];
                    *p_sec_z_imag = 1.772454f * ImagBuffer[2][i_bin] - 1.023326f * ImagBuffer[5][i_bin];
                for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
                {
                    float w = *( p_c_weights++ );

                    *p_sec_w_real = 1.772454f * RealBuffer[0][i_bin] - 1.772454f * RealBuffer[1][i_bin];
                    *p_sec_x_real = 1.772454f * RealBuffer[3][i_bin] - 1.023326f * RealBuffer[4][i_bin];
                    *p_sec_y_real = -0.590818f * RealBuffer[0][i_bin] + 1.772454f * RealBuffer[1][i_bin] + 0.590817f * RealBuffer[6][i_bin] + 1.023326f * RealBuffer[8][i_bin];
                    *p_sec_z_real = 1.772454f * RealBuffer[2][i_bin] - 1.023326f * RealBuffer[5][i_bin];
                }

                // active intensity
                p_real = *p_sec_w_real;
                p_imag = *p_sec_w_imag;
                // freq weighting
                p_real *= c_weights[i_bin];
                p_imag *= c_weights[i_bin];
                sec_I_vec_x[i_sec] += p_real * *p_sec_x_real + p_imag * *p_sec_x_imag;
                sec_I_vec_y[i_sec] += p_real * *p_sec_y_real + p_imag * *p_sec_y_imag;
                sec_I_vec_z[i_sec] += p_real * *p_sec_z_real + p_imag * *p_sec_z_imag;
                    *p_sec_w_imag = 1.772454f * *(p_ImagBuffer_0) -1.772454f * *( p_ImagBuffer_1 );
                    *p_sec_x_imag = 1.772454f * *( p_ImagBuffer_3++ ) - 1.023326f * *( p_ImagBuffer_4++ );
                    *p_sec_y_imag = -0.590818f * *( p_ImagBuffer_0++ ) + 1.772454f * *( p_ImagBuffer_1++ ) + 0.590817f * *( p_ImagBuffer_6++ ) + 1.023326f * *( p_ImagBuffer_8++ );
                    *p_sec_z_imag = 1.772454f * *( p_ImagBuffer_2++ ) - 1.023326f * *( p_ImagBuffer_5++ );

                    *p_sec_w_real = 1.772454f * *(p_RealBuffer_0) -1.772454f * *( p_RealBuffer_1 );
                    *p_sec_x_real = 1.772454f * *( p_RealBuffer_3++ ) - 1.023326f * *( p_RealBuffer_4++ );
                    *p_sec_y_real = -0.590818f * *( p_RealBuffer_0++ ) + 1.772454f * *( p_RealBuffer_1++ ) + 0.590817f * *( p_RealBuffer_6++ ) + 1.023326f * *( p_RealBuffer_8++ );
                    *p_sec_z_real = 1.772454f * *( p_RealBuffer_2++ ) - 1.023326f * *( p_RealBuffer_5++ );

                    p_real = *p_sec_w_real * w;
                    p_imag = *p_sec_w_imag * w;

                    *p_sec_I_vec_x += p_real * *p_sec_x_real + p_imag * *p_sec_x_imag;
                    *p_sec_I_vec_y += p_real * *p_sec_y_real + p_imag * *p_sec_y_imag;
                    *p_sec_I_vec_z += p_real * *p_sec_z_real + p_imag * *p_sec_z_imag;

                    energy += 0.5f * ( p_real * p_real + p_imag * p_imag + *p_sec_x_real * *p_sec_x_real + *p_sec_x_imag * *p_sec_x_imag +
                                       *p_sec_y_real * *p_sec_y_real + *p_sec_y_imag * *p_sec_y_imag +
                                       *p_sec_z_real * *p_sec_z_real + *p_sec_z_imag * *p_sec_z_imag );
                }
            }

            // time-smoothing
            if ( firstrun_sector_params )
            {
                sec_I_vec_smth_x[i_sec][i_band] = sec_I_vec_x[i_sec];
                sec_I_vec_smth_y[i_sec][i_band] = sec_I_vec_y[i_sec];
                sec_I_vec_smth_z[i_sec][i_band] = sec_I_vec_z[i_sec];
                energy_smth[i_sec][i_band] = energy;
                *p_sec_I_vec_smth_x = *p_sec_I_vec_x;
                *p_sec_I_vec_smth_y = *p_sec_I_vec_y;
                *p_sec_I_vec_smth_z = *p_sec_I_vec_z;
                *p_energy_smth = energy;
            }
            else
            {
                sec_I_vec_smth_x[i_sec][i_band] = ( 1.0f - beta ) * sec_I_vec_x[i_sec] + beta * sec_I_vec_smth_x[i_sec][i_band];
                sec_I_vec_smth_y[i_sec][i_band] = ( 1.0f - beta ) * sec_I_vec_y[i_sec] + beta * sec_I_vec_smth_y[i_sec][i_band];
                sec_I_vec_smth_z[i_sec][i_band] = ( 1.0f - beta ) * sec_I_vec_z[i_sec] + beta * sec_I_vec_smth_z[i_sec][i_band];
                energy_smth[i_sec][i_band] = ( 1.0f - beta ) * energy + beta * energy_smth[i_sec][i_band];
                float w = ( 1.0f - beta );
                *p_sec_I_vec_smth_x = w * *p_sec_I_vec_x + beta * *p_sec_I_vec_smth_x;
                *p_sec_I_vec_smth_y = w * *p_sec_I_vec_y + beta * *p_sec_I_vec_smth_y;
                *p_sec_I_vec_smth_z = w * *p_sec_I_vec_z + beta * *p_sec_I_vec_smth_z;
                *p_energy_smth = w * energy + beta * *p_energy_smth;
            }

            if ( energy < EPSILON )
            {
                azi[i_sec * N_bands + i_band] = 0.f;
                ele[i_sec * N_bands + i_band] = 0.f;
                ene[i_sec * N_bands + i_band] = 0.f;
                diff[i_sec * N_bands + i_band] = 1.f;
                *p_azi = 0.f;
                *p_ele = 0.f;
                *p_ene = 0.f;
                *p_diff = 1.f;
            }
            else
            {
                normI = sqrtf( sec_I_vec_smth_x[i_sec][i_band] * sec_I_vec_smth_x[i_sec][i_band] +
                               sec_I_vec_smth_y[i_sec][i_band] * sec_I_vec_smth_y[i_sec][i_band] +
                               sec_I_vec_smth_z[i_sec][i_band] * sec_I_vec_smth_z[i_sec][i_band] );
                theta = asinf( sec_I_vec_smth_z[i_sec][i_band] / ( normI + EPSILON ) );
                phi = atan2f( sec_I_vec_smth_y[i_sec][i_band], sec_I_vec_smth_x[i_sec][i_band] );
                azi[i_sec * N_bands + i_band] = phi * _180_OVER_PI;
                ele[i_sec * N_bands + i_band] = theta * _180_OVER_PI;
                ene[i_sec * N_bands + i_band] = energy_smth[i_sec][i_band];
                diff[i_sec * N_bands + i_band] = 1.f - normI / ( energy_smth[i_sec][i_band] + EPSILON );
                normI = sqrtf( *p_sec_I_vec_smth_x * *p_sec_I_vec_smth_x +
                               *p_sec_I_vec_smth_y * *p_sec_I_vec_smth_y +
                               *p_sec_I_vec_smth_z * *p_sec_I_vec_smth_z );
                *p_azi = atan2f( *p_sec_I_vec_smth_y, *p_sec_I_vec_smth_x ) * _180_OVER_PI;
                *p_ele = asinf( *p_sec_I_vec_smth_z / ( normI + EPSILON ) ) * _180_OVER_PI;
                *p_ene = *p_energy_smth;
                *p_diff = 1.f - normI / ( *p_energy_smth + EPSILON );
            }

            // post
            tmp_diff = diff[i_sec * N_bands + i_band];
            assert( tmp_diff < 1.0001f && tmp_diff > -0.0001f );
            tmp_diff = *p_diff;

            if ( tmp_diff < 0.0f )
            {
                diff[i_sec * N_bands + i_band] = 0.f;
                *p_diff = 0.f;
            }
            if ( tmp_diff > 0.5f )
            {
                if ( firstrun_sector_params )
                {
                    azi[i_sec * N_bands + i_band] = 0.f;
                    ele[i_sec * N_bands + i_band] = 0.f;
                    *p_azi = 0.f;
                    *p_ele = 0.f;
                }
                else
                {
                    azi[i_sec * N_bands + i_band] = 2.f * ( 1.f - tmp_diff ) * azi[i_sec * N_bands + i_band] + ( 2.f * tmp_diff - 1.f ) * azi_prev[i_sec * N_bands + i_band];
                    ele[i_sec * N_bands + i_band] = 2.f * ( 1.f - tmp_diff ) * ele[i_sec * N_bands + i_band] + ( 2.f * tmp_diff - 1.f ) * ele_prev[i_sec * N_bands + i_band];
                    *p_azi = 2.f * ( 1.f - tmp_diff ) * *p_azi + ( 2.f * tmp_diff - 1.f ) * *p_azi_prev;
                    *p_ele = 2.f * ( 1.f - tmp_diff ) * *p_ele + ( 2.f * tmp_diff - 1.f ) * *p_ele_prev;
                }
            }
            else
            {
                azi_prev[i_sec * N_bands + i_band] = azi[i_sec * N_bands + i_band];
                ele_prev[i_sec * N_bands + i_band] = ele[i_sec * N_bands + i_band];
                *p_azi_prev = *p_azi;
                *p_ele_prev = *p_ele;
            }
        } // i_band
    }     // i_sec