Ignore:
Timestamp:
Sep 6, 2019 5:19:40 AM (5 years ago)
Author:
nanang
Message:

Re #2228: Fixed bugs in PCM shifting in G722 codec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-codec/g722.c

    r3664 r6064  
    144144    g722_enc_t           encoder; 
    145145    g722_dec_t           decoder; 
    146     unsigned             pcm_shift; 
    147     pj_int16_t           pcm_clip_mask; 
     146    pj_int16_t           pcm_shift_val; 
     147    pj_int16_t           pcm_min; 
     148    pj_int16_t           pcm_max; 
    148149    pj_bool_t            plc_enabled; 
    149150    pj_bool_t            vad_enabled; 
     
    463464    g722_data->vad_enabled = (attr->setting.vad != 0); 
    464465    g722_data->plc_enabled = (attr->setting.plc != 0); 
    465     g722_data->pcm_shift = g722_codec_factory.pcm_shift; 
    466     g722_data->pcm_clip_mask = (pj_int16_t)(1<<g722_codec_factory.pcm_shift)-1; 
    467     g722_data->pcm_clip_mask <<= (16-g722_codec_factory.pcm_shift); 
     466    g722_data->pcm_shift_val = 1 << (pj_int16_t)g722_codec_factory.pcm_shift; 
     467    g722_data->pcm_max = 0x7FFF / g722_data->pcm_shift_val; 
     468    g722_data->pcm_min = -0x7FFF / g722_data->pcm_shift_val - 1; 
    468469 
    469470    TRACE_((THIS_FILE, "G722 codec opened: vad=%d, plc=%d", 
     
    586587 
    587588    /* Adjust input signal level from 16-bit to 14-bit */ 
    588     if (g722_data->pcm_shift) { 
     589    if (g722_data->pcm_shift_val > 1) { 
    589590        pj_int16_t *p, *end; 
    590591 
     
    592593        end = p + input->size/2; 
    593594        while (p < end) { 
    594             *p++ >>= g722_data->pcm_shift; 
     595            *p = *p / g722_data->pcm_shift_val; 
     596            ++p; 
    595597        } 
    596598    } 
     
    656658 
    657659    /* Adjust input signal level from 14-bit to 16-bit */ 
    658     if (g722_data->pcm_shift) { 
     660    if (g722_data->pcm_shift_val > 1) { 
    659661        pj_int16_t *p, *end; 
    660662 
     
    663665        while (p < end) { 
    664666#if PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING 
    665             /* If there is clipping, stop the PCM shifting */ 
    666             if (*p & g722_data->pcm_clip_mask) { 
    667                 g722_data->pcm_shift = 0; 
     667            /* If there is clipping, reduce/stop the PCM shifting */ 
     668            if (*p < g722_data->pcm_min || *p > g722_data->pcm_max) { 
     669                g722_data->pcm_shift_val /= 2; 
     670                g722_data->pcm_max = 0x7FFF/g722_data->pcm_shift_val; 
     671                g722_data->pcm_min = -0x7FFF/g722_data->pcm_shift_val-1; 
    668672                break; 
    669673            } 
    670 #endif 
    671             *p++ <<= g722_data->pcm_shift; 
     674#else 
     675            /* Avoid PCM shift overflow if we don't stop on clipping */ 
     676            if (*p < g722_data->pcm_min) 
     677                *p = g722_data->pcm_min; 
     678            else if (*p > g722_data->pcm_max) 
     679                *p = g722_data->pcm_max; 
     680             
     681#endif 
     682            *p = *p * g722_data->pcm_shift_val; 
     683            ++p; 
    672684        } 
    673685    } 
Note: See TracChangeset for help on using the changeset viewer.