Commit c5a2b92f authored by sagnowski's avatar sagnowski
Browse files

Merge branch 'port-jbm-fix-basop-part' into 'main'

port MR 1223 from float to fix bug in JBM which causes problems with some CI tests - BASOP part

See merge request !1715
parents 77c8f31b 0b05cbac
Loading
Loading
Loading
Loading
Loading
+95 −0
Original line number Diff line number Diff line
@@ -2462,7 +2462,14 @@ static ivas_error decodeVoIP(
        }
        vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len;
        frame++;
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
        if ( vec_pos_update == 0 )
        {
            systemTime_ms += vec_pos_len * systemTimeInc_ms;
        }
#else
        systemTime_ms += systemTimeInc_ms;
#endif

#ifdef WMOPS
        update_mem();
@@ -2470,6 +2477,94 @@ static ivas_error decodeVoIP(
#endif
    }


#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    int16_t nSamplesFlushed = 0;

    /* decode and get samples */
#ifdef SPLIT_REND_WITH_HEAD_ROT
    if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK )
#else
    if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK )
#endif
    {
        fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) );
        goto cleanup;
    }

    if ( nSamplesFlushed )
    {
        /* Write current frame */
        if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, nSamplesFlushed * nOutChannels ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "\nOutput audio file writer error\n" );
            goto cleanup;
        }

        /* Write ISm metadata to external file(s) */
        if ( decodedGoodFrame && arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL )
        {
            if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM || bsFormat == IVAS_DEC_BS_SBA_ISM )
            {
                if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nError in IVAS_DEC_GetNumObjects: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                    goto cleanup;
                }

                for ( i = 0; i < numObj; ++i )
                {
                    IVAS_ISM_METADATA IsmMetadata;

                    if ( ( error = IVAS_DEC_GetObjectMetadata( hIvasDec, &IsmMetadata, 0, i ) ) != IVAS_ERR_OK )
                    {
                        fprintf( stderr, "\nError in IVAS_DEC_GetObjectMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                        goto cleanup;
                    }

                    if ( ( IsmFileWriter_writeFrame( IsmMetadata, ismWriters[i] ) ) != IVAS_ERR_OK )
                    {
                        fprintf( stderr, "\nError writing ISM metadata to file %s\n", IsmFileWriter_getFilePath( ismWriters[i] ) );
                        goto cleanup;
                    }
                }
            }

            if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM )
            {
                IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta;
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
                int16_t fullDelayNumSamples[3];
                float delayMs;

                /* delayNumSamples is zeroed, and delayNumSamples_orig is updated only on first good frame, so need to re-fetch delay info */
                if ( ( error = IVAS_DEC_GetDelay( hIvasDec, fullDelayNumSamples, &delayTimeScale ) ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) );
                }
#endif
                if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                    goto cleanup;
                }

#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
                delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale );
                if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK )
#else
                if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK )
#endif
                {
                    fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) );
                    goto cleanup;
                }
            }
        }
    }
#endif


    /*------------------------------------------------------------------------------------------*
     * Add zeros at the end to have equal length of synthesized signals
     *------------------------------------------------------------------------------------------*/
+3 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
/*#define DEBUG_FORCE_DIR*/                       /* Force modes/parameters by reading from external binary files */
/*#define DBG_WAV_WRITER*/                    /* Enable dbgwrite_wav() function for generating ".wav" files */
#define SUPPORT_FORCE_TCX10_TCX20             /* VA: Enable -force tcx10|tcx20 command-line option */
/*#define DEBUG_MODE_JBM */                     /* define to output JBM relevant parameters */
#endif

#define SUPPORT_JBM_TRACEFILE                   /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */
@@ -114,4 +115,6 @@
#define FIX_1733_CLDFB_BUG
#define FIX_1740_MISING_POP_WMOPS               /* VA: fix issue 1740: missing pop_wmops() */

#define NONBE_FIX_864_JBM_RENDER_FRAMESIZE                    /* FhG: issue #864: fix different behaviour of JBM TSM with different render frame sizes */

#endif
+110 −3
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ struct IVAS_DEC_VOIP
    UWord16 lastDecodedWasActive;
    JB4_DATAUNIT_HANDLE hCurrentDataUnit; /* Points to the currently processed data unit */
    UWord16 *bs_conversion_buf;           /* Buffer for bitstream conversion from packed to serial */
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    Word16 nSamplesRendered20ms; /* how many samples have been rendered since the last 20ms render border*/
#endif
#ifdef SUPPORT_JBM_TRACEFILE
    IVAS_JBM_TRACE_DATA JbmTraceData;
#endif
@@ -79,8 +82,11 @@ struct IVAS_DEC
    bool Opt_VOIP;          /* flag indicating VOIP mode with JBM */
    Word16 tsm_scale;       /* scale for TSM operation */
    Word16 tsm_max_scaling;
    Word32 *apaExecBuffer_fx; /* Buffer for APA scaling */
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    Word16 timeScalingDone; /* have we done already one TSM in a 20ms frame? */
#endif
    Word16 tsm_quality;       /*Q14*/
    Word32 *apaExecBuffer_fx; /* Buffer for APA scaling */
    PCMDSP_APA_HANDLE hTimeScaler;
    bool needNewFrame;
    bool hasBeenFedFrame;
@@ -112,6 +118,9 @@ static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, cons
static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const UWord16 nSamplesForRendering, UWord16 *nSamplesRendered, UWord16 *nSamplesAvailableNext, Word16 *pcmBuf );
static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, Word16 *nSamplesBuffered );
static Word16 get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize );
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const Word16 nSamplesRendered );
#endif


/*---------------------------------------------------------------------*
@@ -149,6 +158,9 @@ ivas_error IVAS_DEC_Open(
    hIvasDec->tsm_scale = 100;
    hIvasDec->tsm_max_scaling = 0;
    hIvasDec->tsm_quality = ONE_IN_Q14; /*1.f Q14*/
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    hIvasDec->timeScalingDone = 0;
#endif
    hIvasDec->needNewFrame = false;
    hIvasDec->nTransportChannelsOld = 0;
    hIvasDec->nSamplesAvailableNext = 0;
@@ -171,6 +183,9 @@ ivas_error IVAS_DEC_Open(
    move16();
    move16();
    move16();
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    move16();
#endif

    hIvasDec->mode = mode;
    move16();
@@ -805,6 +820,10 @@ ivas_error IVAS_DEC_EnableVoIP(
    hIvasDec->hVoIP->hCurrentDataUnit = NULL;
    hIvasDec->hVoIP->nSamplesFrame = (UWord16) Mpy_32_16_1( hDecoderConfig->output_Fs, INV_FRAME_PER_SEC_Q15 );
    move16();
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    hIvasDec->hVoIP->nSamplesRendered20ms = 0;
    move16();
#endif

#define WMC_TOOL_SKIP
    /* Bitstream conversion is not counted towards complexity and memory usage */
@@ -1107,18 +1126,29 @@ ivas_error IVAS_DEC_GetSamples(
            }
            assert( LE_32( (Word32) nTimeScalerOutSamples, APA_BUF ) );
            nSamplesTcsScaled = idiv1616U( extract_l( nTimeScalerOutSamples ), nTransportChannels );
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
            hIvasDec->timeScalingDone = 1;
            move16();
#endif
        }
        ELSE
        {
            nSamplesTcsScaled = hIvasDec->nSamplesFrame;
            move16();
        }
#ifdef DEBUG_MODE_JBM
        dbgwrite( &nTimeScalerOutSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_nTimeScaleOutSamples.dat" );
#endif

        /* Feed decoded transport channels samples to the renderer */
        IF( NE_32( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer_fx ) ), IVAS_ERR_OK ) )
        {
            return error;
        }
#ifdef DEBUG_MODE_JBM
        dbgwrite( &nResidualSamples, sizeof( int16_t ), 1, 1, "./res/JBM_nResidualSamples.dat" );
#endif


        IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm )
        {
@@ -1559,6 +1589,9 @@ static ivas_error IVAS_DEC_GetBufferedNumberOfSamples(
    if ( hIvasDec->st_ivas->hTcBuffer != NULL )
    {
        *nSamplesBuffered = sub( hIvasDec->st_ivas->hTcBuffer->n_samples_buffered, hIvasDec->st_ivas->hTcBuffer->n_samples_rendered );
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
        *nSamplesBuffered = add( *nSamplesBuffered, hIvasDec->hVoIP->nSamplesRendered20ms );
#endif
        move16();
    }

@@ -2685,7 +2718,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
    UWord32 extBufferedTime_ms, scale, maxScaling;
    JB4_DATAUNIT_HANDLE dataUnit;
    UWord16 extBufferedSamples;
#ifndef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    Word16 timeScalingDone;
#endif
    Word16 result;
    ivas_error error;
    Word16 nSamplesRendered;
@@ -2694,7 +2729,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
    st_ivas = hIvasDec->st_ivas;
    hDecoderConfig = st_ivas->hDecoderConfig;
    hVoIP = hIvasDec->hVoIP;
#ifndef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    timeScalingDone = 0;
#endif
    nOutChannels = (UWord8) st_ivas->hDecoderConfig->nchan_out;
    nSamplesRendered = 0;
    move16();
@@ -2722,7 +2759,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
                }
            }

#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
            extBufferedSamples = nSamplesBuffered;
            move16();
#else
            extBufferedSamples = add( nSamplesRendered, nSamplesBuffered );
#endif
            Word16 exp;
            extBufferedTime_ms = BASOP_Util_Divide3232_Scale( imult3216( extBufferedSamples, 1000 ), hDecoderConfig->output_Fs, &exp );
            extBufferedTime_ms = (UWord32) W_shr( extBufferedTime_ms, sub( 15, exp ) ); // Q0
@@ -2745,19 +2787,33 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
            }
            maxScaling = Mult_32_32( imult3216( hDecoderConfig->output_Fs, (Word16) maxScaling ), INV_1000_Q31 );

#ifdef DEBUG_MODE_JBM
            dbgwrite( &extBufferedSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_extBufferedSamples.dat" );
            dbgwrite( &systemTimestamp_ms, sizeof( uint32_t ), 1, 1, "./res/JBM_systemTimestamp.dat" );
            dbgwrite( &scale, sizeof( uint32_t ), 1, 1, "./res/JBM_scale.dat" );
            dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" );
#endif

            /* avoid time scaling multiple times in one sound card slot */
            IF( NE_64( scale, 100U ) )
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
            {
                IF( hIvasDec->timeScalingDone )
#else
                {
                    IF( timeScalingDone )
#endif
                {
                    scale = 100;
                    move32();
                }
#ifndef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
                ELSE
                {
                    timeScalingDone = 1;
                    move16();
                }
#endif
            }

            /* limit scale to range supported by time scaler */
@@ -2850,6 +2906,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
            hIvasDec->nSamplesAvailableNext = sub( hIvasDec->nSamplesAvailableNext, nSamplesToZero );
            move16();
            move16();
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
            update_voip_rendered20ms( hIvasDec, nSamplesToZero );
#endif
        }
        ELSE
        {
@@ -2864,12 +2923,45 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
            }

            nSamplesRendered = add( nSamplesRendered, nSamplesRendered_loop );
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
            update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop );
#endif
        }
    }

    return IVAS_ERR_OK;
}

#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
/*---------------------------------------------------------------------*
 * update_voip_rendered20ms( )
 *
 * Function to flush remaining audio in VoIP
 *---------------------------------------------------------------------*/

static void update_voip_rendered20ms(
    IVAS_DEC_HANDLE hIvasDec,
    const Word16 nSamplesRendered )
{
    Word16 nSamplesRenderedTotal;
    nSamplesRenderedTotal = add( hIvasDec->hVoIP->nSamplesRendered20ms, nSamplesRendered );
    /* we have crossed a 20ms border, reset the time scaling done flag */
    IF( GE_16( nSamplesRenderedTotal, hIvasDec->hVoIP->nSamplesFrame ) )
    {
        hIvasDec->timeScalingDone = 0;
        move16();
    }

    /* float code was: hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal % hIvasDec->hVoIP->nSamplesFrame; */
    hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal;
    move16();
    WHILE( GE_16( hIvasDec->hVoIP->nSamplesRendered20ms, hIvasDec->hVoIP->nSamplesFrame ) )
    {
        hIvasDec->hVoIP->nSamplesRendered20ms = sub( hIvasDec->hVoIP->nSamplesRendered20ms, hIvasDec->hVoIP->nSamplesFrame );
    }
}

#endif

/*---------------------------------------------------------------------*
 * IVAS_DEC_VoIP_Flush( )
@@ -2895,7 +2987,22 @@ ivas_error IVAS_DEC_Flush(
    move16();

    /* render IVAS frames  */
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    error = IVAS_ERR_OK;

    test();
    IF( GT_16( nSamplesToRender, 0 ) && NE_16( (Word16) hIvasDec->st_ivas->ivas_format, (Word16) MONO_FORMAT ) )
    {
#endif
        error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf );
#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE
    }
    ELSE
    {
        *nSamplesFlushed = 0;
        move16();
    }
#endif

    return error;
}