Changeset 3202


Ignore:
Timestamp:
Jun 11, 2010 1:38:42 PM (9 years ago)
Author:
nanang
Message:

Close #1072:

  • Added API pjmedia_codec_g722_set_pcm_shift() to enable configurable level-adjusment setting.
  • Also added macro PJMEDIA_G722_DEFAULT_PCM_SHIFT (default value is 2) to accomplish 14-16 bit PCM conversion for G722 input/output.
  • Added a feature in G722 to stop level-adjusment/PCM-shifting when clipping occured, compile-time configurable via PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING macro.
Location:
pjproject/trunk/pjmedia
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia-codec/config.h

    r2875 r3202  
    9595#ifndef PJMEDIA_HAS_G722_CODEC 
    9696#   define PJMEDIA_HAS_G722_CODEC    1 
     97#endif 
     98 
     99 
     100/** 
     101 * Default G.722 codec encoder and decoder level adjustment. The G.722 
     102 * specifies that it uses 14 bit PCM for input and output, while PJMEDIA 
     103 * normally uses 16 bit PCM, so the conversion is done by applying 
     104 * level adjustment. If the value is non-zero, then PCM input samples to 
     105 * the encoder will be shifted right by this value, and similarly PCM 
     106 * output samples from the decoder will be shifted left by this value. 
     107 * 
     108 * This can be changed at run-time after initialization by calling 
     109 * #pjmedia_codec_g722_set_pcm_shift(). 
     110 * 
     111 * Default: 2. 
     112 */ 
     113#ifndef PJMEDIA_G722_DEFAULT_PCM_SHIFT 
     114#   define PJMEDIA_G722_DEFAULT_PCM_SHIFT           2 
     115#endif 
     116 
     117 
     118/** 
     119 * Specifies whether G.722 PCM shifting should be stopped when clipping 
     120 * detected in the decoder. Enabling this feature can be useful when 
     121 * talking to G.722 implementation that uses 16 bit PCM for G.722 input/ 
     122 * output (for any reason it seems to work) and the PCM shifting causes 
     123 * audio clipping. 
     124 * 
     125 * See also #PJMEDIA_G722_DEFAULT_PCM_SHIFT. 
     126 * 
     127 * Default: enabled. 
     128 */ 
     129#ifndef PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING 
     130#   define PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING  1 
    97131#endif 
    98132 
  • pjproject/trunk/pjmedia/include/pjmedia-codec/g722.h

    r3083 r3202  
    7979 
    8080 
     81/** 
     82 * Set the G.722 codec encoder and decoder level adjustment. 
     83 * If the value is non-zero, then PCM input samples to the encoder will  
     84 * be shifted right by this value, and similarly PCM output samples from 
     85 * the decoder will be shifted left by this value. 
     86 * 
     87 * Default value is PJMEDIA_G722_DEFAULT_PCM_SHIFT. 
     88 * 
     89 * @param val           The value 
     90 * 
     91 * @return              PJ_SUCCESS on success. 
     92 */ 
     93PJ_DECL(pj_status_t) pjmedia_codec_g722_set_pcm_shift(unsigned val); 
     94 
     95 
    8196PJ_END_DECL 
    8297 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/g722.c

    r2760 r3202  
    134134    pj_mutex_t              *mutex; 
    135135    pjmedia_codec            codec_list; 
     136    unsigned                 pcm_shift; 
    136137} g722_codec_factory; 
    137138 
     
    142143    g722_enc_t           encoder; 
    143144    g722_dec_t           decoder; 
     145    unsigned             pcm_shift; 
     146    pj_int16_t           pcm_clip_mask; 
    144147    pj_bool_t            plc_enabled; 
    145148    pj_bool_t            vad_enabled; 
     
    168171    g722_codec_factory.base.factory_data = NULL; 
    169172    g722_codec_factory.endpt = endpt; 
     173    g722_codec_factory.pcm_shift = PJMEDIA_G722_DEFAULT_PCM_SHIFT; 
    170174 
    171175    g722_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "g722", 1000,  
     
    240244    return status; 
    241245} 
     246 
     247 
     248/* 
     249 * Set level adjustment. 
     250 */ 
     251PJ_DEF(pj_status_t) pjmedia_codec_g722_set_pcm_shift(unsigned val) 
     252{ 
     253    g722_codec_factory.pcm_shift = val; 
     254    return PJ_SUCCESS; 
     255} 
     256 
    242257 
    243258/*  
     
    447462    g722_data->vad_enabled = (attr->setting.vad != 0); 
    448463    g722_data->plc_enabled = (attr->setting.plc != 0); 
     464    g722_data->pcm_shift = g722_codec_factory.pcm_shift; 
     465    g722_data->pcm_clip_mask = (pj_int16_t)(1<<g722_codec_factory.pcm_shift)-1; 
     466    g722_data->pcm_clip_mask <<= (16-g722_codec_factory.pcm_shift); 
    449467 
    450468    TRACE_((THIS_FILE, "G722 codec opened: vad=%d, plc=%d", 
     
    566584    } 
    567585 
     586    /* Adjust input signal level from 16-bit to 14-bit */ 
     587    if (g722_data->pcm_shift) { 
     588        pj_int16_t *p, *end; 
     589 
     590        p = (pj_int16_t*)input->buf; 
     591        end = p + input->size; 
     592        while (p < end) { 
     593            *p++ >>= g722_data->pcm_shift; 
     594        } 
     595    } 
     596 
    568597    /* Encode to temporary buffer */ 
    569598    output->size = output_buf_len; 
     
    624653 
    625654    pj_assert(output->size == SAMPLES_PER_FRAME); 
     655 
     656    /* Adjust input signal level from 14-bit to 16-bit */ 
     657    if (g722_data->pcm_shift) { 
     658        pj_int16_t *p, *end; 
     659 
     660        p = (pj_int16_t*)output->buf; 
     661        end = p + output->size; 
     662        while (p < end) { 
     663#if PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING 
     664            /* If there is clipping, stop the PCM shifting */ 
     665            if (*p & g722_data->pcm_clip_mask) { 
     666                g722_data->pcm_shift = 0; 
     667                break; 
     668            } 
     669#endif 
     670            *p++ <<= g722_data->pcm_shift; 
     671        } 
     672    } 
     673 
    626674    output->size = SAMPLES_PER_FRAME * 2; 
    627675    output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/g722/g722_dec.c

    r2394 r3202  
    505505    int ilowr, ylow, rlow, dlowt; 
    506506    int ihigh, rhigh, dhigh; 
    507     int pcm1, pcm2; 
    508507    pj_uint8_t *in_ = (pj_uint8_t*) in; 
    509508 
     
    530529        /* rhigh <= output high band pcm */ 
    531530 
    532         rx_qmf(dec, rlow, rhigh, &pcm1, &pcm2); 
    533         out[i*2] = (pj_int16_t)(pcm1 << 2); 
    534         out[i*2+1] = (pj_int16_t)(pcm2 << 2); 
     531        rx_qmf(dec, rlow, rhigh, &out[i*2], &out[i*2+1]); 
    535532    } 
    536533 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/g722/g722_enc.c

    r2394 r3202  
    544544     
    545545    for(i = 0; i < nsamples; i += 2) { 
    546         tx_qmf(enc, in[i]>>2, in[i+1]>>2, &xlow, &xhigh); 
     546        tx_qmf(enc, in[i], in[i+1], &xlow, &xhigh); 
    547547 
    548548        /* low band encoder */ 
Note: See TracChangeset for help on using the changeset viewer.