Commit 1eff26d3 authored by Tapani Pihlajakuja's avatar Tapani Pihlajakuja
Browse files

Merge branch '668-add-jbm-for-omasa' into 'main'

[non-BE] Resolve "Add JBM for OMASA"

See merge request !902
parents 30936203 c8c9fecd
Loading
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -5026,7 +5026,13 @@ void ivas_masa_enc_reconfigure(
);

ivas_error ivas_masa_dec_reconfigure(
#ifdef MASA_AND_OBJECTS
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                          */
    uint16_t *nSamplesRendered,                                 /* o  : number of samples flushed from the previous frame (JBM) */
    int16_t *data                                               /* o  : flushed PCM samples                             */
#else
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                          */
#endif
);

ivas_error ivas_masa_encode(
@@ -5723,7 +5729,13 @@ ivas_error ivas_omasa_enc_config(
);

ivas_error ivas_omasa_dec_config(
#ifdef MASA_AND_OBJECTS
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                  */
    uint16_t *nSamplesRendered,                                 /* o  : number of samples flushed from the previous frame (JBM) */
    int16_t *data                                               /* o  : flushed PCM samples                     */
#else
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                  */
#endif
);

void ivas_omasa_set_config(
@@ -5835,12 +5847,34 @@ ivas_error ivas_omasa_dirac_td_binaural(
    const int16_t output_frame                                  /* i  : output frame length per channel         */
);

#ifdef MASA_AND_OBJECTS
ivas_error ivas_omasa_dirac_td_binaural_jbm(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder handle                      */
    const uint16_t nSamplesAsked,                               /* i  : number of samples requested              */
    uint16_t *nSamplesRendered,                                 /* o  : number of samples rendered               */
    uint16_t *nSamplesAvailable,                                /* o  : number of samples still to render        */
    const int16_t nchan_transport,                              /* i  : number of transport channels             */
    float *output_f[]                                           /* o  : rendered time signal                     */
);
#endif

void ivas_omasa_dirac_rend(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                  */
    float output[][L_FRAME48k],                                 /* o  : output synthesis signal                 */
    const int16_t output_frame                                  /* i  : output frame length per channel         */
);

#ifdef MASA_AND_OBJECTS
void ivas_omasa_dirac_rend_jbm(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder handle                      */
    const uint16_t nSamplesAsked,                               /* i  : number of samples requested              */
    uint16_t *nSamplesRendered,                                 /* o  : number of samples rendered               */
    uint16_t *nSamplesAvailable,                                /* o  : number of samples still to render        */
    const int16_t nchan_transport,                              /* i  : number of transport channels             */
    float *output_f[]                                           /* o  : rendered time signal                     */
);
#endif

void ivas_omasa_preProcessStereoTransportsForMovedObjects(
    Decoder_Struct *st_ivas,
    float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
@@ -5863,6 +5897,17 @@ void ivas_omasa_separate_object_render(
    float output_f[][L_FRAME48k],                               /* i/o: output signals                          */
    const int16_t output_frame                                  /* i  : output frame length per channel         */
);

#ifdef MASA_AND_OBJECTS
void ivas_omasa_separate_object_render_jbm(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                   */
    const uint16_t nSamplesRendered,                            /* i  : number of samples rendered               */
    float *output_f[],                                          /* o  : rendered time signal                     */
    const int16_t subframes_rendered,                           /* i  : number of subframes rendered             */
    const int16_t slots_rendered                                /* i  : number of CLDFB slots rendered           */
);
#endif

#ifndef FIX__657_REMOVE_EDITING
void ivas_omasa_set_edited_objects(
    Decoder_Struct *st_ivas                                     /* i/o: IVAS decoder structure                  */
+7 −3
Original line number Diff line number Diff line
@@ -326,7 +326,11 @@ ivas_error ivas_dec_setup(
                        }
                        else
                        {
#ifdef MASA_AND_OBJECTS
                            if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK )
#else
                        if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
#endif
                            {
                                return error;
                            }
@@ -335,7 +339,7 @@ ivas_error ivas_dec_setup(
                    }
                    else
                    {
                        if ( ( error = ivas_omasa_dec_config( st_ivas ) ) != IVAS_ERR_OK )
                        if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK )
                        {
                            return error;
                        }
@@ -358,7 +362,7 @@ ivas_error ivas_dec_setup(
                /* reconfigure in case a change of operation mode is detected */
                if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) )
                {
                    if ( ( error = ivas_omasa_dec_config( st_ivas ) ) != IVAS_ERR_OK )
                    if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK )
                    {
                        return error;
                    }
+158 −2
Original line number Diff line number Diff line
@@ -371,7 +371,6 @@ ivas_error ivas_omasa_separate_object_renderer_open(
        set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
    }

    // Todo OMASA JBM: This needs touches for VOIP path at least. Current version is mostly an adapted copy from ivas_ism_renderer_open()
    if ( st_ivas->hDecoderConfig->voip_active )
    {
        init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS );
@@ -388,6 +387,7 @@ ivas_error ivas_omasa_separate_object_renderer_open(
    {
        st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
    }
    st_ivas->hIsmRendererData->interpolator_length = interpolator_length;

    st_ivas->hMasaIsmData->delayBuffer_size = (int16_t) ( ( st_ivas->hDecoderConfig->output_Fs / 50 ) / MAX_PARAM_SPATIAL_SUBFRAMES );

@@ -470,7 +470,6 @@ void ivas_omasa_separate_object_renderer_close(
 * Rendering separated objects and mixing them to the parametrically rendered signals
 *-------------------------------------------------------------------------*/

// Todo OMASA JBM: This might need adjustments
void ivas_omasa_separate_object_render(
    Decoder_Struct *st_ivas,      /* i/o: IVAS decoder structure                      */
    float input_f[][L_FRAME48k],  /* i  : separated object signal                     */
@@ -575,4 +574,161 @@ void ivas_omasa_separate_object_render(

    return;
}

/*-------------------------------------------------------------------------*
 * ivas_omasa_separate_object_render_jbm()
 *
 * Rendering separated objects and mixing them to the parametrically rendered signals for JBM
 *-------------------------------------------------------------------------*/

void ivas_omasa_separate_object_render_jbm(
    Decoder_Struct *st_ivas,          /* i/o: IVAS decoder structure                      */
    const uint16_t nSamplesRendered,  /* i  : number of samples rendered                  */
    float *output_f[],                /* o  : rendered time signal                        */
    const int16_t subframes_rendered, /* i  : number of subframes rendered                */
    const int16_t slots_rendered      /* i  : number of CLDFB slots rendered              */
)
{
    VBAP_HANDLE hVBAPdata;
    DIRAC_REND_HANDLE hDirACRend;
    SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    int16_t nchan_out_woLFE, num_lfe;
    ISM_RENDERER_HANDLE hRendererData;
    int16_t j, k, j2;
    int16_t obj;
    float gains[MAX_OUTPUT_CHANNELS];
    float g1, g2;
    int16_t lfe_index;
    int16_t azimuth, elevation;
    int16_t num_objects;
    uint8_t single_separated;
    float *input_f[MAX_TRANSPORT_CHANNELS];
    float *output_f_local[MAX_OUTPUT_CHANNELS];
    int16_t offsetSamples;
    int16_t n_samples_sf, md_idx;
    int16_t slots_to_render, first_sf, last_sf, subframe_idx;

    hVBAPdata = st_ivas->hVBAPdata;
    hDirACRend = st_ivas->hDirACRend;
    hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
    num_lfe = st_ivas->hIntSetup.num_lfe;
    hRendererData = st_ivas->hIsmRendererData;
    lfe_index = hDirACRend->hOutSetup.index_lfe[0];

    if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
    {
        single_separated = 1;
        num_objects = 1;
    }
    else
    {
        single_separated = 0;
        num_objects = st_ivas->nchan_ism;
    }

    offsetSamples = slots_rendered * hSpatParamRendCom->slot_size;

    for ( j = 0; j < nchan_out_woLFE + num_lfe; j++ )
    {
        output_f_local[j] = output_f[j];
    }

    for ( obj = 0; obj < num_objects; obj++ )
    {
        input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples];
    }

    slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size;
    first_sf = subframes_rendered;
    last_sf = first_sf;

    while ( slots_to_render > 0 )
    {
        slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf];
        last_sf++;
    }

    for ( obj = 0; obj < num_objects; obj++ )
    {
        /* Delay the signal to match CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */
        if ( slots_rendered == 0 )
        {
            int16_t tcBufferSize;

            tcBufferSize = hSpatParamRendCom->num_slots * hSpatParamRendCom->slot_size;
            delay_signal( input_f[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer[obj], st_ivas->hMasaIsmData->delayBuffer_size );
        }

        offsetSamples = 0;

        for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
        {
            n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size;
            if ( n_samples_sf != hRendererData->interpolator_length )
            {
                for ( k = 0; k < n_samples_sf; k++ )
                {
                    hRendererData->interpolator[k] = (float) k / ( (float) n_samples_sf );
                }
                hRendererData->interpolator_length = n_samples_sf;
            }

            md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];

            if ( single_separated )
            {
                azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[md_idx];
                elevation = st_ivas->hMasaIsmData->elevation_separated_ism[md_idx];
            }
            else
            {
                azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][md_idx];
                elevation = st_ivas->hMasaIsmData->elevation_ism[obj][md_idx];
            }

            if ( st_ivas->hOutSetup.is_planar_setup )
            {
                /* If no elevation support in output format, then rendering should be done with zero elevation */
                elevation = 0;
            }

            if ( hVBAPdata != NULL )
            {
                vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 );
            }
            else
            {
                ivas_dirac_dec_get_response( azimuth, elevation, gains, hDirACRend->hOutSetup.ambisonics_order );
            }

            for ( j = 0; j < nchan_out_woLFE; j++ )
            {
                if ( hDirACRend->hOutSetup.num_lfe > 0 )
                {
                    j2 = j + ( j >= lfe_index );
                }
                else
                {
                    j2 = j;
                }

                if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f )
                {
                    for ( k = 0; k < n_samples_sf; k++ )
                    {
                        g1 = hRendererData->interpolator[k];
                        g2 = 1.0f - g1;
                        output_f_local[j2][k + offsetSamples] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + offsetSamples];
                    }
                }
                hRendererData->prev_gains[obj][j] = gains[j];
            }

            offsetSamples += n_samples_sf;
        }
    }

    return;
}
#endif
+168 −0
Original line number Diff line number Diff line
@@ -77,7 +77,11 @@ ivas_error ivas_jbm_dec_tc(
    float output[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; /* 'float' buffer for transport channels, MAX_TRANSPORT_CHANNELS channels */
    int16_t nchan_remapped;
    float output_lfe_ch[L_FRAME48k];
#ifdef MASA_AND_OBJECTS
    int16_t nb_bits_metadata[MAX_SCE + 1];
#else
    int16_t nb_bits_metadata[MAX_SCE];
#endif
    int32_t output_Fs, ivas_total_brate;
    AUDIO_CONFIG output_config;
    ivas_error error;
@@ -85,6 +89,9 @@ ivas_error ivas_jbm_dec_tc(
#ifdef VLBR_20MS_MD
    int16_t num_md_sub_frames;
#endif
#ifdef MASA_AND_OBJECTS
    int32_t ism_total_brate;
#endif

    error = IVAS_ERR_OK;

@@ -331,6 +338,82 @@ ivas_error ivas_jbm_dec_tc(
#endif
        }
    }
#ifdef MASA_AND_OBJECTS
    else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
    {
        int16_t nchan_ism, nchan_transport_ism;
        int16_t dirac_bs_md_write_idx;

        st = st_ivas->hCPE[0]->hCoreCoder[0];
        set_s( nb_bits_metadata, 0, MAX_SCE + 1 );

        /* Set the number of objects for the parametric rendering */
        dirac_bs_md_write_idx = 0;
        if ( st_ivas->hDirAC != NULL )
        {
            st_ivas->hSpatParamRendCom->numIsmDirections = 0;
            if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
            {
                st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism;
            }

            dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
        }

        /* MASA metadata decoding */
        if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        /* Configuration of combined-format bit-budget distribution */
        ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate );

        st->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] );

        /* set ISM parameters and decode ISM metadata in OMASA format */
        if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        /* decode ISM channels */
        for ( n = 0; n < nchan_transport_ism; n++ )
        {
            if ( ( error = ivas_sce_dec( st_ivas, n, &output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
            {
                return error;
            }
        }

        /* decode MASA channels */
        if ( ( error = ivas_cpe_dec( st_ivas, 0, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
        {
            return error;
        }

        if ( st_ivas->hCPE[0]->nchan_out == 1 )
        {
            mvr2r( output[0], output[1], output_frame ); /* Copy mono signal to stereo output channels */
        }

        /* HP filtering */
        for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
        {
            hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
        }

        if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
        {
            ivas_mono_downmix_render_passive( st_ivas, output, output_frame );
        }

#ifndef FIX_657_REMOVE_EDITING
        /* Set edited object positions, if editing enabled */
        ivas_omasa_set_edited_objects( st_ivas );
#endif
    }
#endif
    else if ( st_ivas->ivas_format == MC_FORMAT )
    {
        st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
@@ -642,6 +725,21 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer(
    {
        ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available );
    }
#ifdef MASA_AND_OBJECTS
    else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
    {
        if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC )
        {
            n_render_timeslots *= ( st_ivas->hTcBuffer->n_samples_granularity / st_ivas->hSpatParamRendCom->slot_size );
        }
        ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available );

        if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
        {
            ivas_ism_dec_digest_tc( st_ivas );
        }
    }
#endif
    else if ( st_ivas->ivas_format == MC_FORMAT )
    {
        if ( st_ivas->mc_mode == MC_MODE_MCT )
@@ -878,6 +976,31 @@ ivas_error ivas_jbm_dec_render(
            ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
        }
    }
#ifdef MASA_AND_OBJECTS
    else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
    {
        nchan_remapped = st_ivas->nchan_transport;

        if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
        {
            if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
            {
                if ( ( ivas_omasa_dirac_td_binaural_jbm( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ) ) != IVAS_ERR_OK )
                {
                    return error;
                }
            }
            else
            {
                ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
            }
        }
        else if ( st_ivas->renderer_type == RENDERER_DIRAC )
        {
            ivas_omasa_dirac_rend_jbm( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
        }
    }
#endif
    else if ( st_ivas->ivas_format == MC_FORMAT )
    {
        if ( st_ivas->mc_mode == MC_MODE_MCT )
@@ -1198,6 +1321,38 @@ ivas_error ivas_jbm_dec_flush_renderer(
                return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong MC_MODE in VoIP renderer flushing!" );
            }
        }
#ifdef MASA_AND_OBJECTS
        else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
        {
            if ( ism_mode_old == ISM_MASA_MODE_DISC )
            {
                float *tc_local[MAX_TRANSPORT_CHANNELS];

                for ( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ )
                {
                    tc_local[ch_idx] = &st_ivas->hTcBuffer->tc[ch_idx + 2][hTcBuffer->n_samples_rendered];
                    mvr2r( st_ivas->hMasaIsmData->delayBuffer[ch_idx], tc_local[ch_idx], st_ivas->hMasaIsmData->delayBuffer_size );
                }

                if ( st_ivas->nchan_ism > 0 )
                {
                    if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK )
                    {
                        return error;
                    }
                }
                else
                {
                    for ( ch_idx = 0; ch_idx < st_ivas->hDecoderConfig->nchan_out; ch_idx++ )
                    {
                        set_zero( p_output[ch_idx], (int16_t) ( *nSamplesRendered ) );
                    }
                    st_ivas->hTcBuffer->slots_rendered += 1;
                    st_ivas->hTcBuffer->subframes_rendered += 1;
                }
            }
        }
#endif
        else
        {
            return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong IVAS format in VoIP renderer flushing!" );
@@ -1516,6 +1671,19 @@ int16_t ivas_jbm_dec_get_num_tc_channels(
            }
        }
    }
#ifdef MASA_AND_OBJECTS
    else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
    {
        if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
        {
            num_tc++;
        }
        else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
        {
            num_tc += st_ivas->nchan_ism;
        }
    }
#endif
    else if ( st_ivas->ivas_format == MC_FORMAT )
    {
        if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO )
+96 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading