]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
in progress
authorBrian West <brian@freeswitch.org>
Tue, 29 Aug 2006 20:31:01 +0000 (20:31 +0000)
committerBrian West <brian@freeswitch.org>
Tue, 29 Aug 2006 20:31:01 +0000 (20:31 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2431 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/codecs/mod_g726/mod_g726.c

index 3648af81d2f7dc6c2c7b46274b078b079e1a6622..945419be295ab148d9753a8e7481775f549f7469 100644 (file)
@@ -38,12 +38,12 @@ static switch_status_t switch_g726_init(switch_codec_t *codec, switch_codec_flag
                                                                          const switch_codec_settings_t *codec_settings) 
 {
        int encoding, decoding;
-       struct g726_state_s *context = NULL;
+       g726_state *context = NULL;
 
        encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
        decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
 
-       if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(struct g726_state_s))))) {
+       if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(g726_state))))) {
                return SWITCH_STATUS_FALSE;
        } else {
                g726_init_state(context);
@@ -59,69 +59,150 @@ static switch_status_t switch_g726_destroy(switch_codec_t *codec)
        return SWITCH_STATUS_SUCCESS;
 }
 
-#define define_encoder(func, coder, datalen)\
-static switch_status_t func(switch_codec_t *codec,\
-                                                       switch_codec_t *other_codec,\
-                                                       void *decoded_data,\
-\
-                                                       uint32_t decoded_data_len,\
-                                                       uint32_t decoded_rate,\
-                                                       void *encoded_data,\
-\
-                                                       uint32_t *encoded_data_len,\
-                                                       uint32_t *encoded_rate,\
-                                                       unsigned int *flag)\
-{\
-       struct g726_state_s *context = codec->private_info;\
-\
-       if (!context) {\
-               return SWITCH_STATUS_FALSE;\
-       }\
-\
-       if (decoded_data_len % datalen == 0) {\
-               coder(*(int *)decoded_data , AUDIO_ENCODING_LINEAR, context);\
-       }\
-\
-       return SWITCH_STATUS_SUCCESS;\
-}\
-
-#define define_decoder(func, coder, datalen)\
-static switch_status_t func(switch_codec_t *codec,\
-                                                       switch_codec_t *other_codec,\
-                                                       void *encoded_data,\
-\
-                                                       uint32_t encoded_data_len,\
-                                                       uint32_t encoded_rate,\
-                                                       void *decoded_data,\
-\
-                                                       uint32_t *decoded_data_len,\
-                                                       uint32_t *decoded_rate,\
-                                                       unsigned int *flag)\
-{\
-       struct g726_state_s *context = codec->private_info;\
-\
-       if (!context) {\
-               return SWITCH_STATUS_FALSE;\
-       }\
-\
-       if (encoded_data_len % datalen == 0) {\
-               coder(*(int *)encoded_data, AUDIO_ENCODING_LINEAR, context);\
-}\
-\
-       return SWITCH_STATUS_SUCCESS;\
-}\
-
-define_encoder(switch_g726_16k_encode, g726_16_encoder, 160) 
-define_decoder(switch_g726_16k_decode, g726_16_decoder, 40)
-
-define_encoder(switch_g726_24k_encode, g726_24_encoder, 160) 
-define_decoder(switch_g726_24k_decode, g726_24_decoder, 60)
-
-define_encoder(switch_g726_32k_encode, g726_32_encoder, 160) 
-define_decoder(switch_g726_32k_decode, g726_32_decoder, 80)
-
-define_encoder(switch_g726_40k_encode, g726_40_encoder, 160) 
-define_decoder(switch_g726_40k_decode, g726_40_decoder, 100)
+typedef int (*encoder_t)(int, int, g726_state *);
+typedef int (*decoder_t)(int, int, g726_state *);
+
+static switch_status_t switch_g726_encode(switch_codec_t *codec, 
+                                                                               switch_codec_t *other_codec, 
+                                                                               void *decoded_data,
+
+                                                                               uint32_t decoded_data_len, 
+                                                                               uint32_t decoded_rate, 
+                                                                               void *encoded_data,
+
+                                                                               uint32_t *encoded_data_len, 
+                                                                               uint32_t *encoded_rate, 
+                                                                               unsigned int *flag) 
+{
+
+       g726_state *context = codec->private_info;
+       uint32_t len = codec->implementation->bytes_per_frame;
+       uint32_t elen = codec->implementation->encoded_bytes_per_frame;
+       encoder_t encoder;
+
+       switch(elen) {
+       case 100:
+               encoder = g726_40_encoder;
+               break;
+       case 80:
+               encoder = g726_32_encoder;
+               break;
+       case 60:
+               encoder = g726_24_encoder;
+               break;
+       case 40:
+               encoder = g726_16_encoder;
+               break;
+       default:
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size %d!\n", elen);
+               return SWITCH_STATUS_FALSE;
+               break;
+       }
+
+       if (!context) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if (decoded_data_len % len == 0) {
+               uint32_t new_len = 0;
+               int16_t *ddp = decoded_data;
+               int8_t *edp = encoded_data;
+               int x;
+               uint32_t loops = decoded_data_len / (sizeof(*ddp));
+
+               for (x = 0; x < loops && new_len < *encoded_data_len; x++) {
+                       int sample = encoder(*ddp, AUDIO_ENCODING_LINEAR, context);
+                       *edp = sample;
+                       edp++;
+
+                       ddp++;
+                       new_len++;
+               }
+
+               if (new_len <= *encoded_data_len) {
+                       printf("encode %d->%d %d\n", decoded_data_len, elen, new_len / 2);
+                       *encoded_data_len = new_len / 2;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len);
+                       return SWITCH_STATUS_FALSE;
+               }
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+static switch_status_t switch_g726_decode(switch_codec_t *codec, 
+                                                                               switch_codec_t *other_codec, 
+                                                                               void *encoded_data,
+
+                                                                               uint32_t encoded_data_len, 
+                                                                               uint32_t encoded_rate, 
+                                                                               void *decoded_data,
+
+                                                                               uint32_t *decoded_data_len, 
+                                                                               uint32_t *decoded_rate, 
+                                                                               unsigned int *flag) 
+{
+
+       g726_state *context = codec->private_info;
+       uint32_t len = codec->implementation->bytes_per_frame;
+       uint32_t elen = codec->implementation->encoded_bytes_per_frame;
+       decoder_t decoder;
+
+       switch(elen) {
+       case 40:
+               decoder = g726_40_decoder;
+               break;
+       case 32:
+               decoder = g726_32_decoder;
+               break;
+       case 24:
+               decoder = g726_24_decoder;
+               break;
+       case 16:
+               decoder = g726_16_decoder;
+               break;
+       default:
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid Encoding Size!\n");
+               return SWITCH_STATUS_FALSE;
+               break;
+       }
+
+       if (!context) {
+               return SWITCH_STATUS_FALSE;
+
+       }
+
+
+       if (encoded_data_len % elen == 0) {
+               int loops = (int) encoded_data_len / elen;
+               char *edp = encoded_data;
+               int16_t *ddp = decoded_data;
+               int x;
+               uint32_t new_len = 0;
+
+               for (x = 0; x < loops && new_len < *decoded_data_len; x++) {
+                       *(int16_t *)ddp = decoder(*(int *)edp, AUDIO_ENCODING_LINEAR, context);
+                       ddp += len;
+                       edp += elen;
+                       new_len += len;
+               }
+
+               if (new_len <= *decoded_data_len) {
+                       *decoded_data_len = new_len;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer overflow!!!\n");
+                       return SWITCH_STATUS_FALSE;
+               }
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+
+}
+
 
 
 /* Registration */ 
@@ -131,17 +212,17 @@ static const switch_codec_implementation_t g726_16k_implementation = {
        /*.ianacode */ 2, 
        /*.iananame */ "G726-16", 
        /*.samples_per_second */ 8000, 
-       /*.bits_per_second */ 16000, 
+       /*.bits_per_second */ 8000, 
        /*.microseconds_per_frame */ 20000, 
        /*.samples_per_frame */ 160, 
-       /*.bytes_per_frame */ 40, 
-       /*.encoded_bytes_per_frame */ 10, 
+       /*.bytes_per_frame */ 320, 
+       /*.encoded_bytes_per_frame */ 40, 
        /*.number_of_channels */ 1, 
        /*.pref_frames_per_packet */ 1, 
        /*.max_frames_per_packet */ 1, 
        /*.init */ switch_g726_init, 
-       /*.encode */ switch_g726_16k_encode, 
-       /*.decode */ switch_g726_16k_decode, 
+       /*.encode */ switch_g726_encode, 
+       /*.decode */ switch_g726_decode, 
        /*.destroy */ switch_g726_destroy, 
 };
 
@@ -151,17 +232,17 @@ static const switch_codec_implementation_t g726_24k_implementation = {
        /*.ianacode */ 2, 
        /*.iananame */ "G726-24", 
        /*.samples_per_second */ 8000, 
-       /*.bits_per_second */ 24000
+       /*.bits_per_second */ 12075
        /*.microseconds_per_frame */ 20000, 
        /*.samples_per_frame */ 160, 
-       /*.bytes_per_frame */ 60, 
-       /*.encoded_bytes_per_frame */ 10, 
+       /*.bytes_per_frame */ 320, 
+       /*.encoded_bytes_per_frame */ 60, 
        /*.number_of_channels */ 1, 
        /*.pref_frames_per_packet */ 1, 
        /*.max_frames_per_packet */ 1, 
        /*.init */ switch_g726_init, 
-       /*.encode */ switch_g726_24k_encode, 
-       /*.decode */ switch_g726_24k_decode, 
+       /*.encode */ switch_g726_encode, 
+       /*.decode */ switch_g726_decode, 
        /*.destroy */ switch_g726_destroy, 
 };
 
@@ -170,17 +251,17 @@ static const switch_codec_implementation_t g726_32k_implementation = {
        /*.ianacode */ 2, 
        /*.iananame */ "G726-32", 
        /*.samples_per_second */ 8000, 
-       /*.bits_per_second */ 32000, 
+       /*.bits_per_second */ 16000, 
        /*.microseconds_per_frame */ 20000, 
        /*.samples_per_frame */ 160, 
-       /*.bytes_per_frame */ 80, 
-       /*.encoded_bytes_per_frame */ 10, 
+       /*.bytes_per_frame */ 320, 
+       /*.encoded_bytes_per_frame */ 80, 
        /*.number_of_channels */ 1, 
        /*.pref_frames_per_packet */ 1, 
        /*.max_frames_per_packet */ 1, 
        /*.init */ switch_g726_init, 
-       /*.encode */ switch_g726_32k_encode, 
-       /*.decode */ switch_g726_32k_decode, 
+       /*.encode */ switch_g726_encode, 
+       /*.decode */ switch_g726_decode, 
        /*.destroy */ switch_g726_destroy, 
 };
 
@@ -188,18 +269,18 @@ static const switch_codec_implementation_t g726_40k_implementation = {
        /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, 
        /*.ianacode */ 2, 
        /*.iananame */ "G726-40", 
-       /*.samples_per_second */ 8000, 
-       /*.bits_per_second */ 40000, 
+       /*.samples_per_second */ 8000,
+       /*.bits_per_second */ 20000, 
        /*.microseconds_per_frame */ 20000, 
        /*.samples_per_frame */ 160, 
-       /*.bytes_per_frame */ 100, 
-       /*.encoded_bytes_per_frame */ 10, 
+       /*.bytes_per_frame */ 320, 
+       /*.encoded_bytes_per_frame */ 100
        /*.number_of_channels */ 1, 
        /*.pref_frames_per_packet */ 1, 
        /*.max_frames_per_packet */ 1, 
        /*.init */ switch_g726_init, 
-       /*.encode */ switch_g726_40k_encode, 
-       /*.decode */ switch_g726_40k_decode, 
+       /*.encode */ switch_g726_encode, 
+       /*.decode */ switch_g726_decode, 
        /*.destroy */ switch_g726_destroy, 
 };