Loading lib_isar/isar_lc3plus_dec.c +169 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,26 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- * isar_LC3PLUS_AllocateSubframeDecodingMatrix() * * *------------------------------------------------------------------------*/ static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ) { for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { free( subframeChannelMatrix[i] ); } free( subframeChannelMatrix ); return; } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_Open() * Loading Loading @@ -193,6 +213,155 @@ ivas_error ISAR_LC3PLUS_DEC_Open( } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() * * *------------------------------------------------------------------------*/ ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ) { int16_t i; if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); } for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { ( *subframeChannelMatrix )[i] = NULL; } for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) { isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); } } return IVAS_ERR_OK; } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix() * * *------------------------------------------------------------------------*/ ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) { int16_t numIvasSubFramesPerLC3frame; uint32_t decIdx; int16_t ivasSubframeIdx; int16_t effectiveIvasSubframeDuration; int16_t actual_num_spatial_subframes; if ( NULL == handle ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); } if ( NULL == subframeChannelMatrix ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); } if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); } effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us ); numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; /* 0.5(0) = 10ms lc3plus, 5ms subframe */ if ( numIvasSubFramesPerLC3frame != 1 ) { return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); } /* map subframeChannelMatrix to lc3plus skip states */ /* 1st pass: Flag the required frames */ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) { for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) { if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) { /* subframe needed by the user, definitely decode */ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; } else { /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ if ( ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) { /* ... but if the following subframe is required, it needs to be decoded and dropped */ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; } else { handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; } } } } /* if a decoder was paused before, it needs to either: * - Decode the cached frame (if available) and the first required frame OR * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) { if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) { /* find the first frame required by the user */ for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) { if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) { /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ if ( 0 == ivasSubframeIdx ) { handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; break; } /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ else { handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; break; } } } } } /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) { for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) { if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) { handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; } } } return IVAS_ERR_OK; } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_GetDelay() * Loading lib_isar/isar_lc3plus_dec.h +9 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,11 @@ void ISAR_LC3PLUS_DEC_Close( ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ ); /*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ ); ivas_error ISAR_LC3PLUS_DEC_Decode( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ Loading @@ -107,6 +112,10 @@ ivas_error ISAR_LC3PLUS_DEC_Conceal( float **pcm_out /* o : concealed samples */ ); ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ); #endif #endif /* IVAS_LC3PLUS_DEC_H */ Loading
lib_isar/isar_lc3plus_dec.c +169 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,26 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- * isar_LC3PLUS_AllocateSubframeDecodingMatrix() * * *------------------------------------------------------------------------*/ static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ) { for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { free( subframeChannelMatrix[i] ); } free( subframeChannelMatrix ); return; } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_Open() * Loading Loading @@ -193,6 +213,155 @@ ivas_error ISAR_LC3PLUS_DEC_Open( } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() * * *------------------------------------------------------------------------*/ ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ) { int16_t i; if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); } for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { ( *subframeChannelMatrix )[i] = NULL; } for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) { isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); } } return IVAS_ERR_OK; } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix() * * *------------------------------------------------------------------------*/ ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) { int16_t numIvasSubFramesPerLC3frame; uint32_t decIdx; int16_t ivasSubframeIdx; int16_t effectiveIvasSubframeDuration; int16_t actual_num_spatial_subframes; if ( NULL == handle ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); } if ( NULL == subframeChannelMatrix ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); } if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); } effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us ); numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; /* 0.5(0) = 10ms lc3plus, 5ms subframe */ if ( numIvasSubFramesPerLC3frame != 1 ) { return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); } /* map subframeChannelMatrix to lc3plus skip states */ /* 1st pass: Flag the required frames */ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) { for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) { if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) { /* subframe needed by the user, definitely decode */ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; } else { /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ if ( ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) { /* ... but if the following subframe is required, it needs to be decoded and dropped */ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; } else { handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; } } } } /* if a decoder was paused before, it needs to either: * - Decode the cached frame (if available) and the first required frame OR * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) { if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) { /* find the first frame required by the user */ for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) { if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) { /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ if ( 0 == ivasSubframeIdx ) { handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; break; } /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ else { handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; break; } } } } } /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) { for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) { if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) { handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; } } } return IVAS_ERR_OK; } /*------------------------------------------------------------------------- * ISAR_LC3PLUS_DEC_GetDelay() * Loading
lib_isar/isar_lc3plus_dec.h +9 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,11 @@ void ISAR_LC3PLUS_DEC_Close( ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ ); /*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ ); ivas_error ISAR_LC3PLUS_DEC_Decode( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ Loading @@ -107,6 +112,10 @@ ivas_error ISAR_LC3PLUS_DEC_Conceal( float **pcm_out /* o : concealed samples */ ); ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ); #endif #endif /* IVAS_LC3PLUS_DEC_H */