Commit 9da722d6 authored by kinuthia's avatar kinuthia
Browse files

use int16_t for TD renderer fx hrtf binaries

- update matlab modelling script to write int16 instead of int32 fx
  point binaries
- update c code to read int16 instead of int32 for TD renderer
  fx hrtf values
parent 81cee0d6
Loading
Loading
Loading
Loading
Loading
+31 −93
Original line number Diff line number Diff line
@@ -269,38 +269,33 @@ static void LoadBSplineBinaryITD_fx(
)
{
    int16_t tmp, factor_Q;
#ifndef FIX_TDREND_HRTF_FILE_FORMAT_OR
    int16_t *v_tmp16;
#endif
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    int32_t *v_tmp32;
#endif
    int16_t j;
    float q_scale;
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    fread( &modelITD->elevDim3, sizeof( int16_t ), 1, f_hrtf );
    modelITD->elevKSeq_dyn = (float *) malloc( ( modelITD->elevDim3 - 2 ) * sizeof( float ) );
    v_tmp32 = (int32_t *) malloc( ( modelITD->elevDim3 - 2 ) * sizeof( int32_t ) );
    v_tmp16 = (int16_t *) malloc( ( modelITD->elevDim3 - 2 ) * sizeof( int16_t ) );
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
    fread( v_tmp32, sizeof( int32_t ), modelITD->elevDim3 - 2, f_hrtf );
    fread( v_tmp16, sizeof( int16_t ), modelITD->elevDim3 - 2, f_hrtf );
    for ( j = 0; j < modelITD->elevDim3 - 2; j++ )
    {
        modelITD->elevKSeq_dyn[j] = ( (float) v_tmp32[j] ) * q_scale;
        modelITD->elevKSeq_dyn[j] = ( (float) v_tmp16[j] ) * q_scale;
    }
    free( v_tmp32 );
    free( v_tmp16 );

    fread( &modelITD->azimDim3, sizeof( int16_t ), 1, f_hrtf );
    modelITD->azimKSeq_dyn = (float *) malloc( ( ( modelITD->azimDim3 + 1 ) / 2 - 2 ) * sizeof( float ) ); /* basis functions are flipped around 180 deg, number of basis functions above/below is (N+1)/2 */
    v_tmp32 = (int32_t *) malloc( ( ( modelITD->azimDim3 + 1 ) / 2 - 2 ) * sizeof( int32_t ) );
    v_tmp16 = (int16_t *) malloc( ( ( modelITD->azimDim3 + 1 ) / 2 - 2 ) * sizeof( int16_t ) );
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
    fread( v_tmp32, sizeof( int32_t ), ( modelITD->azimDim3 + 1 ) / 2 - 2, f_hrtf );
    fread( v_tmp16, sizeof( int16_t ), ( modelITD->azimDim3 + 1 ) / 2 - 2, f_hrtf );
    for ( j = 0; j < ( modelITD->azimDim3 + 1 ) / 2 - 2; j++ )
    {
        modelITD->azimKSeq_dyn[j] = ( (float) v_tmp32[j] ) * q_scale;
        modelITD->azimKSeq_dyn[j] = ( (float) v_tmp16[j] ) * q_scale;
    }
    free( v_tmp32 );
    free( v_tmp16 );
#else
    fread( &modelITD->N, sizeof( int16_t ), 1, f_hrtf );
    fread( &modelITD->elevDim2, sizeof( int16_t ), 1, f_hrtf );
@@ -334,22 +329,13 @@ static void LoadBSplineBinaryITD_fx(

    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    v_tmp32 = (int32_t *) malloc( tmp * sizeof( int32_t ) );
    fread( v_tmp32, sizeof( int32_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        modelITD->W_dyn[j] = ( (float) v_tmp32[j] ) * q_scale;
    }
    free( v_tmp32 );
#else
    v_tmp16 = (int16_t *) malloc( tmp * sizeof( int16_t ) );
    fread( v_tmp16, sizeof( int16_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        modelITD->W_dyn[j] = ( (float) v_tmp16[j] ) * q_scale;
    }
#endif
    free( v_tmp16 );

    /* azimuth */
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
@@ -362,15 +348,15 @@ static void LoadBSplineBinaryITD_fx(

    modelITD->azimBsShape_dyn = (float *) malloc( tmp * sizeof( float ) );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    v_tmp32 = (int32_t *) malloc( tmp * sizeof( int32_t ) );
    v_tmp16 = (int16_t *) malloc( tmp * sizeof( int16_t ) );
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
    fread( v_tmp32, sizeof( int32_t ), tmp, f_hrtf );
    fread( v_tmp16, sizeof( int16_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        modelITD->azimBsShape_dyn[j] = ( (float) v_tmp32[j] ) * q_scale;
        modelITD->azimBsShape_dyn[j] = ( (float) v_tmp16[j] ) * q_scale;
    }
    free( v_tmp32 );
    free( v_tmp16 );
#else
    v_tmp16 = (int16_t *) malloc( tmp * sizeof( int16_t ) );
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
@@ -395,24 +381,16 @@ static void LoadBSplineBinaryITD_fx(
    modelITD->elevBsShape_dyn = (float *) malloc( tmp * sizeof( float ) );

#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    v_tmp32 = (int32_t *) malloc( tmp * sizeof( int32_t ) );
    v_tmp16 = (int16_t *) malloc( tmp * sizeof( int16_t ) );
#endif
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    fread( v_tmp32, sizeof( int32_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        modelITD->elevBsShape_dyn[j] = ( (float) v_tmp32[j] ) * q_scale;
    }
    free( v_tmp32 );
#else
    fread( v_tmp16, sizeof( int16_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        modelITD->elevBsShape_dyn[j] = ( (float) v_tmp16[j] ) * q_scale;
    }
#endif
    free( v_tmp16 );
    fread( &modelITD->elevSegSamples, sizeof( int16_t ), 1, f_hrtf );

    modelITD->elevKSeq = (const float *) modelITD->elevKSeq_dyn;
@@ -506,12 +484,7 @@ static ivas_error LoadBSplineBinary_fx(
{
    ModelParams_t *model;
    int16_t i, tmp, factor_Q;
#ifndef FIX_TDREND_HRTF_FILE_FORMAT_OR
    int16_t *v_tmp16;
#endif
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    int32_t *v_tmp32;
#endif
    int32_t j, tmp32;
    float q_scale;

@@ -561,15 +534,15 @@ static ivas_error LoadBSplineBinary_fx(
    fread( &model->elevDim3, sizeof( int16_t ), 1, f_hrtf );
    model->elevKSeq_dyn = (float *) malloc( ( model->elevDim3 - 2 ) * sizeof( float ) );

    v_tmp32 = (int32_t *) malloc( ( model->elevDim3 - 2 ) * sizeof( int32_t ) );
    v_tmp16 = (int16_t *) malloc( ( model->elevDim3 - 2 ) * sizeof( int16_t ) );
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
    fread( v_tmp32, sizeof( int32_t ), model->elevDim3 - 2, f_hrtf );
    fread( v_tmp16, sizeof( int16_t ), model->elevDim3 - 2, f_hrtf );
    for ( j = 0; j < model->elevDim3 - 2; j++ )
    {
        model->elevKSeq_dyn[j] = ( (float) v_tmp32[j] * q_scale );
        model->elevKSeq_dyn[j] = ( (float) v_tmp16[j] * q_scale );
    }
    free( v_tmp32 );
    free( v_tmp16 );
#endif
    model->azimDim3_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) );
    model->azim_start_idx_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) );
@@ -581,59 +554,41 @@ static ivas_error LoadBSplineBinary_fx(
        fread( &model->azim_start_idx_dyn[i], sizeof( int16_t ), 1, f_hrtf );
        model->azimKSeq[i] = (float *) malloc( ( model->azimDim3_dyn[i] + 1 ) * sizeof( float ) );

        v_tmp32 = (int32_t *) malloc( ( model->azimDim3_dyn[i] + 1 ) * sizeof( int32_t ) );
        v_tmp16 = (int16_t *) malloc( ( model->azimDim3_dyn[i] + 1 ) * sizeof( int16_t ) );
        fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
        q_scale = powf( 2.f, -1.f * (float) factor_Q );
        fread( v_tmp32, sizeof( int32_t ), ( model->azimDim3_dyn[i] + 1 ), f_hrtf );
        fread( v_tmp16, sizeof( int16_t ), ( model->azimDim3_dyn[i] + 1 ), f_hrtf );
        for ( j = 0; j < model->azimDim3_dyn[i] + 1; j++ )
        {
            model->azimKSeq[i][j] = ( (float) v_tmp32[j] * q_scale );
            model->azimKSeq[i][j] = ( (float) v_tmp16[j] * q_scale );
        }
        free( v_tmp32 );
        free( v_tmp16 );
    }
    fread( &model->AlphaN, sizeof( int16_t ), 1, f_hrtf );

    model->AlphaL_dyn = (float *) malloc( model->AlphaN * model->K * sizeof( float ) );

#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    v_tmp32 = (int32_t *) malloc( model->AlphaN * model->K * sizeof( int32_t ) );
#else
    v_tmp16 = (int16_t *) malloc( model->AlphaN * model->K * sizeof( int16_t ) );
#endif
    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    fread( v_tmp32, sizeof( int32_t ), model->AlphaN * model->K, f_hrtf );
    for ( j = 0; j < model->AlphaN * model->K; j++ )
    {
        model->AlphaL_dyn[j] = ( (float) ( v_tmp32[j] ) ) * q_scale; // Q14
    }
#else

    fread( v_tmp16, sizeof( int16_t ), model->AlphaN * model->K, f_hrtf );
    for ( j = 0; j < model->AlphaN * model->K; j++ )
    {
        model->AlphaL_dyn[j] = ( (float) ( v_tmp16[j] ) ) * q_scale; // Q14
    }
#endif
    model->AlphaR_dyn = (float *) malloc( model->AlphaN * model->K * sizeof( float ) );

    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    fread( v_tmp32, sizeof( int32_t ), model->AlphaN * model->K, f_hrtf );
    for ( j = 0; j < model->AlphaN * model->K; j++ )
    {
        model->AlphaR_dyn[j] = ( (float) ( v_tmp32[j] ) ) * q_scale; // Q14
    }

    free( v_tmp32 );
#else
    fread( v_tmp16, sizeof( int16_t ), model->AlphaN * model->K, f_hrtf );
    for ( j = 0; j < model->AlphaN * model->K; j++ )
    {
        model->AlphaR_dyn[j] = ( (float) ( v_tmp16[j] ) ) * q_scale; // Q14
    }
#endif

    free( v_tmp16 );

    /* azimuth */
    fread( &model->num_unique_azim_splines, sizeof( int16_t ), 1, f_hrtf );
    model->azimBsShape = (const float **) malloc( model->num_unique_azim_splines * sizeof( float * ) );
@@ -646,23 +601,14 @@ static ivas_error LoadBSplineBinary_fx(
        model->azimBsShape_dyn[i] = (float *) malloc( tmp * sizeof( float ) );
        fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
        q_scale = powf( 2.f, -1.f * (float) factor_Q );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
        v_tmp32 = (int32_t *) malloc( tmp * sizeof( int32_t ) );
        fread( v_tmp32, sizeof( int32_t ), tmp, f_hrtf );
        for ( j = 0; j < tmp; j++ )
        {
            model->azimBsShape_dyn[i][j] = ( (float) ( v_tmp32[j] ) ) * q_scale;
        }
        fread( &model->azimSegSamples_dyn[i], sizeof( int16_t ), 1, f_hrtf );
        free( v_tmp32 );
#else
        v_tmp16 = (int16_t *) malloc( tmp * sizeof( int16_t ) );
        fread( v_tmp16, sizeof( int16_t ), tmp, f_hrtf );
        for ( j = 0; j < tmp; j++ )
        {
            model->azimBsShape_dyn[i][j] = ( (float) ( v_tmp16[j] ) ) * q_scale;
        }
        fread( &model->azimSegSamples_dyn[i], sizeof( int16_t ), 1, f_hrtf );
#endif
        free( v_tmp16 );
    }

    model->azimShapeIdx_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) );
@@ -679,27 +625,19 @@ static ivas_error LoadBSplineBinary_fx(
#endif
    fread( &tmp, sizeof( int16_t ), 1, f_hrtf );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    v_tmp32 = (int32_t *) malloc( tmp * sizeof( int32_t ) );
    v_tmp16 = (int16_t *) malloc( tmp * sizeof( int16_t ) );
#endif
    model->elevBsShape_dyn = (float *) malloc( tmp * sizeof( float ) );

    fread( &factor_Q, 1, sizeof( int16_t ), f_hrtf );
    q_scale = powf( 2.f, -1.f * (float) factor_Q );
#ifdef FIX_TDREND_HRTF_FILE_FORMAT_OR
    fread( v_tmp32, sizeof( int32_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        model->elevBsShape_dyn[j] = ( (float) ( v_tmp32[j] ) ) * q_scale;
    }
    free( v_tmp32 );
#else
    fread( v_tmp16, sizeof( int16_t ), tmp, f_hrtf );
    for ( j = 0; j < tmp; j++ )
    {
        model->elevBsShape_dyn[j] = ( (float) ( v_tmp16[j] ) ) * q_scale;
    }
    free( v_tmp16 );

#endif
    fread( &model->elevSegSamples, sizeof( int16_t ), 1, f_hrtf );

    /* Set const pointers */
+22 −22
Original line number Diff line number Diff line
@@ -386,15 +386,15 @@ for fs = [48000 32000 16000]
                [~, integer_azimSplineShape{i}, Q_azimSplineShape{i}] = toInt32(azimSplineShape{i});
        end
    else
        [mod_hrf.elevKSeq{1}, integer_elevKSeq, Q_elevKSeq, diff] = toInt32(mod_hrf.elevKSeq{1});
        [mod_hrf.WL{1}, integer_WL, Q_WL, diff] = toInt32(mod_hrf.WL{1});
        [mod_hrf.WR{1}, integer_WR, Q_WR, diff] = toInt32(mod_hrf.WR{1});
        [elevSplineShape_all, integer_elevSplineShape_all, Q_elevSplineShape_all, diff] = toInt32(elevSplineShape_all);
        [mod_hrf.elevKSeq{1}, integer_elevKSeq, Q_elevKSeq, diff] = toInt16(mod_hrf.elevKSeq{1});
        [mod_hrf.WL{1}, integer_WL, Q_WL, diff] = toInt16(mod_hrf.WL{1});
        [mod_hrf.WR{1}, integer_WR, Q_WR, diff] = toInt16(mod_hrf.WR{1});
        [elevSplineShape_all, integer_elevSplineShape_all, Q_elevSplineShape_all, diff] = toInt16(elevSplineShape_all);
        for i = 1:elevDim3
                [mod_hrf.azimKSeq{i}, integer_azimKSeq{i}, Q_azimKSeq{i}, diff] = toInt32(mod_hrf.azimKSeq{i});
                [mod_hrf.azimKSeq{i}, integer_azimKSeq{i}, Q_azimKSeq{i}, diff] = toInt16(mod_hrf.azimKSeq{i});
        end
        for i = 1:num_unique_splines 
                [azimSplineShape{i}, integer_azimSplineShape{i}, Q_azimSplineShape{i}, diff] = toInt32(azimSplineShape{i});
                [azimSplineShape{i}, integer_azimSplineShape{i}, Q_azimSplineShape{i}, diff] = toInt16(azimSplineShape{i});
        end
    end

@@ -430,7 +430,7 @@ for fs = [48000 32000 16000]
        fwrite(fileID_fx, size(mod_hrf.WR{1}, 2), 'short');                % K, filter length
        fwrite(fileID_fx, elevDim3, 'short');                              % elevDim3 = P
        fwrite(fileID_fx, Q_elevKSeq, "int16");
        fwrite(fileID_fx, integer_elevKSeq, 'int32');
        fwrite(fileID_fx, integer_elevKSeq, 'int16');
        % Azimuth model structure
        azim_start_idx = 0;
        for i = 1:elevDim3
@@ -439,7 +439,7 @@ for fs = [48000 32000 16000]
            fwrite(fileID_fx, azim_start_idx, 'short');                    % start azim index per elevation
            azim_start_idx = azim_start_idx + azimDim3;
            fwrite(fileID_fx, Q_azimKSeq{i}, "int16");
            fwrite(fileID_fx, integer_azimKSeq{i}, "int32");
            fwrite(fileID_fx, integer_azimKSeq{i}, "int16");
        end        
    end
    if dataSpec.float_binary
@@ -597,15 +597,15 @@ for fs = [48000 32000 16000]
        % Weights
        fwrite(fileID_fx, size(mod_hrf.WL{1},1), 'short');                 % (P*Q)
        fwrite(fileID_fx, Q_WL, "int16");
        fwrite(fileID_fx, integer_WL, 'int32');                         % (P*Q) by K
        fwrite(fileID_fx, integer_WL, 'int16');                         % (P*Q) by K
        fwrite(fileID_fx, Q_WR, "int16");
        fwrite(fileID_fx, integer_WR, 'int32');                         % (P*Q) by K
        fwrite(fileID_fx, integer_WR, 'int16');                         % (P*Q) by K
        % Azimuth basis functions
        fwrite(fileID_fx, num_unique_splines, 'short');                    % number of unique spline functions
        for i = 1:num_unique_splines 
            fwrite(fileID_fx, len_a_shapes{i}, 'short');                   % length of azimuth shape
            fwrite(fileID_fx, Q_azimSplineShape{i}, "int16");
            fwrite(fileID_fx, integer_azimSplineShape{i}, 'int32');                % azimuth shape
            fwrite(fileID_fx, integer_azimSplineShape{i}, 'int16');                % azimuth shape
            fwrite(fileID_fx, a_num_points(i), 'short');                   % samples between knot points
        end
        fwrite(fileID_fx, azimShapeIdx, 'short');                          % indices for spline functions to use
@@ -616,7 +616,7 @@ for fs = [48000 32000 16000]
        fwrite(fileID_fx, start_e, 'short');                               % start idx (C indexing) of elevation shapes
        fwrite(fileID_fx, length(elevSplineShape_all), 'short');           % total length elevation shapes
        fwrite(fileID_fx, Q_elevSplineShape_all, "int16");
        fwrite(fileID_fx, integer_elevSplineShape_all, 'int32');                % azimuth shape
        fwrite(fileID_fx, integer_elevSplineShape_all, 'int16');                % azimuth shape
        fwrite(fileID_fx, e_num_points, 'short');                          % samples between knot points
    end
    if dataSpec.float_binary
@@ -824,11 +824,11 @@ for fs = [48000 32000 16000]
            [~, integer_azimSplineShapeITD_all, Q_azimSplineShapeITD_all, diff] = toInt32(azimSplineShapeITD_all);
            [~, integer_elevSplineShapeITD_all, Q_elevSplineShapeITD_all, diff] = toInt32(elevSplineShapeITD_all);
        else
            [mod_itd.elevKSeq, integer_elevKSeq_itd, Q_elevKSeq_itd, diff] = toInt32(mod_itd.elevKSeq);
            [mod_itd.azimKSeq{2}, integer_itd_azimKSeq, Q_itd_azimKSeq, diff] = toInt32(mod_itd.azimKSeq{2});
            [mod_itd.W, integer_itd_W, Q_itd_W, diff] = toInt32(mod_itd.W);
            [azimSplineShapeITD_all, integer_azimSplineShapeITD_all, Q_azimSplineShapeITD_all, diff] = toInt32(azimSplineShapeITD_all);
            [elevSplineShapeITD_all, integer_elevSplineShapeITD_all, Q_elevSplineShapeITD_all, diff] = toInt32(elevSplineShapeITD_all);
            [mod_itd.elevKSeq, integer_elevKSeq_itd, Q_elevKSeq_itd, diff] = toInt16(mod_itd.elevKSeq);
            [mod_itd.azimKSeq{2}, integer_itd_azimKSeq, Q_itd_azimKSeq, diff] = toInt16(mod_itd.azimKSeq{2});
            [mod_itd.W, integer_itd_W, Q_itd_W, diff] = toInt16(mod_itd.W);
            [azimSplineShapeITD_all, integer_azimSplineShapeITD_all, Q_azimSplineShapeITD_all, diff] = toInt16(azimSplineShapeITD_all);
            [elevSplineShapeITD_all, integer_elevSplineShapeITD_all, Q_elevSplineShapeITD_all, diff] = toInt16(elevSplineShapeITD_all);
        end

        % Elevation model structure
@@ -839,27 +839,27 @@ for fs = [48000 32000 16000]
        if dataSpec.fx_binary
            fwrite(fileID_fx, elevDim3, 'short');                          % elevDim3 = P
            fwrite(fileID_fx, Q_elevKSeq_itd, "int16");
            fwrite(fileID_fx, integer_elevKSeq_itd, 'int32');
            fwrite(fileID_fx, integer_elevKSeq_itd, 'int16');
            fwrite(fileID_fx, azimDim3, 'short');                          % azimDim3 = Q
            fwrite(fileID_fx, Q_itd_azimKSeq, "int16");
            fwrite(fileID_fx, integer_itd_azimKSeq, 'int32');
            fwrite(fileID_fx, integer_itd_azimKSeq, 'int16');
            % Weights
            fwrite(fileID_fx, size(mod_itd.W,1), 'short');                 % (P*Q)
            fwrite(fileID_fx, Q_itd_W, "int16");
            fwrite(fileID_fx, integer_itd_W, 'int32');
            fwrite(fileID_fx, integer_itd_W, 'int16');
            % Azimuth basis functions
            fwrite(fileID_fx, len_a_ITD, 'short');                         % length of azimuth shapes
            fwrite(fileID_fx, start_a_ITD, 'short');                       % start idx (C indexing) of azimuth shapes
            fwrite(fileID_fx, length(azimSplineShapeITD_all), 'short');    % total length azimuth shapes
            fwrite(fileID_fx, Q_azimSplineShapeITD_all, "int16");
            fwrite(fileID_fx, integer_azimSplineShapeITD_all, 'int32');                       % azimuth shape
            fwrite(fileID_fx, integer_azimSplineShapeITD_all, 'int16');                       % azimuth shape
            fwrite(fileID_fx, a_num_points_ITD, 'short');                  % samples between knot points
            % Elevation basis functions
            fwrite(fileID_fx, len_e_ITD, 'short');                         % length of elevation shapes
            fwrite(fileID_fx, start_e_ITD, 'short');                       % start idx (C indexing) of elevation shapes
            fwrite(fileID_fx, length(elevSplineShapeITD_all), 'short');    % total length elevation shapes
            fwrite(fileID_fx, Q_elevSplineShapeITD_all, "int16");
            fwrite(fileID_fx, integer_elevSplineShapeITD_all, 'int32');                       % elevation shapes
            fwrite(fileID_fx, integer_elevSplineShapeITD_all, 'int16');                       % elevation shapes
            fwrite(fileID_fx, e_num_points_ITD, 'short');                  % samples between knot points
        end
        if dataSpec.float_binary