Commit 4c8fb73d authored by sagnowski's avatar sagnowski
Browse files

Update MC JBM contribution

Includes following changes:
- reduce decoder memory usage in VoIP mode
- update JBM tracefile writing
- add VoIP conditions to self_test.prm
- add script for ensuring BE between decoder in VoIP and non-VoIP mode (not yet used in CI)
- fix bug in IvasModeRunner.py when running decoder in VoIP mode
parent aec722f9
Loading
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -1897,8 +1897,7 @@ static ivas_error decodeVoIP(
    MasaFileWriter *masaWriter = NULL;
    uint16_t numObj = 0;

    const uint32_t pcmBufSizeWithSampleBasedTimeScaling = 3 * MAX_OUTPUT_PCM_BUFFER_SIZE;
    int16_t pcmBuf[3 * MAX_OUTPUT_PCM_BUFFER_SIZE];
    int16_t pcmBuf[MAX_OUTPUT_PCM_BUFFER_SIZE];
#else
    /* For now always assume output with one channel. When adding VoIP to IVAS,
     * initialization of the memory for jitter buffer etc. needs to happen after
@@ -1936,9 +1935,10 @@ static ivas_error decodeVoIP(
    {
        ismWriters[i] = NULL;
    }
#else
    memset( pcmBuf, 0, pcmBufSizeWithSampleBasedTimeScaling );
#endif

    memset( pcmBuf, 0, pcmBufSizeWithSampleBasedTimeScaling );

    rtpdumpDepacker.rtpdump = NULL;
    switch ( arg.inputFormat )
@@ -2111,7 +2111,12 @@ static ivas_error decodeVoIP(
        nOutSamples = (int16_t) ( arg.output_Fs / 50 );

        /* decode and get samples */
        if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK )
        if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms
#ifdef SUPPORT_JBM_TRACEFILE
                                                 ,
                                                 jbmTraceWriter
#endif
                                                 ) ) != IVAS_ERR_OK )
#else
        /* decode and get samples */
        if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, &nOutSamples, pcmBuf, pcmBufSizeWithSampleBasedTimeScaling, systemTime_ms ) ) != IVAS_ERR_OK )
@@ -2121,6 +2126,7 @@ static ivas_error decodeVoIP(
            goto cleanup;
        }

#ifndef MC_JBM
#ifdef SUPPORT_JBM_TRACEFILE
        /* write JBM trace file entry - only done for EVS testing */
        if ( jbmTraceWriter != NULL )
@@ -2139,6 +2145,7 @@ static ivas_error decodeVoIP(
                goto cleanup;
            }
        }
#endif
#endif

        /* write JBM Offset file entry */

ci/jbm_be_test.sh

0 → 100755
+105 −0
Original line number Diff line number Diff line
#! /usr/local/bin/bash

# (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
# contributors to this repository. All Rights Reserved.

# This software is protected by copyright law and by international treaties.
# The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
# contributors to this repository retain full ownership rights in their respective contributions in
# the software. This notice grants no license of any kind, including but not limited to patent
# license, nor is any license granted by implication, estoppel or otherwise.

# Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
# contributions.

# This software is provided "AS IS", without any express or implied warranties. The software is in the
# development stage. It is intended exclusively for experts who have experience with such software and
# solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
# and fitness for a particular purpose are hereby disclaimed and excluded.

# Any dispute, controversy or claim arising under or in relation to providing this software shall be
# submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
# accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
# the United Nations Convention on Contracts on the International Sales of Goods.

# Configuration
modes=('SBA_b128_wb_cbr' 'MC_7_1_b96_fb_cbr' 'ISM2_b48_fb_cbr') # 'stereo_b32_128_fb_rs') # stereo mode sems broken in decoder
output_formats=('STEREO' 'FOA' '7_1' 'HOA3')
limit_input_to_x_seconds=30

network_profile_path="scripts/dly_error_profiles/dly_error_profile_0.dat"

output_dir_default="out"
output_dir_voip="out_voip"

# Build IVAS
make clean
make all -j 8

# Run the same modes in VoIP and non-VoIP mode with a neutral delay profile
./scripts/runIvasCodec.py -p ./scripts/config/ci_linux.json -U $limit_input_to_x_seconds -m "${modes[@]}" --oc "${output_formats[@]}" -o $output_dir_default | tee jbm_be_test_output.txt
./scripts/runIvasCodec.py -p ./scripts/config/ci_linux.json -U $limit_input_to_x_seconds -m "${modes[@]}" --oc "${output_formats[@]}" -o $output_dir_voip -J "$network_profile_path" | tee -a jbm_be_test_output.txt

# Set up Python path
python_audio_module_path=$(pwd)/scripts
export PYTHONPATH=$python_audio_module_path:$PYTHONPATH
python_audiofile_script_path=$python_audio_module_path/pyaudio3dtools/audiofile.py

# Trim JBM delay from VoIP output files
output_dir_voip_dec="$output_dir_voip"/dec
output_dir_voip_dec_trimmed="$output_dir_voip"/dec_trimmed

if [[ ! -d $output_dir_voip_dec_trimmed ]]; then
    mkdir $output_dir_voip_dec_trimmed 
fi

for cut in "$output_dir_voip_dec"/*.wav; do
    output_path=${cut/$output_dir_voip_dec/$output_dir_voip_dec_trimmed}
    output_path=${output_path/".wav"/".raw"}
    python3 "$python_audiofile_script_path" pre-trim 60 "$cut" "$output_path" | tee -a jbm_be_test_output.txt
done

# Convert non-VoIP output from wav to pcm (comparison script doesn't support wav)
output_dir_default_dec="$output_dir_default"/dec
output_dir_default_dec_pcm="$output_dir_default"/dec_pcm

if [[ ! -d $output_dir_default_dec_pcm ]]; then
    mkdir $output_dir_default_dec_pcm 
fi

for ref in "$output_dir_default_dec"/*.wav; do
    output_path=${ref/$output_dir_default_dec/$output_dir_default_dec_pcm}
    output_path=${output_path/".wav"/".raw"}
    python3 "$python_audiofile_script_path" convert "$ref" "$output_path" | tee -a jbm_be_test_output.txt
done

# Assert BE between non-VoIP and VoIP modes
all_be=1

cmp_custom_path=$(pwd)/tests/cmp_custom.py

for ref in "$output_dir_default_dec_pcm"/*; do
    cut=${ref/$output_dir_default_dec_pcm/$output_dir_voip_dec_trimmed}
    cut=${cut/".dec."/"_jbm_dly_error_profile_0_dat.dec."}

    # Print paths of compared files, since the script doesn't do it
    printf "\nComparing %s and %s\n" "$ref" "$cut" | tee -a jbm_be_test_output.txt
    printout=$($cmp_custom_path "$ref" "$cut" 2 0)
    if [ $? -ne 0 ]; then
        all_be=0
    fi
    printf "%s\n" "$printout" | tee -a jbm_be_test_output.txt
done

if [ $all_be -eq 1 ]; then
    printf "\n\nAll tested conditions are bit-exact\n" | tee -a jbm_be_test_output.txt
else
    printf "\n\nBitexactness problems found!\n" | tee -a jbm_be_test_output.txt
    exit 255;
fi
+13 −0
Original line number Diff line number Diff line
@@ -140,15 +140,28 @@ typedef struct ivas_LS_setup_custom IVAS_LSSETUP_CUSTOM_STRUCT;

typedef struct _IVAS_JBM_TRACE_DATA
{
#ifdef MC_JBM
    uint32_t systemTimestamp_ms;
    uint16_t extBufferedSamples;
    uint16_t lastDecodedWasActive;
    int32_t output_Fs;
    int16_t dataUnit_flag;
#else
    double playTime;
    int16_t partialCopyOffset;
#endif
    uint16_t sequenceNumber;
    uint32_t timeStamp;
    uint32_t rcvTime;

#ifdef MC_JBM
    int16_t partial_frame;
    int16_t partialCopyOffset;
#else
    int16_t lastDecodedWasActive;
    int16_t partial_frame_flag;
    int16_t dataUnit_flag;
#endif

} IVAS_JBM_TRACE_DATA;

+41 −6
Original line number Diff line number Diff line
@@ -66,7 +66,12 @@
struct apa_state_t
{
    /* output buffer */
#ifdef MC_JBM
    int16_t *buf_out;
    uint16_t buf_out_capacity;
#else
    int16_t buf_out[APA_BUF];
#endif
    uint16_t l_buf_out;

    /* Hann window */
@@ -143,7 +148,11 @@ static bool extend_frm( apa_state_t *ps, const int16_t frm_in[], int16_t frm_out

/* Allocates memory for state struct and initializes elements. */
uint8_t apa_init(
    apa_state_t **pps )
    apa_state_t **pps
#ifdef MC_JBM
    ,int32_t num_channels
#endif
)
{
    apa_state_t *ps = NULL;

@@ -159,6 +168,15 @@ uint8_t apa_init(
    {
        return 2;
    }
#ifdef MC_JBM
    ps->num_channels = num_channels;
    ps->buf_out_capacity = APA_BUF_PER_CHANNEL * num_channels;
    ps->buf_out = count_malloc( sizeof( float ) * ps->buf_out_capacity );
    if ( !ps->buf_out )
    {
        return 2;
    }
#endif
    apa_reset( ps );
    *pps = ps;

@@ -190,7 +208,9 @@ void apa_reset(
    ps->last_pitch = 0;
    ps->bad_frame_count = 0;
    ps->good_frame_count = 0;
#ifndef MC_JBM
    ps->num_channels = 0;
#endif

    return;
}
@@ -199,8 +219,11 @@ void apa_reset(
/* Sets the audio configuration. */
bool apa_set_rate(
    apa_state_t *ps,
    const int32_t output_Fs,
    const int16_t num_channels )
    const int32_t output_Fs
#ifndef MC_JBM
    ,const int16_t num_channels
#endif
     )
{
    /* make sure pointer is valid */
    if ( ps == NULL )
@@ -222,12 +245,11 @@ bool apa_set_rate(

    /* set number of channels */
#ifdef MC_JBM
    if ( num_channels > APA_MAX_NUM_CHANNELS )
    if ( ps->num_channels > APA_MAX_NUM_CHANNELS )
    {
        return 1;
    }
#endif
    ps->num_channels = num_channels;

    /*
     * several other parameters depend on the sampling rate
@@ -415,6 +437,11 @@ bool apa_exit(
        return 0;
    }

#ifdef MC_JBM
    /* deallocate state struct members */
    count_free( (*pps)->buf_out );
#endif

    /* deallocate state struct */
    count_free( *pps );

@@ -466,7 +493,7 @@ uint8_t apa_exec(
)
{
    uint16_t i;
    int16_t frm_in[APA_BUF];
    int16_t frm_in[APA_BUF]; /* TODO(mcjbm): this buffer could be smaller - always allocates space for 16 channels */
    uint16_t l_frm_out;
    int16_t l_rem;
    int32_t dl_scaled, dl_copied, l_frm_out_target;
@@ -584,7 +611,11 @@ uint8_t apa_exec(
    /* copy output to internal buffer */
    /* avoid buffer overflow: */
    /* discard old samples; always keep at least most recent l_frm samples */
#ifdef MC_JBM
    if ( ( ps->l_buf_out + l_frm_out ) >  ps->buf_out_capacity )
#else
    if ( ( ps->l_buf_out + l_frm_out ) > APA_BUF )
#endif
    {
        int16_t *buf_out_ptr1 = ps->buf_out;
        int16_t *buf_out_ptr2;
@@ -602,7 +633,11 @@ uint8_t apa_exec(
        ps->l_buf_out = l_rem;
    }
    /* append new output samples */
#ifdef MC_JBM
    if ( ( ps->l_buf_out + l_frm_out ) > ps->buf_out_capacity )
#else
    if ( ( ps->l_buf_out + l_frm_out ) > APA_BUF )
#endif
    {
        return 5;
    }
+12 −2
Original line number Diff line number Diff line
@@ -95,7 +95,12 @@ typedef struct apa_state_t *PCMDSP_APA_HANDLE;

/*! Allocates memory for state struct and initializes elements.
 *  @return 0 on success, 1 on failure */
uint8_t apa_init( apa_state_t **s );
uint8_t apa_init( apa_state_t **s
#ifdef MC_JBM
                  ,
                  int32_t num_channels
#endif
);

/*! Sets state variables to initial value. */
void apa_reset( apa_state_t *s );
@@ -109,7 +114,12 @@ void apa_reset( apa_state_t *s );
 *  @param[in] output_Fs sample rate [Hz]
 *  @param[in] num_channels number of channels
 *  @return 0 on success, 1 on failure */
bool apa_set_rate( apa_state_t *ps, const int32_t output_Fs, const int16_t num_channels );
bool apa_set_rate( apa_state_t *ps, const int32_t output_Fs
#ifndef MC_JBM
                   ,
                   const int16_t num_channels
#endif
);

/*! Set scaling.
 *  The scale is given in % and will be valid until changed again.
Loading