Commit 18624e76 authored by vasilache's avatar vasilache
Browse files

Merge branch 'nokia/contribution-45-masa-hr-metadata' into 'main'

[Non-BE] Implements contribution 45 - MASA metadata HR encoding

See merge request !546
parents 2193500c df086053
Loading
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1137,6 +1137,9 @@ enum
#define MASA_DIRECTION_MAX_BITS                 11
#define MASA_NO_INDEX                           32767
#define MASA_BITS_ER                            3
#ifdef HR_METADATA
#define MASA_BITS_ER_HR                         4
#endif
#define MASA_MIN_BITS_TF                        4
#define MASA_LIMIT_2D                           2
#define MASA_NO_CV_COH                          8
@@ -1155,6 +1158,12 @@ enum
#define MASA_COH_LIMIT_2IDX                     144                         /* limit for sum of values across components for having two joint indexes */
#define QMETADATA_MAX_NO_DIRECTIONS             2
#define MASA_MAX_BITS                           1300                        /* max. bit-budget for MASA metadata */

#ifdef HR_METADATA
#define MASA_MAX_BITS_HR                        2000                        /* max. bit-budget for MASA metadata in HR mode*/
#define HR_MASA_ER_LEVELS                       16
#endif

#define LIMIT_ER_ELEVATION_ENC                  4
#define LIMIT_ER_SIMPLE_ENC                     6
#define LIMIT_USE_COMMON                        3
@@ -1183,7 +1192,12 @@ enum
#define MASA_STEREO_MIN_BITRATE                 IVAS_24k4

#define MASA_BIT_REDUCT_PARAM                   10
#ifdef HR_METADATA
#define MASA_MAXIMUM_TWO_DIR_BANDS             24
#define NBITS_HR_COH                          4
#else
#define MASA_MAXIMUM_TWO_DIR_BANDS             18
#endif
typedef enum
{
    MASA_STEREO_NOT_DEFINED,
+177 −0
Original line number Diff line number Diff line
@@ -411,3 +411,180 @@ void masa_sample_rate_band_correction(

    return;
}

#ifdef HR_METADATA
/* !r: output index for direction */
uint16_t index_theta_phi_16(
    float *p_theta,               /* i/o  : input elevation to be indexed */
    float *p_phi,                 /* i/o  : input azimuth to be indexed  */
    SPHERICAL_GRID_DATA *gridData /* i  : generated grid data */
)
{
    float abs_theta;
    int16_t sign_th, id_phi, id_th;
    uint16_t idx_sph;
    uint16_t cum_n;
    float theta_hat, phi_hat;
    float theta, phi;

    theta = *p_theta;
    phi = *p_phi;
    phi_hat = 0;
    theta_hat = 0;
    phi = phi + 180;

    if ( theta < 0 )
    {
        abs_theta = -theta;
        sign_th = -1;
    }
    else
    {
        abs_theta = theta;
        sign_th = 1;
    }

    id_th = quantize_theta( abs_theta, gridData->no_theta, &theta_hat );
    if ( gridData->no_theta > 1 )
    {
        if ( gridData->no_phi[id_th] > 1 )
        {
            id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] );
        }
        else
        {
            id_phi = 0;
            phi_hat = 180;
        }
    }
    else
    {
        id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] );
    }
    *p_theta = sign_th * theta_hat;
    *p_phi = phi_hat - 180;

    /* Starting from Equator, alternating positive and negative */
    if ( id_th == 0 )
    {
        idx_sph = id_phi;
    }
    else
    {
        if ( id_th == gridData->no_theta - 1 )
        {
            idx_sph = 65534 + ( sign_th < 0 );
        }
        else
        {
            theta = MASA_ANGLE_AT_EQUATOR * (float) ( id_th + 0.5f );
            if ( id_th == 1 )
            {
                cum_n = 2 * (uint16_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
            }
            else
            {
                cum_n = 2 * (uint16_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
            }

            cum_n += gridData->no_phi[0];

            if ( sign_th > 0 )
            {
                cum_n -= 2 * gridData->no_phi[id_th];
            }
            else
            {
                cum_n -= gridData->no_phi[id_th];
            }
            idx_sph = cum_n + id_phi;
        }
    }


    return idx_sph;
}

int16_t quantize_theta(
    float x,       /* i  : theta value to be quantized  */
    int16_t no_cb, /* i  : number of codewords          */
    float *xhat    /* o  : quantized value              */
)
{
    int16_t imin;
    float diff1, diff2;

    imin = (int16_t) ( x * MASA_INV_ANGLE_AT_EQUATOR_DEG + 0.5f );

    if ( imin >= no_cb - 1 )
    {
        imin = no_cb - 1;
        diff1 = x - 90;
        diff2 = x - MASA_ANGLE_AT_EQUATOR_DEG * ( imin - 1 );
        if ( fabsf( diff1 ) > fabsf( diff2 ) )
        {
            imin--;
            *xhat = imin * MASA_ANGLE_AT_EQUATOR_DEG;
        }
        else
        {
            *xhat = 90;
        }
    }
    else
    {
        *xhat = imin * MASA_ANGLE_AT_EQUATOR_DEG;
    }

    return imin;
}


/* !r: index azimuth */
int16_t quantize_phi_masa(
    float phi,          /* i  : azimuth value                                                   */
    int16_t flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not    */
    float *phi_hat,     /* o  : quantized azimuth                                               */
    const int16_t n     /* i  : azimuth codebook size                                           */
)
{
    int16_t id_phi;
    float dd;
    float delta_phi;

    delta_phi = 360.0f / (float) n;

    if ( n == 1 )
    {
        *phi_hat = 0;

        return 0;
    }

    if ( flag_delta == 1 )
    {
        dd = delta_phi / 2.0f;
    }
    else
    {
        dd = 0;
    }

    id_phi = (int16_t) ( ( phi - dd + delta_phi / 2.0f ) / (float) delta_phi );

    if ( id_phi == n )
    {
        id_phi = 0;
    }

    if ( id_phi == -1 )
    {
        id_phi = n - 1;
    }

    *phi_hat = id_phi * delta_phi + dd;

    return id_phi;
}

#endif
+52 −0
Original line number Diff line number Diff line
@@ -2932,6 +2932,52 @@ ivas_error ivas_qmetadata_enc_encode(
    IVAS_QMETADATA *hQMetaData                                  /* i/o: q_metadata handle                       */
);

#ifdef HR_METADATA

ivas_error ivas_qmetadata_enc_encode_hr_384_512(
    BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
    IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle           */
    int16_t bits_sph_idx,
    int16_t bits_sp_coh
);
int16_t ivas_qmetadata_dec_decode_hr_384_512(
    IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle  */
    uint16_t *bitstream,              /* i  : bitstream          */
    int16_t *index,                   /* i/o: bitstream position */
    SPHERICAL_GRID_DATA *sph_grid16,   /* i: spherical grid for deindexing */
    int16_t bits_sph_idx,
    int16_t bits_sp_coh
);

void deindex_sph_idx(
    const uint16_t sphIndex,             /* i  : Spherical index            */
    const SPHERICAL_GRID_DATA *gridData, /* i  : Prepared spherical grid    */
    float *theta,                        /* o  : Elevation                  */
    float *phi                           /* o  : Azimuth                    */
);


uint16_t index_theta_phi_16(
    float * p_theta,                  /* i/o  : input elevation to be indexed */
    float * p_phi,                    /* i/o  : input azimuth to be indexed  */
    SPHERICAL_GRID_DATA *gridData /* i  : generated grid data */
);

 int16_t quantize_theta(
    float x,       /* i  : theta value to be quantized  */
    int16_t no_cb, /* i  : number of codewords          */
    float *xhat    /* o  : quantized value              */
);

/* !r: index azimuth */
 int16_t quantize_phi_masa(
    float phi,          /* i  : azimuth value                                                   */
    int16_t flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not    */
    float *phi_hat,     /* o  : quantized azimuth                                               */
    const int16_t n     /* i  : azimuth codebook size                                           */
);
#endif

void reset_metadata_spatial(
    const IVAS_FORMAT ivas_format,                              /* i  : IVAS format                             */
    BSTR_ENC_HANDLE hMetaData,                                  /* i/o: Metadata bitstream handle               */
@@ -2958,6 +3004,8 @@ int16_t ivas_qmetadata_dec_decode(
    int16_t *index                                              /* i/o: bitstream position                      */
);



/*! r: number of bits read */
int16_t ivas_qmetadata_dec_sid_decode(
    IVAS_QMETADATA_HANDLE hQMetaData,                           /* i/o: q_metadata handle                       */
@@ -3032,6 +3080,10 @@ void quantize_direction_frame(
    IVAS_QDIRECTION *q_direction,                               /* i/o: quantized direction structure           */
    float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] 
#ifdef HR_METADATA
    ,
    int16_t is_hr
#endif
);

/* !r: quantized spherical index */
+47 −1
Original line number Diff line number Diff line
@@ -2523,7 +2523,48 @@ const uint16_t ivas_param_mc_sym_freq_ild_delta_combined_48_16bits[2 * PARAM_MC_
/*----------------------------------------------------------------------------------*
 * MASA ROM tables
 *----------------------------------------------------------------------------------*/
#ifdef HR_METADATA
const float diffuseness_reconstructions_hr[HR_MASA_ER_LEVELS] =
{
     0.00f,
     0.0142822265625f,
     0.030029296875f,
     0.052001953125f,
     0.07708740234375f,
     0.10528564453125f,
     0.14483642578125f,
     0.19573974609375f,
     0.26568603515625f,
     0.35467529296875f, 
     0.436279296875f,
     0.510498046875f,
     0.5943603515625f,   
     0.6878662109375f,
     0.80096435546875f,
     0.93365478515625f
};
const float diffuseness_thresholds_hr[HR_MASA_ER_LEVELS + 1] =
{
    0.0f,
    0.009521484375f,
    0.01904296875f,
    0.0410156250f,
    0.06298828125f,
    0.0911865234375f,
    0.119384765625f,
    0.1702880859375f,
    0.22119140625f,
    0.3101806640625f,
    0.399169921875f,
    0.473388671875f,
    0.547607421875f,
    0.641113281250f,
    0.734619140625f,
    0.8673095703125f,
    2.0f /* out-of-range large value to make searching easier */
};
#endif
const int16_t bits_direction_masa[DIRAC_DIFFUSE_LEVELS] =
{
    11,
@@ -2536,6 +2577,7 @@ const int16_t bits_direction_masa[DIRAC_DIFFUSE_LEVELS] =
    3
};
const float coherence_cb0_masa[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH] =
{
    /* this is the same */
@@ -2718,7 +2760,11 @@ const uint8_t masa_joined_nbands[IVAS_NUM_ACTIVE_BRATES] =
const uint8_t masa_twodir_bands[IVAS_NUM_ACTIVE_BRATES] =
{
#ifdef HR_METADATA
    0,           0,           0,           0,          0,          1,          1,          1,          3,           4,           6,           6,           9,           24
#else
    0,           0,           0,           0,          0,          1,          1,          1,          3,           4,           6,           6,           9,           12
#endif
};
const uint8_t masa_twodir_bands_joined[IVAS_NUM_ACTIVE_BRATES] =
+5 −0
Original line number Diff line number Diff line
@@ -289,6 +289,11 @@ extern const uint8_t masa_joined_nbands[];
extern const uint8_t masa_twodir_bands[];
extern const uint8_t masa_twodir_bands_joined[];

#ifdef HR_METADATA
extern const float diffuseness_reconstructions_hr[HR_MASA_ER_LEVELS];
extern const float diffuseness_thresholds_hr[HR_MASA_ER_LEVELS + 1];
#endif

/* Multi-channel input and output setups */
extern const float ls_azimuth_CICP2[2];
extern const float ls_elevation_CICP2[2];
Loading