summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-04-20 14:19:11 +0000
committerBenny Prijono <bennylp@teluu.com>2009-04-20 14:19:11 +0000
commitf8ca7b03d701cd46ead9a61ee18c17d232a616a1 (patch)
treebc15ac76df66a68066a694455608a3307c1971ab
parent96d0f3f079f982be294f694590c49b8e9fed2420 (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.h16
-rw-r--r--pjmedia/include/pjmedia-codec/g7221.h15
-rw-r--r--pjmedia/src/pjmedia-codec/g7221.c41
-rw-r--r--pjmedia/src/test/codec_vectors.c3
-rw-r--r--third_party/g7221/common/defs.h2
-rw-r--r--third_party/g7221/encode/sam2coef.c5
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;