diff options
author | Benny Prijono <bennylp@teluu.com> | 2009-04-20 14:19:11 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2009-04-20 14:19:11 +0000 |
commit | f8ca7b03d701cd46ead9a61ee18c17d232a616a1 (patch) | |
tree | bc15ac76df66a68066a694455608a3307c1971ab | |
parent | 96d0f3f079f982be294f694590c49b8e9fed2420 (diff) |
More ticket #774: added option to shift PCM input to encoder right by some value (default is 1) to make it compatible with some other app
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2620 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r-- | pjmedia/include/pjmedia-codec/config.h | 16 | ||||
-rw-r--r-- | pjmedia/include/pjmedia-codec/g7221.h | 15 | ||||
-rw-r--r-- | pjmedia/src/pjmedia-codec/g7221.c | 41 | ||||
-rw-r--r-- | pjmedia/src/test/codec_vectors.c | 3 | ||||
-rw-r--r-- | third_party/g7221/common/defs.h | 2 | ||||
-rw-r--r-- | third_party/g7221/encode/sam2coef.c | 5 |
6 files changed, 77 insertions, 5 deletions
diff --git a/pjmedia/include/pjmedia-codec/config.h b/pjmedia/include/pjmedia-codec/config.h index 046c8618..314506e5 100644 --- a/pjmedia/include/pjmedia-codec/config.h +++ b/pjmedia/include/pjmedia-codec/config.h @@ -237,8 +237,22 @@ * G.722.1 codec is disabled by default, it's currently under development. */ #ifndef PJMEDIA_HAS_G7221_CODEC -# define PJMEDIA_HAS_G7221_CODEC 0 +# define PJMEDIA_HAS_G7221_CODEC 0 #endif +/** + * Default G.722.1 codec encoder and decoder level adjustment. + * If the value is non-zero, then PCM input samples to the encoder will + * be shifted right by this value, and similarly PCM output samples from + * the decoder will be shifted left by this value. + * + * This can be changed at run-time after initialization by calling + * #pjmedia_codec_g7221_set_pcm_shift(). + */ +#ifndef PJMEDIA_G7221_DEFAULT_PCM_SHIFT +# define PJMEDIA_G7221_DEFAULT_PCM_SHIFT 1 +#endif + + #endif /* __PJMEDIA_CODEC_CONFIG_H__ */ diff --git a/pjmedia/include/pjmedia-codec/g7221.h b/pjmedia/include/pjmedia-codec/g7221.h index 11ec11f4..8c7cbd20 100644 --- a/pjmedia/include/pjmedia-codec/g7221.h +++ b/pjmedia/include/pjmedia-codec/g7221.h @@ -93,6 +93,21 @@ PJ_DECL(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate, unsigned bitrate, pj_bool_t enabled); +/** + * Set the G.722.1 codec encoder and decoder level adjustment. + * If the value is non-zero, then PCM input samples to the encoder will + * be shifted right by this value, and similarly PCM output samples from + * the decoder will be shifted left by this value. + * + * Default value is PJMEDIA_G7221_DEFAULT_PCM_SHIFT. + * + * @param val The value + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val); + + /** * Unregister G722.1 codecs factory from pjmedia endpoint. diff --git a/pjmedia/src/pjmedia-codec/g7221.c b/pjmedia/src/pjmedia-codec/g7221.c index e4eb1aee..fcaebde2 100644 --- a/pjmedia/src/pjmedia-codec/g7221.c +++ b/pjmedia/src/pjmedia-codec/g7221.c @@ -137,6 +137,7 @@ static struct codec_factory { pj_pool_t *pool; /**< Codec factory pool. */ pj_mutex_t *mutex; /**< Codec factory mutex. */ + int pcm_shift; /**< Level adjustment */ unsigned mode_count; /**< Number of G722.1 modes. */ codec_mode modes[MAX_CODEC_MODES]; /**< The G722.1 modes. */ unsigned mode_rsv_start;/**< Start index of G722.1 non- @@ -164,8 +165,10 @@ typedef struct codec_private { pj_uint16_t frame_size; /**< Coded frame size. */ pj_uint16_t frame_size_bits; /**< Coded frame size in bits. */ pj_uint16_t number_of_regions; /**< Number of regions. */ + int pcm_shift; /**< Adjustment for PCM in/out */ /* Encoder specific state */ + Word16 *enc_frame; /**< 16bit to 14bit buffer */ Word16 *enc_old_frame; /* Decoder specific state */ @@ -251,6 +254,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt ) /* Initialize codec modes, by default all standard bitrates are enabled */ codec_factory.mode_count = 0; + codec_factory.pcm_shift = PJMEDIA_G7221_DEFAULT_PCM_SHIFT; mode = &codec_factory.modes[codec_factory.mode_count++]; mode->enabled = PJ_TRUE; @@ -408,6 +412,15 @@ PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate, /* + * Set level adjustment. + */ +PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val) +{ + codec_factory.pcm_shift = val; + return PJ_SUCCESS; +} + +/* * Unregister G722.1 codec factory from pjmedia endpoint. */ PJ_DEF(pj_status_t) pjmedia_codec_g7221_deinit(void) @@ -644,10 +657,12 @@ static pj_status_t codec_open( pjmedia_codec *codec, codec_data->number_of_regions = (pj_uint16_t) (attr->info.clock_rate <= WB_SAMPLE_RATE? NUMBER_OF_REGIONS:MAX_NUMBER_OF_REGIONS); + codec_data->pcm_shift = codec_factory.pcm_shift; /* Initialize encoder state */ tmp = codec_data->samples_per_frame << 1; codec_data->enc_old_frame = (Word16*)pj_pool_zalloc(pool, tmp); + codec_data->enc_frame = (Word16*)pj_pool_alloc(pool, tmp); /* Initialize decoder state */ tmp = codec_data->samples_per_frame; @@ -733,6 +748,7 @@ static pj_status_t codec_encode( pjmedia_codec *codec, struct pjmedia_frame *output) { codec_private_t *codec_data = (codec_private_t*) codec->codec_data; + const Word16 *pcm_input; Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME]; Word16 mag_shift; @@ -772,8 +788,21 @@ static pj_status_t codec_encode( pjmedia_codec *codec, } } + /* Encoder adjust the input signal level */ + if (codec_data->pcm_shift) { + unsigned i; + pcm_input = (const Word16*)input->buf; + for (i=0; i<codec_data->samples_per_frame; ++i) { + codec_data->enc_frame[i] = + (pj_int16_t)(pcm_input[i] >> codec_data->pcm_shift); + } + pcm_input = codec_data->enc_frame; + } else { + pcm_input = (const Word16*)input->buf; + } + /* Convert input samples to rmlt coefs */ - mag_shift = samples_to_rmlt_coefs((Word16*)input->buf, + mag_shift = samples_to_rmlt_coefs(pcm_input, codec_data->enc_old_frame, mlt_coefs, codec_data->samples_per_frame); @@ -855,6 +884,16 @@ static pj_status_t codec_decode( pjmedia_codec *codec, codec_data->samples_per_frame, mag_shift); + /* Decoder adjust PCM signal */ + if (codec_data->pcm_shift) { + unsigned i; + pj_int16_t *buf = (Word16*)output->buf; + + for (i=0; i<codec_data->samples_per_frame; ++i) { + buf[i] <<= codec_data->pcm_shift; + } + } + output->type = PJMEDIA_FRAME_TYPE_AUDIO; output->size = codec_data->samples_per_frame << 1; diff --git a/pjmedia/src/test/codec_vectors.c b/pjmedia/src/test/codec_vectors.c index 7bf3b38c..0c4b81ca 100644 --- a/pjmedia/src/test/codec_vectors.c +++ b/pjmedia/src/test/codec_vectors.c @@ -572,6 +572,9 @@ int codec_test_vectors(void) pjmedia_endpt_destroy(endpt); return -7; } + + /* Set shift value to zero for the test vectors */ + pjmedia_codec_g7221_set_pcm_shift(0); #endif PJ_LOG(3,(THIS_FILE," encode tests:")); diff --git a/third_party/g7221/common/defs.h b/third_party/g7221/common/defs.h index 2c4978e0..40db16fb 100644 --- a/third_party/g7221/common/defs.h +++ b/third_party/g7221/common/defs.h @@ -140,7 +140,7 @@ void decoder(Bit_Obj *bitobj, Word16 *old_decoder_mlt_coefs, Word16 frame_error_flag); -Word16 samples_to_rmlt_coefs(Word16 *new_samples,Word16 *history,Word16 *coefs,Word16 dct_length); +Word16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *history,Word16 *coefs,Word16 dct_length); void rmlt_coefs_to_samples(Word16 *coefs, Word16 *old_samples, Word16 *out_samples, diff --git a/third_party/g7221/encode/sam2coef.c b/third_party/g7221/encode/sam2coef.c index fc369e0c..3dd5b766 100644 --- a/third_party/g7221/encode/sam2coef.c +++ b/third_party/g7221/encode/sam2coef.c @@ -65,12 +65,13 @@ ***************************************************************************/ -Word16 samples_to_rmlt_coefs(Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length) +Word16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length) { Word16 index, vals_left,mag_shift,n; Word16 windowed_data[MAX_DCT_LENGTH]; - Word16 *new_ptr, *old_ptr, *sam_low, *sam_high; + Word16 *old_ptr; + const Word16 *new_ptr, *sam_low, *sam_high; Word16 *win_low, *win_high; Word16 *dst_ptr; Word16 neg_win_low; |