[Freeswitch-svn] [commit] r7670 - in freeswitch/trunk: . build src src/include src/mod/codecs/mod_g711 src/mod/codecs/mod_l16 src/mod/codecs/mod_voipcodecs

Freeswitch SVN anthm at freeswitch.org
Mon Feb 18 14:43:58 EST 2008


Author: anthm
Date: Mon Feb 18 14:43:57 2008
New Revision: 7670

Added:
   freeswitch/trunk/src/g711.c
   freeswitch/trunk/src/include/g711.h
Removed:
   freeswitch/trunk/src/mod/codecs/mod_g711/
   freeswitch/trunk/src/mod/codecs/mod_l16/
Modified:
   freeswitch/trunk/Makefile.am
   freeswitch/trunk/build/modules.conf.in
   freeswitch/trunk/src/include/switch_loadable_module.h
   freeswitch/trunk/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c
   freeswitch/trunk/src/switch_loadable_module.c

Log:
move L16 and g711 into the core

Modified: freeswitch/trunk/Makefile.am
==============================================================================
--- freeswitch/trunk/Makefile.am	(original)
+++ freeswitch/trunk/Makefile.am	Mon Feb 18 14:43:57 2008
@@ -78,6 +78,8 @@
 src/switch_time.c\
 libs/stfu/stfu.c\
 src/switch_cpp.cpp\
+src/g711.c\
+src/switch_pcm.c\
 libs/libteletone/src/libteletone_detect.c\
 libs/libteletone/src/libteletone_generate.c
 

Modified: freeswitch/trunk/build/modules.conf.in
==============================================================================
--- freeswitch/trunk/build/modules.conf.in	(original)
+++ freeswitch/trunk/build/modules.conf.in	Mon Feb 18 14:43:57 2008
@@ -15,14 +15,12 @@
 #applications/mod_rss
 #asr_tts/mod_cepstral
 #asr_tts/mod_openmrcp
-#codecs/mod_g711
 codecs/mod_g723_1
 codecs/mod_amr
 codecs/mod_g729
 codecs/mod_h26x
 codecs/mod_voipcodecs
 codecs/mod_ilbc
-codecs/mod_l16
 codecs/mod_speex
 #dialplans/mod_dialplan_directory
 dialplans/mod_dialplan_xml

Added: freeswitch/trunk/src/g711.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/g711.c	Mon Feb 18 14:43:57 2008
@@ -0,0 +1,92 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g711.c - A-law and u-law transcoding routines
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * Copyright (C) 2006 Steve Underwood
+ *
+ *  Despite my general liking of the GPL, I place this code in the
+ *  public domain for the benefit of all mankind - even the slimy
+ *  ones who might try to proprietize my work and use it to my
+ *  detriment.
+ *
+ * $Id: g711.c,v 1.1 2006/06/07 15:46:39 steveu Exp $
+ */
+
+/*! \file */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#ifndef _MSC_VER
+#include <inttypes.h>
+#ifdef HAVE_TGMATH_H
+#include <tgmath.h>
+#endif
+#endif
+
+#include "g711.h"
+
+/* Copied from the CCITT G.711 specification */
+static const uint8_t ulaw_to_alaw_table[256] =
+{
+     42,  43,  40,  41,  46,  47,  44,  45,  34,  35,  32,  33,  38,  39,  36,  37,
+     58,  59,  56,  57,  62,  63,  60,  61,  50,  51,  48,  49,  54,  55,  52,  53,
+     10,  11,   8,   9,  14,  15,  12,  13,   2,   3,   0,   1,   6,   7,   4,  26,
+     27,  24,  25,  30,  31,  28,  29,  18,  19,  16,  17,  22,  23,  20,  21, 106,
+    104, 105, 110, 111, 108, 109,  98,  99,  96,  97, 102, 103, 100, 101, 122, 120,
+    126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117,  75,  73,  79,  77,
+     66,  67,  64,  65,  70,  71,  68,  69,  90,  91,  88,  89,  94,  95,  92,  93,
+     82,  82,  83,  83,  80,  80,  81,  81,  86,  86,  87,  87,  84,  84,  85,  85,
+    170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
+    186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
+    138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
+    155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
+    232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
+    254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
+    194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
+    210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
+};
+
+/* These transcoding tables are copied from the CCITT G.711 specification. To achieve
+   optimal results, do not change them. */
+
+static const uint8_t alaw_to_ulaw_table[256] =
+{
+     42,  43,  40,  41,  46,  47,  44,  45,  34,  35,  32,  33,  38,  39,  36,  37,
+     57,  58,  55,  56,  61,  62,  59,  60,  49,  50,  47,  48,  53,  54,  51,  52,
+     10,  11,   8,   9,  14,  15,  12,  13,   2,   3,   0,   1,   6,   7,   4,   5,
+     26,  27,  24,  25,  30,  31,  28,  29,  18,  19,  16,  17,  22,  23,  20,  21,
+     98,  99,  96,  97, 102, 103, 100, 101,  93,  93,  92,  92,  95,  95,  94,  94,
+    116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
+     72,  73,  70,  71,  76,  77,  74,  75,  64,  65,  63,  63,  68,  69,  66,  67,
+     86,  87,  84,  85,  90,  91,  88,  89,  79,  79,  78,  78,  82,  83,  80,  81,
+    170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
+    185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
+    138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
+    154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
+    226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
+    244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
+    200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
+    214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
+};
+
+uint8_t alaw_to_ulaw(uint8_t alaw)
+{
+    return alaw_to_ulaw_table[alaw];
+}
+/*- End of function --------------------------------------------------------*/
+
+uint8_t ulaw_to_alaw(uint8_t ulaw)
+{
+    return ulaw_to_alaw_table[ulaw];
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/

Added: freeswitch/trunk/src/include/g711.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/include/g711.h	Mon Feb 18 14:43:57 2008
@@ -0,0 +1,382 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g711.h - In line A-law and u-law conversion routines
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * Copyright (C) 2001 Steve Underwood
+ *
+ *  Despite my general liking of the GPL, I place this code in the
+ *  public domain for the benefit of all mankind - even the slimy
+ *  ones who might try to proprietize my work and use it to my
+ *  detriment.
+ *
+ * $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $
+ */
+
+/*! \file */
+
+/*! \page g711_page A-law and mu-law handling
+Lookup tables for A-law and u-law look attractive, until you consider the impact
+on the CPU cache. If it causes a substantial area of your processor cache to get
+hit too often, cache sloshing will severely slow things down. The main reason
+these routines are slow in C, is the lack of direct access to the CPU's "find
+the first 1" instruction. A little in-line assembler fixes that, and the
+conversion routines can be faster than lookup tables, in most real world usage.
+A "find the first 1" instruction is available on most modern CPUs, and is a
+much underused feature. 
+
+If an assembly language method of bit searching is not available, these routines
+revert to a method that can be a little slow, so the cache thrashing might not
+seem so bad :(
+
+Feel free to submit patches to add fast "find the first 1" support for your own
+favourite processor.
+
+Look up tables are used for transcoding between A-law and u-law, since it is
+difficult to achieve the precise transcoding procedure laid down in the G.711
+specification by other means.
+*/
+
+#if !defined(_G711_H_)
+#define _G711_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#ifndef __inline__
+#define __inline__ __inline
+#endif
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef unsigned __int16 uint16_t;
+#endif
+
+#if defined(__i386__)
+/*! \brief Find the bit position of the highest set bit in a word
+    \param bits The word to be searched
+    \return The bit number of the highest set bit, or -1 if the word is zero. */
+static __inline__ int top_bit(unsigned int bits)
+{
+    int res;
+
+    __asm__ __volatile__(" movl $-1,%%edx;\n"
+                         " bsrl %%eax,%%edx;\n"
+                         : "=d" (res)
+                         : "a" (bits));
+    return res;
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Find the bit position of the lowest set bit in a word
+    \param bits The word to be searched
+    \return The bit number of the lowest set bit, or -1 if the word is zero. */
+static __inline__ int bottom_bit(unsigned int bits)
+{
+    int res;
+
+    __asm__ __volatile__(" movl $-1,%%edx;\n"
+                         " bsfl %%eax,%%edx;\n"
+                         : "=d" (res)
+                         : "a" (bits));
+    return res;
+}
+/*- End of function --------------------------------------------------------*/
+#elif defined(__x86_64__)
+static __inline__ int top_bit(unsigned int bits)
+{
+    int res;
+
+    __asm__ __volatile__(" movq $-1,%%rdx;\n"
+                         " bsrq %%rax,%%rdx;\n"
+                         : "=d" (res)
+                         : "a" (bits));
+    return res;
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int bottom_bit(unsigned int bits)
+{
+    int res;
+
+    __asm__ __volatile__(" movq $-1,%%rdx;\n"
+                         " bsfq %%rax,%%rdx;\n"
+                         : "=d" (res)
+                         : "a" (bits));
+    return res;
+}
+/*- End of function --------------------------------------------------------*/
+#else
+static __inline__ int top_bit(unsigned int bits)
+{
+    int i;
+    
+    if (bits == 0)
+        return -1;
+    i = 0;
+    if (bits & 0xFFFF0000)
+    {
+        bits &= 0xFFFF0000;
+        i += 16;
+    }
+    if (bits & 0xFF00FF00)
+    {
+        bits &= 0xFF00FF00;
+        i += 8;
+    }
+    if (bits & 0xF0F0F0F0)
+    {
+        bits &= 0xF0F0F0F0;
+        i += 4;
+    }
+    if (bits & 0xCCCCCCCC)
+    {
+        bits &= 0xCCCCCCCC;
+        i += 2;
+    }
+    if (bits & 0xAAAAAAAA)
+    {
+        bits &= 0xAAAAAAAA;
+        i += 1;
+    }
+    return i;
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int bottom_bit(unsigned int bits)
+{
+    int i;
+    
+    if (bits == 0)
+        return -1;
+    i = 32;
+    if (bits & 0x0000FFFF)
+    {
+        bits &= 0x0000FFFF;
+        i -= 16;
+    }
+    if (bits & 0x00FF00FF)
+    {
+        bits &= 0x00FF00FF;
+        i -= 8;
+    }
+    if (bits & 0x0F0F0F0F)
+    {
+        bits &= 0x0F0F0F0F;
+        i -= 4;
+    }
+    if (bits & 0x33333333)
+    {
+        bits &= 0x33333333;
+        i -= 2;
+    }
+    if (bits & 0x55555555)
+    {
+        bits &= 0x55555555;
+        i -= 1;
+    }
+    return i;
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
+ *      However, you should consider the cache footprint.
+ *
+ *      A 64K byte table for linear to x-law and a 512 byte table for x-law to
+ *      linear sound like peanuts these days, and shouldn't an array lookup be
+ *      real fast? No! When the cache sloshes as badly as this one will, a tight
+ *      calculation may be better. The messiest part is normally finding the
+ *      segment, but a little inline assembly can fix that on an i386, x86_64 and
+ *      many other modern processors.
+ */
+ 
+/*
+ * Mu-law is basically as follows:
+ *
+ *      Biased Linear Input Code        Compressed Code
+ *      ------------------------        ---------------
+ *      00000001wxyza                   000wxyz
+ *      0000001wxyzab                   001wxyz
+ *      000001wxyzabc                   010wxyz
+ *      00001wxyzabcd                   011wxyz
+ *      0001wxyzabcde                   100wxyz
+ *      001wxyzabcdef                   101wxyz
+ *      01wxyzabcdefg                   110wxyz
+ *      1wxyzabcdefgh                   111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz.  * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+
+//#define ULAW_ZEROTRAP                 /* turn on the trap as per the MIL-STD */
+#define ULAW_BIAS        0x84           /* Bias for linear code. */
+
+/*! \brief Encode a linear sample to u-law
+    \param linear The sample to encode.
+    \return The u-law value.
+*/
+static __inline__ uint8_t linear_to_ulaw(int linear)
+{
+    uint8_t u_val;
+    int mask;
+    int seg;
+
+    /* Get the sign and the magnitude of the value. */
+    if (linear < 0)
+    {
+        linear = ULAW_BIAS - linear;
+        mask = 0x7F;
+    }
+    else
+    {
+        linear = ULAW_BIAS + linear;
+        mask = 0xFF;
+    }
+
+    seg = top_bit(linear | 0xFF) - 7;
+
+    /*
+     * Combine the sign, segment, quantization bits,
+     * and complement the code word.
+     */
+    if (seg >= 8)
+        u_val = (uint8_t) (0x7F ^ mask);
+    else
+        u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
+#ifdef ULAW_ZEROTRAP
+    /* Optional ITU trap */
+    if (u_val == 0)
+        u_val = 0x02;
+#endif
+    return  u_val;
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Decode an u-law sample to a linear value.
+    \param ulaw The u-law sample to decode.
+    \return The linear value.
+*/
+static __inline__ int16_t ulaw_to_linear(uint8_t ulaw)
+{
+    int t;
+    
+    /* Complement to obtain normal u-law value. */
+    ulaw = ~ulaw;
+    /*
+     * Extract and bias the quantization bits. Then
+     * shift up by the segment number and subtract out the bias.
+     */
+    t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
+    return  (int16_t) ((ulaw & 0x80)  ?  (ULAW_BIAS - t)  :  (t - ULAW_BIAS));
+}
+/*- End of function --------------------------------------------------------*/
+
+/*
+ * A-law is basically as follows:
+ *
+ *      Linear Input Code        Compressed Code
+ *      -----------------        ---------------
+ *      0000000wxyza             000wxyz
+ *      0000001wxyza             001wxyz
+ *      000001wxyzab             010wxyz
+ *      00001wxyzabc             011wxyz
+ *      0001wxyzabcd             100wxyz
+ *      001wxyzabcde             101wxyz
+ *      01wxyzabcdef             110wxyz
+ *      1wxyzabcdefg             111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+
+#define ALAW_AMI_MASK       0x55
+
+/*! \brief Encode a linear sample to A-law
+    \param linear The sample to encode.
+    \return The A-law value.
+*/
+static __inline__ uint8_t linear_to_alaw(int linear)
+{
+    int mask;
+    int seg;
+    
+    if (linear >= 0)
+    {
+        /* Sign (bit 7) bit = 1 */
+        mask = ALAW_AMI_MASK | 0x80;
+    }
+    else
+    {
+        /* Sign (bit 7) bit = 0 */
+        mask = ALAW_AMI_MASK;
+        linear = -linear - 8;
+    }
+
+    /* Convert the scaled magnitude to segment number. */
+    seg = top_bit(linear | 0xFF) - 7;
+    if (seg >= 8)
+    {
+        if (linear >= 0)
+        {
+            /* Out of range. Return maximum value. */
+            return (uint8_t) (0x7F ^ mask);
+        }
+        /* We must be just a tiny step below zero */
+        return (uint8_t) (0x00 ^ mask);
+    }
+    /* Combine the sign, segment, and quantization bits. */
+    return (uint8_t) (((seg << 4) | ((linear >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask);
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Decode an A-law sample to a linear value.
+    \param alaw The A-law sample to decode.
+    \return The linear value.
+*/
+static __inline__ int16_t alaw_to_linear(uint8_t alaw)
+{
+    int i;
+    int seg;
+
+    alaw ^= ALAW_AMI_MASK;
+    i = ((alaw & 0x0F) << 4);
+    seg = (((int) alaw & 0x70) >> 4);
+    if (seg)
+        i = (i + 0x108) << (seg - 1);
+    else
+        i += 8;
+    return (int16_t) ((alaw & 0x80)  ?  i  :  -i);
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
+    \param alaw The A-law sample to transcode.
+    \return The best matching u-law value.
+*/
+uint8_t alaw_to_ulaw(uint8_t alaw);
+
+/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
+    \param alaw The u-law sample to transcode.
+    \return The best matching A-law value.
+*/
+uint8_t ulaw_to_alaw(uint8_t ulaw);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/

Modified: freeswitch/trunk/src/include/switch_loadable_module.h
==============================================================================
--- freeswitch/trunk/src/include/switch_loadable_module.h	(original)
+++ freeswitch/trunk/src/include/switch_loadable_module.h	Mon Feb 18 14:43:57 2008
@@ -321,7 +321,7 @@
                                                         /*! the IANA code number */
                                                         switch_payload_t ianacode,
                                                         /*! the IANA code name */
-                                                        char *iananame,
+                                                        const char *iananame,
                                                         /*! default fmtp to send (can be overridden by the init function) */
                                                         char *fmtp,
                                                         /*! samples transferred per second */
@@ -357,7 +357,7 @@
 		switch_codec_implementation_t *impl = (switch_codec_implementation_t *) switch_core_alloc(pool, sizeof(*impl));
 		impl->codec_type = codec_type;
 		impl->ianacode = ianacode;
-		impl->iananame = iananame;
+		impl->iananame = switch_core_strdup(pool, iananame);
 		impl->fmtp = fmtp;
 		impl->samples_per_second = samples_per_second;
 		impl->actual_samples_per_second = actual_samples_per_second;

Modified: freeswitch/trunk/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c
==============================================================================
--- freeswitch/trunk/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c	(original)
+++ freeswitch/trunk/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c	Mon Feb 18 14:43:57 2008
@@ -189,6 +189,7 @@
 }
 /*  GSM       - END */
 
+#ifdef ENABLE_G711
 /*  G711      - START */
 static switch_status_t switch_g711u_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
 {
@@ -332,6 +333,8 @@
 }
 
 /*  G711      - END */
+#endif
+
 
 /*  G722      - START */
 
@@ -656,6 +659,7 @@
                                              switch_g722_init, switch_g722_encode, switch_g722_decode, switch_g722_destroy);
     }
 
+#ifdef ENABLE_G711
 	/* G711 */
 	mpf = 10000, spf = 80, bpf = 160, ebpf = 80;
 	SWITCH_ADD_CODEC(codec_interface, "G.711 ulaw");
@@ -673,6 +677,7 @@
                                              mpf * count, spf * count, bpf * count, ebpf * count, 1, 1, 12,
                                              switch_g711a_init, switch_g711a_encode, switch_g711a_decode, switch_g711a_destroy);
     }
+#endif
 
 	/* GSM */
 	mpf = 20000, spf = 160, bpf = 320, ebpf = 33;

Modified: freeswitch/trunk/src/switch_loadable_module.c
==============================================================================
--- freeswitch/trunk/src/switch_loadable_module.c	(original)
+++ freeswitch/trunk/src/switch_loadable_module.c	Mon Feb 18 14:43:57 2008
@@ -978,6 +978,7 @@
 	switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool);
 
 	switch_loadable_module_load_module("", "softtimer", SWITCH_FALSE, &err);
+	switch_loadable_module_load_module("", "PCM", SWITCH_FALSE, &err);
 
 	if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
 		switch_xml_t mods, ld;



More information about the Freeswitch-svn mailing list