Commit e1049aef authored by Dominik Weckbecker's avatar Dominik Weckbecker 💬
Browse files

implement new prediction formula with sector DoAs

parent 5a8ca6f9
Loading
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -4185,6 +4185,11 @@ void ivas_get_spar_md_from_dirac(
    float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float diffuseness[IVAS_MAX_NUM_BANDS],
#ifdef HODIRAC
    float azi_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float ele_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float ratio[IVAS_MAX_NUM_BANDS],
#endif
    const int16_t n_ts,
    float ***mixer_mat,
    ivas_spar_md_t *hSpar_md,
@@ -4194,6 +4199,10 @@ void ivas_get_spar_md_from_dirac(
    const int16_t order,
    const int16_t dtx_vad,
    float Wscale_d[IVAS_MAX_NUM_BANDS]
#ifdef HODIRAC
    ,
    int16_t hodirac
#endif
);

ivas_error ivas_spar_md_dec_open(
+117 −3
Original line number Diff line number Diff line
@@ -1640,6 +1640,11 @@ void ivas_get_spar_md_from_dirac(
    float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float diffuseness[IVAS_MAX_NUM_BANDS],
#ifdef HODIRAC
    float azi_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float ele_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float ratio[IVAS_MAX_NUM_BANDS],
#endif
    const int16_t n_ts,
    float ***mixer_mat,
    ivas_spar_md_t *hSpar_md,
@@ -1648,12 +1653,21 @@ void ivas_get_spar_md_from_dirac(
    const int16_t end_band,
    const int16_t order,
    const int16_t dtx_vad,
    float Wscale_d[IVAS_MAX_NUM_BANDS] )
    float Wscale_d[IVAS_MAX_NUM_BANDS]
#ifdef HODIRAC
    ,
    int16_t hodirac
#endif
)
{
    int16_t num_ch, band, i, j;
    int16_t block, ch;
    float response_avg[MAX_OUTPUT_CHANNELS];
    float response[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS];
#ifdef HODIRAC
    float response_avg2[MAX_OUTPUT_CHANNELS];
    float response2[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS];
#endif
    float cov_real_dirac[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
    float *pCov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
@@ -1662,6 +1676,10 @@ void ivas_get_spar_md_from_dirac(
    float **ppMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH];
    float *pMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH];
    float en_ratio_fac, diff_norm_order1, diff_norm_order2, diff_norm_order3;
#ifdef HODIRAC
    float w1 = 0;
    float w2 = 0;
#endif
    int16_t ndm, foa_ch, hoa2_ch;
    float P_dir_fact[IVAS_SPAR_MAX_CH - 1];
    const int16_t *remix_order;
@@ -1743,15 +1761,34 @@ void ivas_get_spar_md_from_dirac(

            /*SPAR from DirAC*/
            set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS );
#ifdef HODIRAC
            if ( hodirac )
            {
                set_f( response_avg2, 0.0f, MAX_OUTPUT_CHANNELS );
            }
#endif

            if ( n_ts > 1 )
            {
                ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg, order );
#ifdef HODIRAC
                if ( hodirac )
                {
                    ivas_dirac_dec_get_response( (int16_t) azi_dirac2[band][i_ts], (int16_t) ele_dirac2[band][i_ts], response_avg2, order );
                }
#endif
            }
            else
            {
                for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
                {
                    ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][block], (int16_t) ele_dirac[band][block], &( response[block][0] ), order );
#ifdef HODIRAC
                    if ( hodirac )
                    {
                        ivas_dirac_dec_get_response( (int16_t) azi_dirac2[band][block], (int16_t) ele_dirac2[band][block], &( response2[block][0] ), order );
                    }
#endif
                }

                /* average responses in all subframes*/
@@ -1806,6 +1843,56 @@ void ivas_get_spar_md_from_dirac(
                    {
                        response_avg[ch] /= norm;
                    }

#ifdef HODIRAC
                    if ( hodirac )
                    {

                        for ( ch = 0; ch < num_ch_order; ch++ )
                        {
                            for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
                            {
                                response_avg2[ch] += response2[block][ch];
                            }
                            response_avg2[ch] /= MAX_PARAM_SPATIAL_SUBFRAMES;
                        }

                        norm = 0.0f;
                        for ( ch = 1; ch < foa_ch; ch++ )
                        {
                            norm += response_avg2[ch] * response_avg2[ch];
                        }
                        norm = max( EPSILON, sqrtf( norm ) );
                        for ( ch = 1; ch < foa_ch; ch++ )
                        {
                            response_avg2[ch] /= norm;
                        }

                        /*normalize 2nd order*/
                        norm = 0.0f;
                        for ( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ )
                        {
                            norm += response_avg2[ch] * response_avg2[ch];
                        }
                        norm = max( EPSILON, sqrtf( norm ) );
                        for ( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ )
                        {
                            response_avg2[ch] /= norm;
                        }

                        /*normalize 3rd order*/
                        norm = 0.0f;
                        for ( ch = hoa2_ch_order; ch < num_ch_order; ch++ )
                        {
                            norm += response_avg2[ch] * response_avg2[ch];
                        }
                        norm = max( EPSILON, sqrtf( norm ) );
                        for ( ch = hoa2_ch_order; ch < num_ch_order; ch++ )
                        {
                            response_avg2[ch] /= norm;
                        }
                    }
#endif
                }
            }

@@ -1813,7 +1900,23 @@ void ivas_get_spar_md_from_dirac(
            {
                response_avg[i] = response_avg[HOA_keep_ind[i]];
            }
#ifdef HODIRAC
            if ( hodirac )
            {
                for ( i = FOA_CHANNELS + 1; i < num_ch; i++ )
                {
                    response_avg2[i] = response_avg2[HOA_keep_ind[i]];
                }
            }
#endif
            en_ratio_fac = ( 1.0f - diffuseness[band] );
#ifdef HODIRAC
            if ( hodirac )
            {
                w1 = ratio[band] * ratio[band];
                w2 = ( 1.0f - ratio[band] ) * ( 1.0f - ratio[band] );
            }
#endif

            for ( i = 0; i < num_ch; i++ )
            {
@@ -1828,8 +1931,10 @@ void ivas_get_spar_md_from_dirac(
                        else
                        {
                            cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j];

                            if ( hSpar_md_cfg->nchan_transport <= 2 )
                            {

                                cov_real_dirac[i][j][band] *= en_ratio_fac;
                                if ( ( i >= ndm ) && ( dtx_vad == 1 ) )
                                {
@@ -1870,11 +1975,20 @@ void ivas_get_spar_md_from_dirac(
                    }
                    else
                    {
#ifdef HODIRAC
                        if ( hodirac )
                        {
                            cov_real_dirac[i][j][band] = en_ratio_fac * ( w1 * response_avg[i] * response_avg[j] + w2 * response_avg2[i] * response_avg2[j] );
                        }
                        else
#endif
                        {
                            cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j];
                        }
                    }
                }
            }
        }

        for ( i = 0; i < num_ch; i++ )
        {
@@ -1884,7 +1998,7 @@ void ivas_get_spar_md_from_dirac(
            }
        }

#ifdef DEBUG_SPAR_WRITE_OUT_COV
#ifdef DEBUG_SBA_MD_DUMP
        {
            static FILE *fid = 0;
            int16_t k = 0;
+2 −2
Original line number Diff line number Diff line
@@ -151,11 +151,11 @@
#define HODIRAC                                         /* FhG: Sector-based HO-DirAC method for SBA at high bitrates */
#define HODIRAC_CRASH_FIX

/*#define HODIRAC_DEBUG*/
#define HODIRAC_DEBUG

#ifdef HODIRAC_DEBUG
//#define HODIRAC_CHECK_VALUE_RANGE
//#define HODIRAC_WRITE_PARAMS
#define HODIRAC_WRITE_PARAMS
///#define HODIRAC_READ_PARAMS
#endif

+65 −3
Original line number Diff line number Diff line
@@ -1389,7 +1389,7 @@ void ivas_spar_dec_gen_umx_mat(
            }
        }

#if DEBUG_SBA_MD_DUMP
#ifdef DEBUG_SBA_MD_DUMP
        {
            static FILE *f_mat = 0;

@@ -2542,6 +2542,11 @@ void ivas_spar_to_dirac(
    int16_t sba_order_internal;
    float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
#ifdef HODIRAC
    float azi_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    float ele_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    float ratio[IVAS_MAX_NUM_BANDS];
#endif
    int16_t azi[IVAS_MAX_NUM_BANDS];
    int16_t ele[IVAS_MAX_NUM_BANDS];
    float dvx[IVAS_MAX_NUM_BANDS], dvy[IVAS_MAX_NUM_BANDS], dvz[IVAS_MAX_NUM_BANDS];
@@ -2739,15 +2744,50 @@ void ivas_spar_to_dirac(
            }
            azi_dirac[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[block];
            ele_dirac[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].elevation[block];
#ifdef HODIRAC
            if ( st_ivas->sba_analysis_order > 1 )
            {
                azi_dirac2[band][block] = st_ivas->hQMetaData->q_direction[1].band_data[dirac_band_idx].azimuth[block];
                ele_dirac2[band][block] = st_ivas->hQMetaData->q_direction[1].band_data[dirac_band_idx].elevation[block];
            }
#endif
        }

        diffuseness[band] = 1.0f - st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0];
#ifdef HODIRAC
        if ( st_ivas->sba_analysis_order > 1 )
        {
            ratio[band] = st_ivas->hQMetaData->q_direction[1].band_data[dirac_band_idx].energy_ratio[0];
        }
#endif
    }

    /* DirAC MD averaged over 4 subframes and converted to SPAR format similar to encoder processing */
    if ( hMdDec->spar_md_cfg.nchan_transport > 1 )
    {
        ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL );
        ivas_get_spar_md_from_dirac( 
            azi_dirac, 
            ele_dirac, 
            diffuseness,
#ifdef HODIRAC
            azi_dirac2,
            ele_dirac2,
            ratio,
#endif
            1, 
            NULL, 
            &hMdDec->spar_md, 
            &hMdDec->spar_md_cfg, 
            end_band, 
            num_bands_out, 
            ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, 
            dtx_vad, 
            NULL 
#ifdef HODIRAC
            ,
            st_ivas->sba_analysis_order > 1
#endif
        );

        /* temporarily copy frame-wise prediction coefficients in DirAC bands*/
        for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ )
@@ -2759,7 +2799,29 @@ void ivas_spar_to_dirac(
        }
    }

    ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, MAX_PARAM_SPATIAL_SUBFRAMES, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL );
    ivas_get_spar_md_from_dirac( 
        azi_dirac, 
        ele_dirac, 
        diffuseness, 
#ifdef HODIRAC
        azi_dirac2,
        ele_dirac2,
        ratio,
#endif
        MAX_PARAM_SPATIAL_SUBFRAMES, 
        NULL, 
        &hMdDec->spar_md, 
        &hMdDec->spar_md_cfg, 
        end_band, 
        num_bands_out, 
        ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, 
        dtx_vad, 
        NULL 
#ifdef HODIRAC
        ,
        st_ivas->sba_analysis_order > 1
#endif
    );

    /* expand DirAC TC 20ms MD for residual channels to all subframes*/
    for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+49 −3
Original line number Diff line number Diff line
@@ -721,6 +721,11 @@ static ivas_error ivas_spar_enc_process(
    {
        float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
        float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
#ifdef HODIRAC
        float azi_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
        float ele_dirac2[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
        float ratio[IVAS_MAX_NUM_BANDS];
#endif
        float diffuseness[IVAS_MAX_NUM_BANDS];
        float Wscale_d[IVAS_MAX_NUM_BANDS];
        int16_t d_start_band, d_end_band;
@@ -734,10 +739,31 @@ static ivas_error ivas_spar_enc_process(
            dirac_band_idx = hSpar->dirac_to_spar_md_bands[b] - d_start_band;
            for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ )
            {
                azi_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[i_ts];
                ele_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].elevation[i_ts];
                azi_dirac[b][i_ts] = hQMetaData->q_direction[0].band_data[dirac_band_idx].azimuth[i_ts];
                ele_dirac[b][i_ts] = hQMetaData->q_direction[0].band_data[dirac_band_idx].elevation[i_ts];
#ifdef HODIRAC
                if ( st_ivas->sba_analysis_order > 1 )
                {
                    azi_dirac2[b][i_ts] = hQMetaData->q_direction[1].band_data[dirac_band_idx].azimuth[i_ts] + hQMetaData->q_direction[0].band_data[dirac_band_idx].azimuth[i_ts] - 180.f;
                    if ( azi_dirac2[b][i_ts] < -180.f )
                    {
                        azi_dirac2[b][i_ts] += 360.f;
                    }
                    if ( azi_dirac2[b][i_ts] >= 180.f )
                    {
                        azi_dirac2[b][i_ts] -= 360.f;
                    }
                    ele_dirac2[b][i_ts] = hQMetaData->q_direction[1].band_data[dirac_band_idx].elevation[i_ts];
                }
#endif
            }
            diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0];
#ifdef HODIRAC
            if ( st_ivas->sba_analysis_order > 1 )
            {
                ratio[b] = hQMetaData->q_direction[1].band_data[dirac_band_idx].energy_ratio[0];
            }
#endif
        }

        if ( d_start_band >= 6 && dtx_vad == 1 )
@@ -757,7 +783,27 @@ static ivas_error ivas_spar_enc_process(
            Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) );
        }

        ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d );
        ivas_get_spar_md_from_dirac(
            azi_dirac,
            ele_dirac,
            diffuseness,
#ifdef HODIRAC
            azi_dirac2,
            ele_dirac2,
            ratio,
#endif
            1,
            hSpar->hMdEnc->mixer_mat,
            &hSpar->hMdEnc->spar_md,
            &hSpar->hMdEnc->spar_md_cfg,
            d_start_band,
            d_end_band,
            ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d
#ifdef HODIRAC
            ,
            st_ivas->sba_analysis_order > 1
#endif
        );
    }

    if ( hSpar->hMdEnc->spar_hoa_md_flag )