Commit a38ca793 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Few renderer functions conv to fixed point, cleanup of float dependencies

[x] chol2x2 fixed point implementation
[x] efap functions cleanup
[x] ivas_rotation.c and lib_rend.c intermediate float conversions cleanup
[x] Fix for high MLD for EVS non-diegetic panning and OMASA case.
parent 2a8ce389
Loading
Loading
Loading
Loading
Loading
+105 −3
Original line number Diff line number Diff line
@@ -643,6 +643,7 @@ int main(
#ifdef IVAS_FLOAT_FIXED
    Word32 *outInt32Buffer;
    Word32 *inInt32Buffer;
    Word32 gain_fx;
#endif
    float *outFloatBuffer;
    IVAS_REND_AudioBuffer inBuffer;
@@ -933,7 +934,9 @@ int main(
    }

    IVAS_REND_LfePanMtx lfePanMatrix;

#ifdef IVAS_FLOAT_FIXED
    IVAS_REND_LfePanMtx_fx lfePanMatrix_fx;
#endif
    /* parse input LFE panning matrix */
    if ( args.lfeCustomRoutingEnabled && !isEmptyString( args.inLfePanningMatrixFile ) )
    {
@@ -968,6 +971,7 @@ int main(

    for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i )
    {
#ifndef IVAS_FLOAT_FIXED
        if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
@@ -979,6 +983,21 @@ int main(
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }
#else
        IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }

        gain_fx = (Word32) ( ( args.inputGainGlobal * dBToLin( args.inConfig.multiChannelBuses[i].gain_dB ) ) * ( 1u << 30 ) );

        IF ((error = IVAS_REND_SetInputGain_fx(hIvasRend, mcIds[i], gain_fx)) != IVAS_ERR_OK)
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }
#endif

        if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM )
        {
@@ -998,7 +1017,16 @@ int main(
                args.lfePanningEnabled = false;
            }

#ifdef IVAS_FLOAT_FIXED
            FOR( Word16 k = 0; k < IVAS_MAX_OUTPUT_CHANNELS; k++ )
            {
                ( *lfePanMatrix_fx )[k] = (Word32) ( ( *lfePanMatrix )[k] * ( 1u << 31 ) );
            }

            IF ( ( error = IVAS_REND_SetInputLfeMtx_fx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx_fx *) &lfePanMatrix_fx ) ) != IVAS_ERR_OK )
#else
            if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK )
#endif // IVAS_FLOAT_FIXED
            {
                fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
                exit( -1 );
@@ -1007,7 +1035,12 @@ int main(
        /* set panning gains for input LFE */
        else if ( args.lfePanningEnabled )
        {
#ifdef IVAS_FLOAT_FIXED
            Word32 inputGain = (Word32) ( args.lfeConfigGain * ( 1u << 31 ) );
            IF( ( error = IVAS_REND_SetInputLfePos_fx( hIvasRend, mcIds[i], inputGain, (Word16) args.lfeConfigAzimuth, (Word16) args.lfeConfigElevation ) ) != IVAS_ERR_OK )
#else
            if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], args.lfeConfigGain, args.lfeConfigAzimuth, args.lfeConfigElevation ) ) != IVAS_ERR_OK )
#endif // IVAS_FLOAT_FIXED
            {
                fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
                exit( -1 );
@@ -1027,7 +1060,16 @@ int main(
                        exit( -1 );
                    }

#ifdef IVAS_FLOAT_FIXED
                    FOR( Word16 k = 0; k < IVAS_MAX_OUTPUT_CHANNELS; k++ )
                    {
                        ( *lfePanMatrix_fx )[k] = (Word32) ( ( *lfePanMatrix )[k] * ( 1u << 31 ) );
                    }

                    if ( ( error = IVAS_REND_SetInputLfeMtx_fx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx_fx *) &lfePanMatrix_fx ) ) != IVAS_ERR_OK )
#else
                    if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK )
#endif // IVAS_FLOAT_FIXED
                    {
                        fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
                        exit( -1 );
@@ -1036,7 +1078,12 @@ int main(
                /* set position based gains */
                else
                {
#ifdef IVAS_FLOAT_FIXED
                    Word32 inputGain = (Word32) ( lfeRoutingConfigs[i]->lfe_gain_dB * ( 1u << 31 ) );
                    IF( ( error = IVAS_REND_SetInputLfePos_fx( hIvasRend, mcIds[i], inputGain, (Word16) lfeRoutingConfigs[i]->lfe_azi, (Word16) lfeRoutingConfigs[i]->lfe_ele ) ) != IVAS_ERR_OK )
#else
                    if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], lfeRoutingConfigs[i]->lfe_gain_dB, lfeRoutingConfigs[i]->lfe_azi, lfeRoutingConfigs[i]->lfe_ele ) ) != IVAS_ERR_OK )
#endif // IVAS_FLOAT_FIXED
                    {
                        fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
                        exit( -1 );
@@ -1046,6 +1093,7 @@ int main(
        }
    }

#ifndef IVAS_FLOAT_FIXED
    for ( i = 0; i < args.inConfig.numAudioObjects; ++i )
    {
        if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_AUDIO_CONFIG_OBA, &ismIds[i] ) ) != IVAS_ERR_OK )
@@ -1082,7 +1130,6 @@ int main(
        }
    }


    for ( i = 0; i < args.inConfig.numMasaBuses; ++i )
    {
        if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK )
@@ -1097,6 +1144,61 @@ int main(
            exit( -1 );
        }
    }
#else
    FOR ( i = 0; i < args.inConfig.numAudioObjects; ++i )
    {
        IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, IVAS_AUDIO_CONFIG_OBA, &ismIds[i] ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }

        gain_fx = (Word32) ( args.inputGainGlobal * dBToLin( args.inConfig.audioObjects[i].gain_dB ) * ( 1u << 30 ) );
        IF( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, ismIds[i], gain_fx) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }

        /* With MASA output, all objects are handled at once, so add only one input having all objects in it */
        IF ( EQ_32(args.outConfig.audioConfig, IVAS_AUDIO_CONFIG_MASA1) || EQ_32(args.outConfig.audioConfig, IVAS_AUDIO_CONFIG_MASA2) )
        {
            BREAK;
        }
    }

    FOR ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i )
    {
        IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }

        gain_fx = (Word32) ( args.inputGainGlobal * dBToLin( args.inConfig.ambisonicsBuses[i].gain_dB ) * ( 1u << 30 ) );
        IF ( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, sbaIds[i], gain_fx ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }
    }

    FOR ( i = 0; i < args.inConfig.numMasaBuses; ++i )
    {
        IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }

        gain_fx = (Word32) ( ( args.inputGainGlobal * dBToLin( args.inConfig.masaBuses[i].gain_dB ) ) * ( 1u << 30 ) );
        IF ( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, masaIds[i], gain_fx) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }
    }
#endif // !IVAS_FLOAT_FIXED

    const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds );

+18 −0
Original line number Diff line number Diff line
@@ -5467,6 +5467,24 @@ Word16 L_norm_arr( Word32 *arr, Word16 size )
    return q;
}

Word16 get_min_scalefactor( Word32 x, Word32 y )
{
    Word16 scf = Q31;
    IF( EQ_32( x, 0 ) && EQ_32( y, 0 ) )
    {
        return 0;
    }
    IF( NE_32( x, 0 ) )
    {
        scf = s_min( scf, norm_l( x ) );
    }
    IF( NE_32( y, 0 ) )
    {
        scf = s_min( scf, norm_l( y ) );
    }
    return scf;
}

#if 0
/* Functions are already in fixed point and available in fft.c file */

+6 −1
Original line number Diff line number Diff line
@@ -6451,10 +6451,15 @@ void ivas_spar_param_to_masa_param_mapping_fx(
/*---------------------------------------------------------------------------------*
 * Binaural FastConv Renderer Prototypes
*-----------------------------------------------------------------------------------*/

#ifdef IVAS_FLOAT_FIXED
ivas_error ivas_binRenderer_open_fx(
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                          */
);
#else
ivas_error ivas_binRenderer_open(
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                          */
);
#endif

void ivas_binRenderer_close(
    BINAURAL_RENDERER_HANDLE *hBinRenderer                      /* i/o: decoder binaural renderer handle                */
+2 −0
Original line number Diff line number Diff line
@@ -4254,6 +4254,8 @@ Word16 find_guarded_bits_fx(Word32 n);

Word16 L_norm_arr(Word32* arr, Word16 size);

Word16 get_min_scalefactor( Word32 x, Word32 y );

void edct2_fx_ivas(
    const Word16 n,
    const Word16 isgn,
+188 −13
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#ifdef IVAS_FLOAT_FIXED
#include "prot_fx1.h"
#include "prot_fx2.h"
#include "ivas_rom_com_fx.h"
#include "debug.h"
#define float_to_fix( n, factor )     ( round( n * ( 1 << factor ) ) )
#define float_to_fixQ29( n )          float_to_fix( n, Q29 )
@@ -1601,8 +1602,8 @@ static void ivas_binaural_obtain_DMX_fx(
 *
 * Open fastconv binaural renderer handle
 *-------------------------------------------------------------------------*/

ivas_error ivas_binRenderer_open(
#ifdef IVAS_FLOAT_FIXED
ivas_error ivas_binRenderer_open_fx(
    Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
)
{
@@ -1683,7 +1684,7 @@ ivas_error ivas_binRenderer_open(

        IF( st_ivas->hoa_dec_mtx == NULL )
        {
            IF( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
            IF( ( error = ivas_sba_get_hoa_dec_matrix_fx( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
            {
                return error;
            }
@@ -1746,11 +1747,7 @@ ivas_error ivas_binRenderer_open(
        {
            FOR( k = 0; k < hBinRenderer->nInChannels; k++ )
            {
#ifndef IVAS_FLOAT_FIXED
                hBinRenderer->hReverb->dmxmtx[chIdx][k] = dmxmtx_table[chIdx][k];
#else
                hBinRenderer->hReverb->dmxmtx_fx[chIdx][k] = dmxmtx_table_fx[chIdx][k];
#endif
            }
        }
    }
@@ -1767,17 +1764,13 @@ ivas_error ivas_binRenderer_open(
        {
            FOR( k = 0; k < 11; k++ )
            {
#ifndef IVAS_FLOAT_FIXED
                ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 );
#else
                ivas_dirac_dec_get_response_fixed( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc_fx[k], 1 );
                ivas_dirac_dec_get_response_fixed( (Word16) L_shr_r( ls_azimuth_CICP19_fx[k], 22 ), (Word16) L_shr_r( ls_elevation_CICP19_fx[k], 22 ), hBinRenderer->hReverb->foa_enc_fx[k], 1 );
                // Q29: hBinRenderer->hReverb->foa_enc_fx[k]
#endif
            }
        }
        ELSE IF( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
        {
            IF( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK )
            IF( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK )
            {
                return error;
            }
@@ -1792,7 +1785,189 @@ ivas_error ivas_binRenderer_open(

    return error;
}
#else
ivas_error ivas_binRenderer_open(
    Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
)
{
    BINAURAL_RENDERER_HANDLE hBinRenderer;
    int16_t convBand, chIdx, k;
    ivas_error error;

    error = IVAS_ERR_OK;

    /*-----------------------------------------------------------------*
     * prepare library opening
     *-----------------------------------------------------------------*/

    if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
    {
        return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
    }

    hBinRenderer->hInputSetup = &st_ivas->hIntSetup;

    /* Define of head rotation has to be done in binRendeder in CLDFB*/
    hBinRenderer->rotInCldfb = 0;
    if ( st_ivas->ivas_format == MC_FORMAT || st_ivas->ivas_format == SBA_FORMAT )
    {
        hBinRenderer->rotInCldfb = 1;
    }


    /* Declare some common variables needed for renderer */
    /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */
    if ( st_ivas->hIntSetup.is_loudspeaker_setup )
    {
        hBinRenderer->ivas_format = MC_FORMAT;
    }
    else
    {
        hBinRenderer->ivas_format = SBA_FORMAT;
    }
    hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
    convBand = hBinRenderer->max_band;

    hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */

    if ( convBand > BINAURAL_CONVBANDS )
    {
        hBinRenderer->conv_band = BINAURAL_CONVBANDS;
    }
    else
    {
        hBinRenderer->conv_band = convBand;
    }

    /*LFE rendering switched off by default*/
    hBinRenderer->render_lfe = 0;

    if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup )
    {
        hBinRenderer->render_lfe = 1;
    }

    /* Load HRTF tables */
    if ( ( error = ivas_binaural_hrtf_open( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ) != IVAS_ERR_OK )
    {
        return error;
    }

    if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) )
    {
        IVAS_OUTPUT_SETUP out_setup;

        /* Allocate memories and buffers needed for convolutional module in CICP19 */
        if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 );

        if ( st_ivas->hoa_dec_mtx == NULL )
        {
            if ( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
            {
                return error;
            }
        }

        hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx;
        st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f );
    }
    else
    {
        /* Allocate memories and buffers needed for convolutional module */
        if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV )
        {
            if ( hBinRenderer->ivas_format == MC_FORMAT )
            {
                st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s * 1000000000.f );
            }
            else
            {
                if ( hBinRenderer->nInChannels == 16 )
                {
                    st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s * 1000000000.f );
                }
                else if ( hBinRenderer->nInChannels == 9 )
                {
                    st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s * 1000000000.f );
                }
                else if ( hBinRenderer->nInChannels == 4 )
                {
                    st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s * 1000000000.f );
                }
                else
                {
                    return IVAS_ERR_INVALID_INPUT_FORMAT;
                }
            }
        }
        else
        {
            /* same value for MC or HOA both use MC BRIR*/
            st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f );
        }
    }

    /* Allocate memories needed for reverb module */
    if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
    {
        if ( ( error = ivas_binaural_reverb_open_fastconv( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hIntSetup.output_config, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        /* initialize the dmx matrix */
        for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
        {
            for ( k = 0; k < hBinRenderer->nInChannels; k++ )
            {
                hBinRenderer->hReverb->dmxmtx[chIdx][k] = dmxmtx_table[chIdx][k];
            }
        }
    }
    else
    {
        hBinRenderer->hReverb = NULL;
    }

    hBinRenderer->hEFAPdata = NULL;

    if ( hBinRenderer->hReverb != NULL )
    {
        if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
        {
            for ( k = 0; k < 11; k++ )
            {
                ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 );
            }
        }
        else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
        {
            if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK )
            {
                return error;
            }

            /* Copy handles to bin renderer handle*/
            hBinRenderer->hEFAPdata = st_ivas->hEFAPdata;
        }
    }

    /* Copy the handles to main handle */
    st_ivas->hBinRenderer = hBinRenderer;

    return error;
}
#endif

/*-------------------------------------------------------------------------
 * ivas_binRenderer_convModuleClose()
Loading