Commit 33920dcf authored by Marek Szczerba's avatar Marek Szczerba
Browse files

Support for multiple acoustic environments plus early reflections in...

Support for multiple acoustic environments plus early reflections in text-based configuration (prototype)
parent 457ffd79
Loading
Loading
Loading
Loading
+128 −18
Original line number Diff line number Diff line
@@ -1619,9 +1619,7 @@ static ivas_error RenderConfigReader_readBinReverb(
            {
                return IVAS_ERR_FAILED_ALLOC;
            }
            /* Initialize memory pointers to allow safe freeing ico eg errors */
            pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff = 0;
            pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = 0;
            pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = NULL;

            /* Room sizes */
            if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK )
@@ -1735,10 +1733,15 @@ ivas_error RenderConfigReader_read(
    FREQ_GRID_MODE fgMode;
    float freqHop;
    uint32_t acIdx;
    uint32_t defGridId, defGridLen, defGridSubGrid, defGridOffset, defGridNrBands;
    uint32_t defGridId, defGridLen, defGridOffset, defGridNrBands;
    const float *pDefGrid;
    uint32_t hasER;
    float erTemp[N_ABS_COEFFS];
    uint32_t roomAcHasFgCount, roomAcHasAcEnvCount;
    uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop;
    uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr;
#ifdef CONTROL_METADATA_EARLY_REFLECTIONS
    uint32_t aeHasER, aeHasERsize, aeHasERabs;
#endif
#else
    int16_t nBandsInput;
    int16_t nVectorsMissing;
@@ -1752,6 +1755,7 @@ ivas_error RenderConfigReader_read(
    pTemp = (char *) calloc( file_size + 1, sizeof( char ) );
#ifdef CONTROL_METADATA_REVERB
    acIdx = 0;
    roomAcHasFgCount = roomAcHasAcEnvCount = FALSE;
#else
    nBandsInput = hRenderConfig->room_acoustics.nBands;
    nVectorsMissing = N_REVERB_VECTORS;
@@ -1814,12 +1818,14 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%d", &pRenderConfigReader->nFG ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        /* Allocate memory for the frequency grids */
                        if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL )
                        {
                            return IVAS_ERR_FAILED_ALLOC;
                        }
                        roomAcHasFgCount = TRUE;
                    }
                    else if ( strcmp( item, "ACOUSTICENVIRONMENTCOUNT" ) == 0 )
                    {
@@ -1827,6 +1833,7 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%d", &pRenderConfigReader->nAE ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        /* Allocate memory for the acoustic environments array */
                        if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL )
@@ -1843,7 +1850,22 @@ ivas_error RenderConfigReader_read(
#endif
                        }
                        acIdx = 0;
                        roomAcHasAcEnvCount = TRUE;
                    }
                }
#ifdef DEBUGGING
                if ( roomAcHasFgCount == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: frequencyGridCount missing from 'roomAcoustics' chapter.\n\n" );
                }
                if ( roomAcHasAcEnvCount == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: acousticEnvironmentCount missing from 'roomAcoustics' chapter.\n\n" );
                }
#endif
                if ( roomAcHasFgCount == FALSE || roomAcHasAcEnvCount == FALSE )
                {
                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                }
                free( pValue );
            }
@@ -1863,6 +1885,7 @@ ivas_error RenderConfigReader_read(
                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                }

                fgHasMethod = fgHasNBands = fgHasFreqs = fgHasDefaultGrid = fgHasStartFreq = fgHasFreqHop = FALSE;
                fgMode = FREQ_GRID_MODE_UNKNOWN;
                params_idx = 0;
                pValue = (char *) calloc( strlen( pParams ), sizeof( char ) );
@@ -1886,6 +1909,7 @@ ivas_error RenderConfigReader_read(
                        {
                            fgMode = FREQ_GRID_MODE_DEFAULT_BANDING;
                        }
                        fgHasMethod = TRUE;
                    }
                    /* Read number of bands for individual frequency, start-hop-amount mode */
                    else if ( strcmp( item, "NBANDS" ) == 0 )
@@ -1897,12 +1921,14 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%d", &pRenderConfigReader->pFG[idx].nrBands ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        /* Allocate memory for the center frequency array */
                        if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( pRenderConfigReader->pFG[idx].nrBands * sizeof( float ) ) ) == NULL )
                        {
                            return IVAS_ERR_FAILED_ALLOC;
                        }
                        fgHasNBands = TRUE;
                    }
                    else if ( strcmp( item, "FREQUENCIES" ) == 0 )
                    {
@@ -1914,7 +1940,9 @@ ivas_error RenderConfigReader_read(
                        if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pFG[idx].pFc ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        fgHasFreqs = TRUE;
                    }
                    else if ( strcmp( item, "STARTFREQUENCY" ) == 0 )
                    {
@@ -1925,7 +1953,9 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%f", &pRenderConfigReader->pFG[idx].pFc[0] ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        fgHasStartFreq = TRUE;
                    }
                    else if ( strcmp( item, "FREQUENCYHOP" ) == 0 )
                    {
@@ -1936,12 +1966,14 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%f", &freqHop ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        /* Fill up the center frequency array */
                        for ( i = 1; i < pRenderConfigReader->pFG[idx].nrBands; i++ )
                        {
                            pRenderConfigReader->pFG[idx].pFc[i] = pRenderConfigReader->pFG[idx].pFc[i - 1] * freqHop;
                        }
                        fgHasFreqHop = TRUE;
                    }
                    /* Handle default grids, with optional sub-grids */
                    else if ( strcmp( item, "DEFAULTGRID" ) == 0 )
@@ -1949,6 +1981,7 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%d", &defGridId ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }

                        switch ( defGridId )
@@ -1992,28 +2025,28 @@ ivas_error RenderConfigReader_read(
                            default:
                                return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        fgHasDefaultGrid = TRUE;

                        /* Handle sub-grids */
                        defGridSubGrid = FALSE;
                        defGridOffset = 0;
                        defGridNrBands = defGridLen;


                        while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 )
                        {
                            if ( strcmp( item, "DEFAULTGRIDOFFSET" ) == 0 )
                            {
                                defGridSubGrid = TRUE;
                                if ( !sscanf( pValue, "%d", &defGridOffset ) )
                                {
                                    errorHandler( item, ERROR_VALUE_INVALID );
                                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                                }
                            }
                            else if ( strcmp( item, "DEFAULTGRIDNRBANDS" ) == 0 )
                            {
                                defGridSubGrid = TRUE;
                                if ( !sscanf( pValue, "%d", &defGridNrBands ) )
                                {
                                    errorHandler( item, ERROR_VALUE_INVALID );
                                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                                }
                            }
                            else
@@ -2023,8 +2056,11 @@ ivas_error RenderConfigReader_read(
                            params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 );
                        }

                        if ( defGridSubGrid == TRUE && defGridOffset + defGridNrBands > defGridLen )
                        if ( defGridOffset + defGridNrBands > defGridLen )
                        {
#ifdef DEBUGGING
                            fprintf( stderr, "Rendering configuration: Invalid default banding selection.\n\n" );
#endif
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        pRenderConfigReader->pFG[idx].nrBands = defGridNrBands;
@@ -2048,6 +2084,16 @@ ivas_error RenderConfigReader_read(
                    }
#endif
                }
                if ( fgHasMethod == FALSE ||
                     ( fgMode == FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && ( fgHasFreqs == FALSE || fgHasNBands == FALSE ) ) ||
                     ( fgMode == FREQ_GRID_MODE_DEFAULT_BANDING && fgHasDefaultGrid == FALSE ) ||
                     ( fgMode == FREQ_GRID_MODE_START_HOP_AMOUNT && ( fgHasStartFreq == FALSE || fgHasFreqHop == FALSE || fgHasNBands == FALSE ) ) )
                {
#ifdef DEBUGGING
                    fprintf( stderr, "Rendering configuration: inconsistent default frequency band configuration.\n\n" );
#endif
                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                }
                free( pValue );
            }
            /* Handle multiple acoustic environments */
@@ -2060,6 +2106,10 @@ ivas_error RenderConfigReader_read(
                idx = strtol( strtok( NULL, ":" ), NULL, 0 );
                pRenderConfigReader->pAE->id = idx;

                aeHasFgIdx = aeHasPredelay = aeHasRt60 = aeHasDsr = FALSE;
#ifdef CONTROL_METADATA_EARLY_REFLECTIONS
                aeHasER = aeHasERsize = aeHasERabs = FALSE;
#endif
                params_idx = 0;
                pValue = (char *) calloc( strlen( pParams ), sizeof( char ) );
                while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 )
@@ -2074,6 +2124,7 @@ ivas_error RenderConfigReader_read(
                        if ( !sscanf( pValue, "%d", &i ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        if ( i > pRenderConfigReader->nFG || &pRenderConfigReader->pFG[i] == NULL )
                        {
@@ -2091,45 +2142,53 @@ ivas_error RenderConfigReader_read(
                        {
                            return IVAS_ERR_FAILED_ALLOC;
                        }

                        aeHasFgIdx = TRUE;
                    }
                    /* Pre-delay */
                    if ( strcmp( item, "PREDELAY" ) == 0 )
                    else if ( strcmp( item, "PREDELAY" ) == 0 )
                    {
                        if ( !sscanf( pValue, "%f", &pRenderConfigReader->pAE[acIdx].preDelay ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        aeHasPredelay = TRUE;
                    }
                    /* RT60 */
                    if ( strcmp( item, "RT60" ) == 0 )
                    else if ( strcmp( item, "RT60" ) == 0 )
                    {
                        if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        aeHasRt60 = TRUE;
                    }
                    /* DSR */
                    if ( strcmp( item, "DSR" ) == 0 )
                    else if ( strcmp( item, "DSR" ) == 0 )
                    {
                        if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        aeHasDsr = TRUE;
                    }
#ifdef CONTROL_METADATA_EARLY_REFLECTIONS
                    if ( strcmp( item, "HASEARLYREFLECTIONS" ) == 0 )
                    else if ( strcmp( item, "HASEARLYREFLECTIONS" ) == 0 )
                    {
                        if ( read_txt_bool( pValue, &hasER ) )
                        if ( read_txt_bool( pValue, &aeHasER ) )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        if ( hasER == TRUE )
                        if ( aeHasER == TRUE )
                        {
                            if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL )
                            {
                                return IVAS_ERR_FAILED_ALLOC;
                            }
                            aeHasERsize = aeHasERabs = FALSE;
                            while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 )
                            {
                                if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 )
@@ -2137,28 +2196,33 @@ ivas_error RenderConfigReader_read(
                                    if ( read_txt_vector( pValue, 3, erTemp ) )
                                    {
                                        errorHandler( item, ERROR_VALUE_INVALID );
                                        return IVAS_ERR_INVALID_RENDER_CONFIG;
                                    }
                                    pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.x = erTemp[0];
                                    pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.y = erTemp[1];
                                    pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.z = erTemp[2];
                                    aeHasERsize = TRUE;
                                }
                                else if ( strcmp( item, "ABSORPTIONCOEFFS" ) == 0 )
                                {
                                    if ( read_txt_vector( pValue, N_ABS_COEFFS, erTemp ) )
                                    {
                                        errorHandler( item, ERROR_VALUE_INVALID );
                                        return IVAS_ERR_INVALID_RENDER_CONFIG;
                                    }

                                    for ( i = 0; i < N_ABS_COEFFS; i++ )
                                    {
                                        pRenderConfigReader->pAE[acIdx].pEarlyReflections->pAbsCoeff[i] = erTemp[i];
                                    }
                                    aeHasERabs = TRUE;
                                }
                                else if ( strcmp( item, "LISTENERORIGIN" ) )
                                {
                                    if ( read_txt_vector( pValue, 3, erTemp ) )
                                    {
                                        errorHandler( item, ERROR_VALUE_INVALID );
                                        return IVAS_ERR_INVALID_RENDER_CONFIG;
                                    }
                                    if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL )
                                    {
@@ -2177,7 +2241,52 @@ ivas_error RenderConfigReader_read(
                        }
                    }
#endif
#ifdef DEBUGGING
                    else
                    {
                        fprintf( stderr, "Unsupported configuration property %s\n", item );
                    }
#endif
                }
#ifdef DEBUGGING
                if ( aeHasFgIdx == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: frequencyGridIndex missing from 'acousticEnvironment' %d.\n\n", acIdx );
                }
                if ( aeHasPredelay == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: predelay missing from 'acousticEnvironment' %d.\n\n", acIdx );
                }
                if ( aeHasRt60 == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: RT60 missing from 'acousticEnvironment' %d.\n\n", acIdx );
                }
                if ( aeHasDsr == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: DSR missing from 'acousticEnvironment' %d.\n\n", acIdx );
                }
#ifdef CONTROL_METADATA_EARLY_REFLECTIONS
                if ( aeHasER == TRUE && aeHasERsize == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: early reflections room size missing from 'acousticEnvironment' %d.\n\n", acIdx );
                }
                if ( aeHasER == TRUE && aeHasERabs == FALSE )
                {
                    fprintf( stderr, "Renderer configuration: early reflections absorption coeffs missing from 'acousticEnvironment' %d.\n\n", acIdx );
                }
#endif
#endif
                if ( aeHasFgIdx == FALSE || aeHasPredelay == FALSE || aeHasRt60 == FALSE || aeHasDsr == FALSE )
                {
                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                }
#ifdef CONTROL_METADATA_EARLY_REFLECTIONS
                if ( aeHasER && ( aeHasERsize == FALSE || aeHasERabs == FALSE ) )
                {
                    return IVAS_ERR_INVALID_RENDER_CONFIG;
                }
#endif

                free( pValue );
                acIdx++;
            }
@@ -2297,6 +2406,7 @@ ivas_error RenderConfigReader_read(
                        if ( ( error = RenderConfigReader_readBinReverb( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK )
                        {
                            errorHandler( item, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                        free( pCombinedName );
                    }
@@ -2318,6 +2428,7 @@ ivas_error RenderConfigReader_read(
                        else
                        {
                            errorHandler( pValue, ERROR_VALUE_INVALID );
                            return IVAS_ERR_INVALID_RENDER_CONFIG;
                        }
                    }
                    else if ( strcmp( item, "DIRECTIVITY" ) == 0 )
@@ -2442,7 +2553,6 @@ void RenderConfigReader_close(
        if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL )
        {
            free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin );
            free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff );
            free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections );
        }
#endif