mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-13 21:17:06 +00:00
cleanup
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2512 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1 parent
344c37a2aa
commit
37c9bd44fe
10 files changed
+21
-20
No files matched your search
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g711.c - A-law and u-law transcoding routines
|
||||
*
|
||||
* Written by Steve Underwood <steveu@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>
|
||||
#include <tgmath.h>
|
||||
#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 ------------------------------------------------------------*/
|
||||
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g722_decode.c - The ITU G.722 codec, decode part.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2005 Steve Underwood
|
||||
*
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to 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.
|
||||
*
|
||||
* Based in part on a single channel G.722 codec which is:
|
||||
*
|
||||
* Copyright (c) CMU 1993
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*
|
||||
* $Id: g722_decode.c,v 1.15 2006/07/07 16:37:49 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <inttypes.h>
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
|
||||
#include "g722.h"
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#if !defined(TRUE)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
static __inline__ int16_t saturate(int32_t amp)
|
||||
{
|
||||
int16_t amp16;
|
||||
|
||||
/* Hopefully this is optimised for the common case - not clipping */
|
||||
amp16 = (int16_t) amp;
|
||||
if (amp == amp16)
|
||||
return amp16;
|
||||
if (amp > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
return INT16_MIN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void block4(g722_decode_state_t *s, int band, int d);
|
||||
|
||||
static void block4(g722_decode_state_t *s, int band, int d)
|
||||
{
|
||||
int wd1;
|
||||
int wd2;
|
||||
int wd3;
|
||||
int i;
|
||||
|
||||
/* Block 4, RECONS */
|
||||
s->band[band].d[0] = d;
|
||||
s->band[band].r[0] = saturate(s->band[band].s + d);
|
||||
|
||||
/* Block 4, PARREC */
|
||||
s->band[band].p[0] = saturate(s->band[band].sz + d);
|
||||
|
||||
/* Block 4, UPPOL2 */
|
||||
for (i = 0; i < 3; i++)
|
||||
s->band[band].sg[i] = s->band[band].p[i] >> 15;
|
||||
wd1 = saturate(s->band[band].a[1] << 2);
|
||||
|
||||
wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
|
||||
if (wd2 > 32767)
|
||||
wd2 = 32767;
|
||||
wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
|
||||
wd3 += (wd2 >> 7);
|
||||
wd3 += (s->band[band].a[2]*32512) >> 15;
|
||||
if (wd3 > 12288)
|
||||
wd3 = 12288;
|
||||
else if (wd3 < -12288)
|
||||
wd3 = -12288;
|
||||
s->band[band].ap[2] = wd3;
|
||||
|
||||
/* Block 4, UPPOL1 */
|
||||
s->band[band].sg[0] = s->band[band].p[0] >> 15;
|
||||
s->band[band].sg[1] = s->band[band].p[1] >> 15;
|
||||
wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
|
||||
wd2 = (s->band[band].a[1]*32640) >> 15;
|
||||
|
||||
s->band[band].ap[1] = saturate(wd1 + wd2);
|
||||
wd3 = saturate(15360 - s->band[band].ap[2]);
|
||||
if (s->band[band].ap[1] > wd3)
|
||||
s->band[band].ap[1] = wd3;
|
||||
else if (s->band[band].ap[1] < -wd3)
|
||||
s->band[band].ap[1] = -wd3;
|
||||
|
||||
/* Block 4, UPZERO */
|
||||
wd1 = (d == 0) ? 0 : 128;
|
||||
s->band[band].sg[0] = d >> 15;
|
||||
for (i = 1; i < 7; i++)
|
||||
{
|
||||
s->band[band].sg[i] = s->band[band].d[i] >> 15;
|
||||
wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
|
||||
wd3 = (s->band[band].b[i]*32640) >> 15;
|
||||
s->band[band].bp[i] = saturate(wd2 + wd3);
|
||||
}
|
||||
|
||||
/* Block 4, DELAYA */
|
||||
for (i = 6; i > 0; i--)
|
||||
{
|
||||
s->band[band].d[i] = s->band[band].d[i - 1];
|
||||
s->band[band].b[i] = s->band[band].bp[i];
|
||||
}
|
||||
|
||||
for (i = 2; i > 0; i--)
|
||||
{
|
||||
s->band[band].r[i] = s->band[band].r[i - 1];
|
||||
s->band[band].p[i] = s->band[band].p[i - 1];
|
||||
s->band[band].a[i] = s->band[band].ap[i];
|
||||
}
|
||||
|
||||
/* Block 4, FILTEP */
|
||||
wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
|
||||
wd1 = (s->band[band].a[1]*wd1) >> 15;
|
||||
wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
|
||||
wd2 = (s->band[band].a[2]*wd2) >> 15;
|
||||
s->band[band].sp = saturate(wd1 + wd2);
|
||||
|
||||
/* Block 4, FILTEZ */
|
||||
s->band[band].sz = 0;
|
||||
for (i = 6; i > 0; i--)
|
||||
{
|
||||
wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
|
||||
s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
|
||||
}
|
||||
s->band[band].sz = saturate(s->band[band].sz);
|
||||
|
||||
/* Block 4, PREDIC */
|
||||
s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)
|
||||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
if (rate == 48000)
|
||||
s->bits_per_sample = 6;
|
||||
else if (rate == 56000)
|
||||
s->bits_per_sample = 7;
|
||||
else
|
||||
s->bits_per_sample = 8;
|
||||
if ((options & G722_SAMPLE_RATE_8000))
|
||||
s->eight_k = TRUE;
|
||||
if ((options & G722_PACKED) && s->bits_per_sample != 8)
|
||||
s->packed = TRUE;
|
||||
else
|
||||
s->packed = FALSE;
|
||||
s->band[0].det = 32;
|
||||
s->band[1].det = 8;
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int g722_decode_release(g722_decode_state_t *s)
|
||||
{
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
|
||||
{
|
||||
static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
|
||||
static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
static const int ilb[32] =
|
||||
{
|
||||
2048, 2093, 2139, 2186, 2233, 2282, 2332,
|
||||
2383, 2435, 2489, 2543, 2599, 2656, 2714,
|
||||
2774, 2834, 2896, 2960, 3025, 3091, 3158,
|
||||
3228, 3298, 3371, 3444, 3520, 3597, 3676,
|
||||
3756, 3838, 3922, 4008
|
||||
};
|
||||
static const int wh[3] = {0, -214, 798};
|
||||
static const int rh2[4] = {2, 1, 2, 1};
|
||||
static const int qm2[4] = {-7408, -1616, 7408, 1616};
|
||||
static const int qm4[16] =
|
||||
{
|
||||
0, -20456, -12896, -8968,
|
||||
-6288, -4240, -2584, -1200,
|
||||
20456, 12896, 8968, 6288,
|
||||
4240, 2584, 1200, 0
|
||||
};
|
||||
static const int qm5[32] =
|
||||
{
|
||||
-280, -280, -23352, -17560,
|
||||
-14120, -11664, -9752, -8184,
|
||||
-6864, -5712, -4696, -3784,
|
||||
-2960, -2208, -1520, -880,
|
||||
23352, 17560, 14120, 11664,
|
||||
9752, 8184, 6864, 5712,
|
||||
4696, 3784, 2960, 2208,
|
||||
1520, 880, 280, -280
|
||||
};
|
||||
static const int qm6[64] =
|
||||
{
|
||||
-136, -136, -136, -136,
|
||||
-24808, -21904, -19008, -16704,
|
||||
-14984, -13512, -12280, -11192,
|
||||
-10232, -9360, -8576, -7856,
|
||||
-7192, -6576, -6000, -5456,
|
||||
-4944, -4464, -4008, -3576,
|
||||
-3168, -2776, -2400, -2032,
|
||||
-1688, -1360, -1040, -728,
|
||||
24808, 21904, 19008, 16704,
|
||||
14984, 13512, 12280, 11192,
|
||||
10232, 9360, 8576, 7856,
|
||||
7192, 6576, 6000, 5456,
|
||||
4944, 4464, 4008, 3576,
|
||||
3168, 2776, 2400, 2032,
|
||||
1688, 1360, 1040, 728,
|
||||
432, 136, -432, -136
|
||||
};
|
||||
static const int qmf_coeffs[12] =
|
||||
{
|
||||
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
|
||||
};
|
||||
|
||||
int dlowt;
|
||||
int rlow;
|
||||
int ihigh;
|
||||
int dhigh;
|
||||
int rhigh;
|
||||
int xout1;
|
||||
int xout2;
|
||||
int wd1;
|
||||
int wd2;
|
||||
int wd3;
|
||||
int code;
|
||||
int outlen;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
outlen = 0;
|
||||
rhigh = 0;
|
||||
for (j = 0; j < len; )
|
||||
{
|
||||
if (s->packed)
|
||||
{
|
||||
/* Unpack the code bits */
|
||||
if (s->in_bits < s->bits_per_sample)
|
||||
{
|
||||
s->in_buffer |= (g722_data[j++] << s->in_bits);
|
||||
s->in_bits += 8;
|
||||
}
|
||||
code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
|
||||
s->in_buffer >>= s->bits_per_sample;
|
||||
s->in_bits -= s->bits_per_sample;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = g722_data[j++];
|
||||
}
|
||||
|
||||
switch (s->bits_per_sample)
|
||||
{
|
||||
default:
|
||||
case 8:
|
||||
wd1 = code & 0x3F;
|
||||
ihigh = (code >> 6) & 0x03;
|
||||
wd2 = qm6[wd1];
|
||||
wd1 >>= 2;
|
||||
break;
|
||||
case 7:
|
||||
wd1 = code & 0x1F;
|
||||
ihigh = (code >> 5) & 0x03;
|
||||
wd2 = qm5[wd1];
|
||||
wd1 >>= 1;
|
||||
break;
|
||||
case 6:
|
||||
wd1 = code & 0x0F;
|
||||
ihigh = (code >> 4) & 0x03;
|
||||
wd2 = qm4[wd1];
|
||||
break;
|
||||
}
|
||||
/* Block 5L, LOW BAND INVQBL */
|
||||
wd2 = (s->band[0].det*wd2) >> 15;
|
||||
/* Block 5L, RECONS */
|
||||
rlow = s->band[0].s + wd2;
|
||||
/* Block 6L, LIMIT */
|
||||
if (rlow > 16383)
|
||||
rlow = 16383;
|
||||
else if (rlow < -16384)
|
||||
rlow = -16384;
|
||||
|
||||
/* Block 2L, INVQAL */
|
||||
wd2 = qm4[wd1];
|
||||
dlowt = (s->band[0].det*wd2) >> 15;
|
||||
|
||||
/* Block 3L, LOGSCL */
|
||||
wd2 = rl42[wd1];
|
||||
wd1 = (s->band[0].nb*127) >> 7;
|
||||
wd1 += wl[wd2];
|
||||
if (wd1 < 0)
|
||||
wd1 = 0;
|
||||
else if (wd1 > 18432)
|
||||
wd1 = 18432;
|
||||
s->band[0].nb = wd1;
|
||||
|
||||
/* Block 3L, SCALEL */
|
||||
wd1 = (s->band[0].nb >> 6) & 31;
|
||||
wd2 = 8 - (s->band[0].nb >> 11);
|
||||
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
|
||||
s->band[0].det = wd3 << 2;
|
||||
|
||||
block4(s, 0, dlowt);
|
||||
|
||||
if (!s->eight_k)
|
||||
{
|
||||
/* Block 2H, INVQAH */
|
||||
wd2 = qm2[ihigh];
|
||||
dhigh = (s->band[1].det*wd2) >> 15;
|
||||
/* Block 5H, RECONS */
|
||||
rhigh = dhigh + s->band[1].s;
|
||||
/* Block 6H, LIMIT */
|
||||
if (rhigh > 16383)
|
||||
rhigh = 16383;
|
||||
else if (rhigh < -16384)
|
||||
rhigh = -16384;
|
||||
|
||||
/* Block 2H, INVQAH */
|
||||
wd2 = rh2[ihigh];
|
||||
wd1 = (s->band[1].nb*127) >> 7;
|
||||
wd1 += wh[wd2];
|
||||
if (wd1 < 0)
|
||||
wd1 = 0;
|
||||
else if (wd1 > 22528)
|
||||
wd1 = 22528;
|
||||
s->band[1].nb = wd1;
|
||||
|
||||
/* Block 3H, SCALEH */
|
||||
wd1 = (s->band[1].nb >> 6) & 31;
|
||||
wd2 = 10 - (s->band[1].nb >> 11);
|
||||
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
|
||||
s->band[1].det = wd3 << 2;
|
||||
|
||||
block4(s, 1, dhigh);
|
||||
}
|
||||
|
||||
if (s->itu_test_mode)
|
||||
{
|
||||
amp[outlen++] = (int16_t) (rlow << 1);
|
||||
amp[outlen++] = (int16_t) (rhigh << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->eight_k)
|
||||
{
|
||||
amp[outlen++] = (int16_t) rlow;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Apply the receive QMF */
|
||||
for (i = 0; i < 22; i++)
|
||||
s->x[i] = s->x[i + 2];
|
||||
s->x[22] = rlow + rhigh;
|
||||
s->x[23] = rlow - rhigh;
|
||||
|
||||
xout1 = 0;
|
||||
xout2 = 0;
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
xout2 += s->x[2*i]*qmf_coeffs[i];
|
||||
xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
||||
}
|
||||
amp[outlen++] = (int16_t) (xout1 >> 12);
|
||||
amp[outlen++] = (int16_t) (xout2 >> 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outlen;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g722_encode.c - The ITU G.722 codec, encode part.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2005 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to 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.
|
||||
*
|
||||
* Based on a single channel 64kbps only G.722 codec which is:
|
||||
*
|
||||
***** Copyright (c) CMU 1993 *****
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*
|
||||
* $Id: g722_encode.c,v 1.14 2006/07/07 16:37:49 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <inttypes.h>
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
|
||||
#include "g722.h"
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#if !defined(TRUE)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
static __inline__ int16_t saturate(int32_t amp)
|
||||
{
|
||||
int16_t amp16;
|
||||
|
||||
/* Hopefully this is optimised for the common case - not clipping */
|
||||
amp16 = (int16_t) amp;
|
||||
if (amp == amp16)
|
||||
return amp16;
|
||||
if (amp > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
return INT16_MIN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void block4(g722_encode_state_t *s, int band, int d)
|
||||
{
|
||||
int wd1;
|
||||
int wd2;
|
||||
int wd3;
|
||||
int i;
|
||||
|
||||
/* Block 4, RECONS */
|
||||
s->band[band].d[0] = d;
|
||||
s->band[band].r[0] = saturate(s->band[band].s + d);
|
||||
|
||||
/* Block 4, PARREC */
|
||||
s->band[band].p[0] = saturate(s->band[band].sz + d);
|
||||
|
||||
/* Block 4, UPPOL2 */
|
||||
for (i = 0; i < 3; i++)
|
||||
s->band[band].sg[i] = s->band[band].p[i] >> 15;
|
||||
wd1 = saturate(s->band[band].a[1] << 2);
|
||||
|
||||
wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
|
||||
if (wd2 > 32767)
|
||||
wd2 = 32767;
|
||||
wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
|
||||
wd3 += (s->band[band].a[2]*32512) >> 15;
|
||||
if (wd3 > 12288)
|
||||
wd3 = 12288;
|
||||
else if (wd3 < -12288)
|
||||
wd3 = -12288;
|
||||
s->band[band].ap[2] = wd3;
|
||||
|
||||
/* Block 4, UPPOL1 */
|
||||
s->band[band].sg[0] = s->band[band].p[0] >> 15;
|
||||
s->band[band].sg[1] = s->band[band].p[1] >> 15;
|
||||
wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
|
||||
wd2 = (s->band[band].a[1]*32640) >> 15;
|
||||
|
||||
s->band[band].ap[1] = saturate(wd1 + wd2);
|
||||
wd3 = saturate(15360 - s->band[band].ap[2]);
|
||||
if (s->band[band].ap[1] > wd3)
|
||||
s->band[band].ap[1] = wd3;
|
||||
else if (s->band[band].ap[1] < -wd3)
|
||||
s->band[band].ap[1] = -wd3;
|
||||
|
||||
/* Block 4, UPZERO */
|
||||
wd1 = (d == 0) ? 0 : 128;
|
||||
s->band[band].sg[0] = d >> 15;
|
||||
for (i = 1; i < 7; i++)
|
||||
{
|
||||
s->band[band].sg[i] = s->band[band].d[i] >> 15;
|
||||
wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
|
||||
wd3 = (s->band[band].b[i]*32640) >> 15;
|
||||
s->band[band].bp[i] = saturate(wd2 + wd3);
|
||||
}
|
||||
|
||||
/* Block 4, DELAYA */
|
||||
for (i = 6; i > 0; i--)
|
||||
{
|
||||
s->band[band].d[i] = s->band[band].d[i - 1];
|
||||
s->band[band].b[i] = s->band[band].bp[i];
|
||||
}
|
||||
|
||||
for (i = 2; i > 0; i--)
|
||||
{
|
||||
s->band[band].r[i] = s->band[band].r[i - 1];
|
||||
s->band[band].p[i] = s->band[band].p[i - 1];
|
||||
s->band[band].a[i] = s->band[band].ap[i];
|
||||
}
|
||||
|
||||
/* Block 4, FILTEP */
|
||||
wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
|
||||
wd1 = (s->band[band].a[1]*wd1) >> 15;
|
||||
wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
|
||||
wd2 = (s->band[band].a[2]*wd2) >> 15;
|
||||
s->band[band].sp = saturate(wd1 + wd2);
|
||||
|
||||
/* Block 4, FILTEZ */
|
||||
s->band[band].sz = 0;
|
||||
for (i = 6; i > 0; i--)
|
||||
{
|
||||
wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
|
||||
s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
|
||||
}
|
||||
s->band[band].sz = saturate(s->band[band].sz);
|
||||
|
||||
/* Block 4, PREDIC */
|
||||
s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options)
|
||||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
if (rate == 48000)
|
||||
s->bits_per_sample = 6;
|
||||
else if (rate == 56000)
|
||||
s->bits_per_sample = 7;
|
||||
else
|
||||
s->bits_per_sample = 8;
|
||||
if ((options & G722_SAMPLE_RATE_8000))
|
||||
s->eight_k = TRUE;
|
||||
if ((options & G722_PACKED) && s->bits_per_sample != 8)
|
||||
s->packed = TRUE;
|
||||
else
|
||||
s->packed = FALSE;
|
||||
s->band[0].det = 32;
|
||||
s->band[1].det = 8;
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int g722_encode_release(g722_encode_state_t *s)
|
||||
{
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len)
|
||||
{
|
||||
static const int q6[32] =
|
||||
{
|
||||
0, 35, 72, 110, 150, 190, 233, 276,
|
||||
323, 370, 422, 473, 530, 587, 650, 714,
|
||||
786, 858, 940, 1023, 1121, 1219, 1339, 1458,
|
||||
1612, 1765, 1980, 2195, 2557, 2919, 0, 0
|
||||
};
|
||||
static const int iln[32] =
|
||||
{
|
||||
0, 63, 62, 31, 30, 29, 28, 27,
|
||||
26, 25, 24, 23, 22, 21, 20, 19,
|
||||
18, 17, 16, 15, 14, 13, 12, 11,
|
||||
10, 9, 8, 7, 6, 5, 4, 0
|
||||
};
|
||||
static const int ilp[32] =
|
||||
{
|
||||
0, 61, 60, 59, 58, 57, 56, 55,
|
||||
54, 53, 52, 51, 50, 49, 48, 47,
|
||||
46, 45, 44, 43, 42, 41, 40, 39,
|
||||
38, 37, 36, 35, 34, 33, 32, 0
|
||||
};
|
||||
static const int wl[8] =
|
||||
{
|
||||
-60, -30, 58, 172, 334, 538, 1198, 3042
|
||||
};
|
||||
static const int rl42[16] =
|
||||
{
|
||||
0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
};
|
||||
static const int ilb[32] =
|
||||
{
|
||||
2048, 2093, 2139, 2186, 2233, 2282, 2332,
|
||||
2383, 2435, 2489, 2543, 2599, 2656, 2714,
|
||||
2774, 2834, 2896, 2960, 3025, 3091, 3158,
|
||||
3228, 3298, 3371, 3444, 3520, 3597, 3676,
|
||||
3756, 3838, 3922, 4008
|
||||
};
|
||||
static const int qm4[16] =
|
||||
{
|
||||
0, -20456, -12896, -8968,
|
||||
-6288, -4240, -2584, -1200,
|
||||
20456, 12896, 8968, 6288,
|
||||
4240, 2584, 1200, 0
|
||||
};
|
||||
static const int qm2[4] =
|
||||
{
|
||||
-7408, -1616, 7408, 1616
|
||||
};
|
||||
static const int qmf_coeffs[12] =
|
||||
{
|
||||
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
|
||||
};
|
||||
static const int ihn[3] = {0, 1, 0};
|
||||
static const int ihp[3] = {0, 3, 2};
|
||||
static const int wh[3] = {0, -214, 798};
|
||||
static const int rh2[4] = {2, 1, 2, 1};
|
||||
|
||||
int dlow;
|
||||
int dhigh;
|
||||
int el;
|
||||
int wd;
|
||||
int wd1;
|
||||
int ril;
|
||||
int wd2;
|
||||
int il4;
|
||||
int ih2;
|
||||
int wd3;
|
||||
int eh;
|
||||
int mih;
|
||||
int i;
|
||||
int j;
|
||||
/* Low and high band PCM from the QMF */
|
||||
int xlow;
|
||||
int xhigh;
|
||||
int g722_bytes;
|
||||
/* Even and odd tap accumulators */
|
||||
int sumeven;
|
||||
int sumodd;
|
||||
int ihigh;
|
||||
int ilow;
|
||||
int code;
|
||||
|
||||
g722_bytes = 0;
|
||||
xhigh = 0;
|
||||
for (j = 0; j < len; )
|
||||
{
|
||||
if (s->itu_test_mode)
|
||||
{
|
||||
xlow =
|
||||
xhigh = amp[j++] >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->eight_k)
|
||||
{
|
||||
xlow = amp[j++];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Apply the transmit QMF */
|
||||
/* Shuffle the buffer down */
|
||||
for (i = 0; i < 22; i++)
|
||||
s->x[i] = s->x[i + 2];
|
||||
s->x[22] = amp[j++];
|
||||
s->x[23] = amp[j++];
|
||||
|
||||
/* Discard every other QMF output */
|
||||
sumeven = 0;
|
||||
sumodd = 0;
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
sumodd += s->x[2*i]*qmf_coeffs[i];
|
||||
sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
||||
}
|
||||
xlow = (sumeven + sumodd) >> 13;
|
||||
xhigh = (sumeven - sumodd) >> 13;
|
||||
}
|
||||
}
|
||||
/* Block 1L, SUBTRA */
|
||||
el = saturate(xlow - s->band[0].s);
|
||||
|
||||
/* Block 1L, QUANTL */
|
||||
wd = (el >= 0) ? el : -(el + 1);
|
||||
|
||||
for (i = 1; i < 30; i++)
|
||||
{
|
||||
wd1 = (q6[i]*s->band[0].det) >> 12;
|
||||
if (wd < wd1)
|
||||
break;
|
||||
}
|
||||
ilow = (el < 0) ? iln[i] : ilp[i];
|
||||
|
||||
/* Block 2L, INVQAL */
|
||||
ril = ilow >> 2;
|
||||
wd2 = qm4[ril];
|
||||
dlow = (s->band[0].det*wd2) >> 15;
|
||||
|
||||
/* Block 3L, LOGSCL */
|
||||
il4 = rl42[ril];
|
||||
wd = (s->band[0].nb*127) >> 7;
|
||||
s->band[0].nb = wd + wl[il4];
|
||||
if (s->band[0].nb < 0)
|
||||
s->band[0].nb = 0;
|
||||
else if (s->band[0].nb > 18432)
|
||||
s->band[0].nb = 18432;
|
||||
|
||||
/* Block 3L, SCALEL */
|
||||
wd1 = (s->band[0].nb >> 6) & 31;
|
||||
wd2 = 8 - (s->band[0].nb >> 11);
|
||||
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
|
||||
s->band[0].det = wd3 << 2;
|
||||
|
||||
block4(s, 0, dlow);
|
||||
|
||||
if (s->eight_k)
|
||||
{
|
||||
/* Just leave the high bits as zero */
|
||||
code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Block 1H, SUBTRA */
|
||||
eh = saturate(xhigh - s->band[1].s);
|
||||
|
||||
/* Block 1H, QUANTH */
|
||||
wd = (eh >= 0) ? eh : -(eh + 1);
|
||||
wd1 = (564*s->band[1].det) >> 12;
|
||||
mih = (wd >= wd1) ? 2 : 1;
|
||||
ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
|
||||
|
||||
/* Block 2H, INVQAH */
|
||||
wd2 = qm2[ihigh];
|
||||
dhigh = (s->band[1].det*wd2) >> 15;
|
||||
|
||||
/* Block 3H, LOGSCH */
|
||||
ih2 = rh2[ihigh];
|
||||
wd = (s->band[1].nb*127) >> 7;
|
||||
s->band[1].nb = wd + wh[ih2];
|
||||
if (s->band[1].nb < 0)
|
||||
s->band[1].nb = 0;
|
||||
else if (s->band[1].nb > 22528)
|
||||
s->band[1].nb = 22528;
|
||||
|
||||
/* Block 3H, SCALEH */
|
||||
wd1 = (s->band[1].nb >> 6) & 31;
|
||||
wd2 = 10 - (s->band[1].nb >> 11);
|
||||
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
|
||||
s->band[1].det = wd3 << 2;
|
||||
|
||||
block4(s, 1, dhigh);
|
||||
code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
|
||||
}
|
||||
|
||||
if (s->packed)
|
||||
{
|
||||
/* Pack the code bits */
|
||||
s->out_buffer |= (code << s->out_bits);
|
||||
s->out_bits += s->bits_per_sample;
|
||||
if (s->out_bits >= 8)
|
||||
{
|
||||
g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
|
||||
s->out_bits -= 8;
|
||||
s->out_buffer >>= 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g722_data[g722_bytes++] = (uint8_t) code;
|
||||
}
|
||||
}
|
||||
return g722_bytes;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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@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 ------------------------------------------------------------*/
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g722.h - The ITU G.722 codec.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2005 Steve Underwood
|
||||
*
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to 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.
|
||||
*
|
||||
* Based on a single channel G.722 codec which is:
|
||||
*
|
||||
***** Copyright (c) CMU 1993 *****
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*
|
||||
* $Id: g722.h,v 1.10 2006/06/16 12:45:53 steveu Exp $
|
||||
*/
|
||||
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_G722_H_)
|
||||
#define _G722_H_
|
||||
|
||||
#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;
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX 0x7fff
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-INT16_MAX - 1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*! \page g722_page G.722 encoding and decoding
|
||||
\section g722_page_sec_1 What does it do?
|
||||
The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
|
||||
specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
|
||||
|
||||
To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
|
||||
support an option for the linear audio to be an 8k samples/second stream. In this mode the
|
||||
codec is considerably faster, and still fully compatible with wideband terminals using G.722.
|
||||
|
||||
\section g722_page_sec_2 How does it work?
|
||||
???.
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
G722_SAMPLE_RATE_8000 = 0x0001,
|
||||
G722_PACKED = 0x0002
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
||||
disabled. */
|
||||
int itu_test_mode;
|
||||
/*! TRUE if the G.722 data is packed */
|
||||
int packed;
|
||||
/*! TRUE if encode from 8k samples/second */
|
||||
int eight_k;
|
||||
/*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
|
||||
int bits_per_sample;
|
||||
|
||||
/*! Signal history for the QMF */
|
||||
int x[24];
|
||||
|
||||
struct
|
||||
{
|
||||
int s;
|
||||
int sp;
|
||||
int sz;
|
||||
int r[3];
|
||||
int a[3];
|
||||
int ap[3];
|
||||
int p[3];
|
||||
int d[7];
|
||||
int b[7];
|
||||
int bp[7];
|
||||
int sg[7];
|
||||
int nb;
|
||||
int det;
|
||||
} band[2];
|
||||
|
||||
unsigned int in_buffer;
|
||||
int in_bits;
|
||||
unsigned int out_buffer;
|
||||
int out_bits;
|
||||
} g722_encode_state_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
||||
disabled. */
|
||||
int itu_test_mode;
|
||||
/*! TRUE if the G.722 data is packed */
|
||||
int packed;
|
||||
/*! TRUE if decode to 8k samples/second */
|
||||
int eight_k;
|
||||
/*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
|
||||
int bits_per_sample;
|
||||
|
||||
/*! Signal history for the QMF */
|
||||
int x[24];
|
||||
|
||||
struct
|
||||
{
|
||||
int s;
|
||||
int sp;
|
||||
int sz;
|
||||
int r[3];
|
||||
int a[3];
|
||||
int ap[3];
|
||||
int p[3];
|
||||
int d[7];
|
||||
int b[7];
|
||||
int bp[7];
|
||||
int sg[7];
|
||||
int nb;
|
||||
int det;
|
||||
} band[2];
|
||||
|
||||
unsigned int in_buffer;
|
||||
int in_bits;
|
||||
unsigned int out_buffer;
|
||||
int out_bits;
|
||||
} g722_decode_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
|
||||
int g722_encode_release(g722_encode_state_t *s);
|
||||
int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
|
||||
|
||||
g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
|
||||
int g722_decode_release(g722_decode_state_t *s);
|
||||
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g726.h - ITU G.726 codec.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2006 Steve Underwood
|
||||
*
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to 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.
|
||||
*
|
||||
* Based on G.721/G.723 code which is:
|
||||
*
|
||||
* This source code is a product of Sun Microsystems, Inc. and is provided
|
||||
* for unrestricted use. Users may copy or modify this source code without
|
||||
* charge.
|
||||
*
|
||||
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
|
||||
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun source code is provided with no support and without any obligation on
|
||||
* the part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* $Id: g726.h,v 1.8 2006/09/03 04:43:46 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_G726_H_)
|
||||
#define _G726_H_
|
||||
|
||||
#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
|
||||
|
||||
/*! \page g726_page G.726 encoding and decoding
|
||||
\section g726_page_sec_1 What does it do?
|
||||
|
||||
The G.726 module is a bit exact implementation of the full ITU G.726 specification.
|
||||
It supports:
|
||||
- 16 kbps, 24kbps, 32kbps, and 40kbps operation.
|
||||
- Tandem adjustment, for interworking with A-law and u-law.
|
||||
- Annex A support, for use in environments not using A-law or u-law.
|
||||
|
||||
It passes the ITU tests.
|
||||
|
||||
\section g726_page_sec_2 How does it work?
|
||||
???.
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
G726_ENCODING_LINEAR = 0, /* Interworking with 16 bit signed linear */
|
||||
G726_ENCODING_ULAW, /* Interworking with u-law */
|
||||
G726_ENCODING_ALAW /* Interworking with A-law */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
G726_PACKING_NONE = 0,
|
||||
G726_PACKING_LEFT = 1,
|
||||
G726_PACKING_RIGHT = 2
|
||||
};
|
||||
|
||||
struct g726_state_s;
|
||||
|
||||
typedef int16_t (*g726_decoder_func_t)(struct g726_state_s *s, uint8_t code);
|
||||
|
||||
typedef uint8_t (*g726_encoder_func_t)(struct g726_state_s *s, int16_t amp);
|
||||
|
||||
/*
|
||||
* The following is the definition of the state structure
|
||||
* used by the G.726 encoder and decoder to preserve their internal
|
||||
* state between successive calls. The meanings of the majority
|
||||
* of the state structure fields are explained in detail in the
|
||||
* CCITT Recommendation G.721. The field names are essentially indentical
|
||||
* to variable names in the bit level description of the coding algorithm
|
||||
* included in this Recommendation.
|
||||
*/
|
||||
typedef struct g726_state_s
|
||||
{
|
||||
/*! The bit rate */
|
||||
int rate;
|
||||
/*! The external coding, for tandem operation */
|
||||
int ext_coding;
|
||||
/*! The number of bits per sample */
|
||||
int bits_per_sample;
|
||||
/*! One fo the G.726_PACKING_xxx options */
|
||||
int packing;
|
||||
|
||||
/*! Locked or steady state step size multiplier. */
|
||||
int32_t yl;
|
||||
/*! Unlocked or non-steady state step size multiplier. */
|
||||
int16_t yu;
|
||||
/*! int16_t term energy estimate. */
|
||||
int16_t dms;
|
||||
/*! Long term energy estimate. */
|
||||
int16_t dml;
|
||||
/*! Linear weighting coefficient of 'yl' and 'yu'. */
|
||||
int16_t ap;
|
||||
|
||||
/*! Coefficients of pole portion of prediction filter. */
|
||||
int16_t a[2];
|
||||
/*! Coefficients of zero portion of prediction filter. */
|
||||
int16_t b[6];
|
||||
/*! Signs of previous two samples of a partially reconstructed signal. */
|
||||
int16_t pk[2];
|
||||
/*! Previous 6 samples of the quantized difference signal represented in
|
||||
an internal floating point format. */
|
||||
int16_t dq[6];
|
||||
/*! Previous 2 samples of the quantized difference signal represented in an
|
||||
internal floating point format. */
|
||||
int16_t sr[2];
|
||||
/*! Delayed tone detect */
|
||||
int td;
|
||||
|
||||
unsigned int in_buffer;
|
||||
int in_bits;
|
||||
unsigned int out_buffer;
|
||||
int out_bits;
|
||||
|
||||
g726_encoder_func_t enc_func;
|
||||
g726_decoder_func_t dec_func;
|
||||
} g726_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! Initialise a G.726 encode or decode context.
|
||||
\param s The G.726 context.
|
||||
\param bit_rate The required bit rate for the ADPCM data.
|
||||
The valid rates are 16000, 24000, 32000 and 40000.
|
||||
\param ext_coding The coding used outside G.726.
|
||||
\param packing One of the G.726_PACKING_xxx options.
|
||||
\return A pointer to the G.726 context, or NULL for error. */
|
||||
g726_state_t *g726_init(g726_state_t *s, int bit_rate, int ext_coding, int packing);
|
||||
|
||||
/*! Free a G.726 encode or decode context.
|
||||
\param s The G.726 context.
|
||||
\return 0 for OK. */
|
||||
int g726_release(g726_state_t *s);
|
||||
|
||||
/*! Decode a buffer of G.726 ADPCM data to linear PCM, a-law or u-law.
|
||||
\param s The G.726 context.
|
||||
\param amp
|
||||
\param g726_data
|
||||
\param g726_bytes
|
||||
\return The number of samples returned. */
|
||||
int g726_decode(g726_state_t *s,
|
||||
int16_t amp[],
|
||||
const uint8_t g726_data[],
|
||||
int g726_bytes);
|
||||
|
||||
/*! Encode a buffer of linear PCM data to G.726 ADPCM.
|
||||
\param s The G.726 context.
|
||||
\param g726_data
|
||||
\param amp
|
||||
\param samples
|
||||
\return The number of bytes of G.726 data produced. */
|
||||
int g726_encode(g726_state_t *s,
|
||||
uint8_t g726_data[],
|
||||
const int16_t amp[],
|
||||
int samples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
Reference in new issue
Block a user