Commit 4c989a0f authored by Marek Szczerba's avatar Marek Szczerba
Browse files

Orientation tracking refactoring. Added six test cases for average orientation tracking.

parent 524cad29
Loading
Loading
Loading
Loading
+65 −65
Original line number Diff line number Diff line
@@ -58,27 +58,27 @@
 *------------------------------------------------------------------------------------------*/

#ifdef FIX_I109_ORIENTATION_TRACKING
Quaternion QuaternionProduct( const Quaternion q1, const Quaternion q2 );
float QuaternionDotProduct( const Quaternion q1, const Quaternion q2 );
Quaternion QuaternionDivision( const Quaternion q, const float d );
Quaternion QuaternionNormalize( const Quaternion q );
Quaternion QuaternionSlerp( const Quaternion q1, const Quaternion q2, const float t );
Quaternion QuaternionConjugate( const Quaternion q );
void QuaternionProduct( const Quaternion q1, const Quaternion q2, Quaternion *const result );
float QuaternionDotProduct( const Quaternion q1, const Quaternion );
void QuaternionDivision( const Quaternion q, const float d, Quaternion *const result );
void QuaternionNormalize( const Quaternion q, Quaternion *const result );
void QuaternionSlerp( const Quaternion q1, const Quaternion q2, const float t, Quaternion *const result );
void QuaternionConjugate( const Quaternion q, Quaternion *const result );
float QuaternionAngle( const Quaternion q1, const Quaternion q2 );
Quaternion QuaternionInverse( const Quaternion q );
void QuaternionInverse( const Quaternion q, Quaternion *const result );

Quaternion QuaternionProduct(
void QuaternionProduct(
    const Quaternion q1,
    const Quaternion q2 )
    const Quaternion q2,
    Quaternion *const r )
{
    Quaternion r;
    Quaternion tmp;
    tmp.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
    tmp.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
    tmp.y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x;
    tmp.z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w;

    r.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
    r.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
    r.y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x;
    r.z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w;

    return r;
    *r = tmp;
}

float QuaternionDotProduct(
@@ -88,61 +88,58 @@ float QuaternionDotProduct(
    return q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
}

Quaternion QuaternionDivision(
void QuaternionDivision(
    const Quaternion q,
    const float d )
    const float d,
    Quaternion *const r )
{
    Quaternion r = q;
    r.w = r.w / d;
    r.x = r.x / d;
    r.y = r.y / d;
    r.z = r.z / d;
    return r;
    r->w = q.w / d;
    r->x = q.x / d;
    r->y = q.y / d;
    r->z = q.z / d;
}

Quaternion QuaternionNormalize(
    const Quaternion q )
void QuaternionNormalize(
    const Quaternion q,
    Quaternion *const r )
{
    Quaternion r = q;
    r = QuaternionDivision( r, sqrtf( QuaternionDotProduct( r, r ) ) );
    return r;
    QuaternionDivision( q, sqrtf( QuaternionDotProduct( q, q ) ), r );
}

Quaternion QuaternionSlerp(
void QuaternionSlerp(
    const Quaternion q1,
    const Quaternion q2,
    const float t )
    const float t,
    Quaternion *const r )
{
    Quaternion r;
    float angle, denom, s, s2;

    angle = acosf( QuaternionDotProduct( q1, q2 ) );
    denom = sinf( angle );

    // check if denom is zero means same rotation
    if ( denom < 0.0001F && denom > -0.0001F )
    s = QuaternionDotProduct( q1, q2 );
    if ( fabsf(s) >= 1.0f )
    {
        return q2;
        *r = q2;
        return;
    }
    angle = acosf( s );
    denom = sinf( angle );

    s = sinf( 1 - t ) * angle;
    s2 = sinf( t * angle );
    r.x = ( q1.x * s + q2.x * s2 ) / denom;
    r.y = ( q1.y * s + q2.y * s2 ) / denom;
    r.z = ( q1.z * s + q2.z * s2 ) / denom;
    r.w = ( q1.w * s + q2.w * s2 ) / denom;
    r->x = ( q1.x * s + q2.x * s2 ) / denom;
    r->y = ( q1.y * s + q2.y * s2 ) / denom;
    r->z = ( q1.z * s + q2.z * s2 ) / denom;
    r->w = ( q1.w * s + q2.w * s2 ) / denom;

    return QuaternionNormalize( r );
    QuaternionNormalize( *r, r );
}

Quaternion QuaternionConjugate(
    const Quaternion q )
void QuaternionConjugate(
    const Quaternion q,
    Quaternion *const r )
{
    Quaternion r = q;
    r.x = -r.x;
    r.y = -r.y;
    r.z = -r.z;
    return r;
    r->w =  q.w;
    r->x = -q.x;
    r->y = -q.y;
    r->z = -q.z;
}

float QuaternionAngle(
@@ -151,22 +148,21 @@ float QuaternionAngle(
{
    Quaternion q12;
    float angle;

    q12 = QuaternionProduct( QuaternionConjugate( q1 ), q2 );
    QuaternionConjugate( q1, &q12 );
    QuaternionProduct( q12, q2, &q12 );
    angle = 2.0f * atan2f( sqrtf( q12.x * q12.x + q12.y * q12.y + q12.z * q12.z ), q12.w );
    return angle;
}

Quaternion QuaternionInverse(
    const Quaternion q )
void QuaternionInverse(
    const Quaternion q,
    Quaternion *const r )
{
    Quaternion r;
    float dot_product;

    dot_product = QuaternionDotProduct( q, q );
    r = QuaternionConjugate( q );
    r = QuaternionDivision( r, dot_product );
    return r;
    QuaternionConjugate( q, r );
    QuaternionDivision( *r, dot_product, r );
}

#else
@@ -311,12 +307,16 @@ ivas_error ivas_orient_trk_Process(
    float cutoffFrequency;
    float alpha = pOTR->alpha;
    float ang;
    Quaternion tq;

    if ( pOTR->trackingType == OTR_TRACKING_AVG_ORIENT )
    {
        /* Compute average (low-pass filtered) absolute orientation */
        pOTR->absAvgRot = QuaternionSlerp( pOTR->absAvgRot, absRot, alpha );
        QuaternionSlerp( pOTR->absAvgRot, absRot, alpha, &pOTR->absAvgRot );

        *pTrkRot = pOTR->absAvgRot;
        /* Compute relative orientation = (absolute orientation) - (average absolute orientation) */
        QuaternionInverse( pOTR->absAvgRot, pTrkRot );
        QuaternionProduct( *pTrkRot, absRot, pTrkRot );

        /* Adapt LPF constant based on orientation excursion relative to current mean:
        - low  cutoff (slow adaptation) for small excursions (around center)
@@ -358,7 +358,8 @@ ivas_error ivas_orient_trk_Process(
            pOTR->alpha = sinf( 2.0f * EVS_PI * pOTR->centerAdaptationRate / updateRate );

            /* Compute relative orientation = (absolute orientation) - (reference orientation) */
            *pTrkRot = QuaternionProduct( QuaternionInverse( pOTR->refRot ), absRot );
            QuaternionInverse( pOTR->refRot, pTrkRot );
            QuaternionProduct( *pTrkRot, absRot, pTrkRot );
        }
        else
        {
@@ -367,8 +368,7 @@ ivas_error ivas_orient_trk_Process(
    }
#else
ivas_error ivas_orient_trk_Process(
    ivas_orient_trk_state_t *pOTR
)
    ivas_orient_trk_state_t *pOTR )
{
    float yaw;
    float pitch;
+24 −0
Original line number Diff line number Diff line
@@ -400,6 +400,10 @@
../IVAS_cod -ism 4 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv 256000 48 testv/stv4ISM48s.pcm bit
../IVAS_dec -t testv/headrot_case03_3000_q.csv BINAURAL 48 bit testv/stv4ISM48s.pcm_256000_48-48_TDHR.tst

// 4 ISm with metadata at 256 kbps, 48 kHz in, 48 kHz out, TD BINAURAL out, head rotation, Orientation tracking
../IVAS_cod -ism 4 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv 256000 48 testv/stv4ISM48s.pcm bit
../IVAS_dec -t testv/headrot.csv -otr avg BINAURAL 48 bit testv/stv4ISM48s.pcm_256000_48-48_TDHR_OtrAvg.tst

// 1 ISm with metadata bitrate switching from 13.2 kbps to 128 kbps, 32 kHz in, 32 kHz out, mono out, DTX on
../IVAS_cod -dtx -ism 1 testv/stvISM1.csv ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 32 testv/stv32c.pcm bit
../IVAS_dec MONO 32 bit testv/stv32c.pcm_brate_sw_32-32_mono_dtx.tst
@@ -441,6 +445,10 @@
../IVAS_cod -sba 3 24400 32 testv/stv3OA32c.pcm bit
../IVAS_dec -t testv/headrot.csv BINAURAL 32 bit testv/stv3OA32c.pcm_SBA_24400_32-32_Binaural_Headrot.tst

// SBA at 24.4 kbps, 32kHz in, 32kHz out, BINAURAL out, Headrotation, Orientation tracking
../IVAS_cod -sba 3 24400 32 testv/stv3OA32c.pcm bit
../IVAS_dec -t testv/headrot.csv -otr avg BINAURAL 32 bit testv/stv3OA32c.pcm_SBA_24400_32-32_Binaural_Headrot_OtrAvg.tst

// SBA at 24.4 kbps, 32kHz in, 32kHz out, DTX on, BINAURAL out, random FEC at 5%
../IVAS_cod -sba 3 -dtx 24400 32 testv/stv3OA32c.pcm bit
../IVAS_dec -fec 5 BINAURAL 32 bit testv/stv3OA32c.pcm_SBA_24400_32-32_DTX_Binaural_FEC5.tst
@@ -485,6 +493,10 @@
../IVAS_cod -sba 3 48000 32 testv/stv3OA32c.pcm bit
../IVAS_dec -t testv/headrot.csv BINAURAL_ROOM 32 bit testv/stv3OA32c.pcm_SBA_48000_32-32_BinauralRoom_Headrot.tst

// SBA at 48 kbps, 32kHz in, 32kHz out, BINAURAL ROOM out, Headrotation, Orientation tracking
../IVAS_cod -sba 3 48000 32 testv/stv3OA32c.pcm bit
../IVAS_dec -t testv/headrot.csv -otr avg BINAURAL_ROOM 32 bit testv/stv3OA32c.pcm_SBA_48000_32-32_BinauralRoom_Headrot_OtrAvg.tst

// SBA at 48 kbps, 32kHz in, 32kHz out, DTX on, BINAURAL out, random FEC at 5%
../IVAS_cod -sba 3 -dtx 48000 32 testv/stv3OA32c.pcm bit
../IVAS_dec -fec 5 BINAURAL 32 bit testv/stv3OA32c.pcm_SBA_48000_32-32_DTX_Binaural_FEC5.tst
@@ -650,6 +662,14 @@
../IVAS_cod -masa 2 testv/stv_IVASMASA_1dir2TC.met 32000 48 testv/stv_IVASMASA_1dir2TC.pcm bit
../IVAS_dec -t testv/headrot.csv BINAURAL_ROOM 48 bit testv/stv_IVASMASA_1dir2TC.pcm_32000_48-48_BinauralRoom_Headrot.tst

// MASA 1dir 2TC at 32 kbps, 48kHz in, 48kHz out, BINAURAL ROOM out, Headrotation, Orientation tracking
../IVAS_cod -masa 2 testv/stv_IVASMASA_1dir2TC.met 32000 48 testv/stv_IVASMASA_1dir2TC.pcm bit
../IVAS_dec -t testv/headrot.csv -otr avg BINAURAL_ROOM 48 bit testv/stv_IVASMASA_1dir2TC.pcm_32000_48-48_BinauralRoom_Headrot_OtrAvg.tst

// MASA 1dir 2TC at 32 kbps, 48kHz in, 48kHz out, BINAURAL ROOM out, Headrotation, Orientation tracking
../IVAS_cod -masa 2 testv/stv_IVASMASA_1dir2TC.met 32000 48 testv/stv_IVASMASA_1dir2TC.pcm bit
../IVAS_dec -t testv/headrot.csv -otr avg BINAURAL_ROOM 48 bit testv/stv_IVASMASA_1dir2TC.pcm_32000_48-48_BinauralRoom_Headrot_OtrAvg.tst

// MASA 1dir 2TC at 48 kbps, 48kHz in, 48kHz out, 7_1_4 out, random FEC at 5%
../IVAS_cod -masa 2 testv/stv_IVASMASA_1dir2TC.met 48000 48 testv/stv_IVASMASA_1dir2TC.pcm bit
../IVAS_dec -fec 5 7_1_4 48 bit testv/stv_IVASMASA_1dir2TC.pcm_48000_48-48_7_1_4_FEC5.tst
@@ -783,6 +803,10 @@
../IVAS_cod -mc 5_1 256000 48 testv/stv51MC48c.pcm bit
../IVAS_dec -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM 48 bit testv/stv51MC48c.pcm_MC51_256000_48-48_BinauralRoom_Headrot.tst

// Multi-channel 5_1 at 256 kbps, 48kHz in, 48kHz out, BINAURAL ROOM out, head rotation, Orientation tracking
../IVAS_cod -mc 5_1 256000 48 testv/stv51MC48c.pcm bit
../IVAS_dec -t testv/headrot_case00_3000_q.csv -otr avg BINAURAL_ROOM 48 bit testv/stv51MC48c.pcm_MC51_256000_48-48_BinauralRoom_Headrot_OtrAvg.tst

// Multi-channel 5_1 at 384 kbps, 48kHz in, 48kHz out
../IVAS_cod -mc 5_1 384000 48 testv/stv51MC48c.pcm bit
../IVAS_dec 5_1 48 bit testv/stv51MC48c.pcm_MC51_384000_48-48_5_1.tst