WebRtc_Word -> stdint in audio_coding/g711/

BUG=

Review URL: https://webrtc-codereview.appspot.com/1223004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3699 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org
2013-03-21 13:38:29 +00:00
parent 836af79f58
commit ae4e2b352b
5 changed files with 486 additions and 540 deletions

View File

@@ -20,64 +20,54 @@
* -Added option to run encoder bitexact with ITU-T reference implementation * -Added option to run encoder bitexact with ITU-T reference implementation
*/ */
/*! \file */
#include "g711.h" #include "g711.h"
#include "typedefs.h" #include "typedefs.h"
/* Copied from the CCITT G.711 specification */ /* Copied from the CCITT G.711 specification */
static const WebRtc_UWord8 ulaw_to_alaw_table[256] = static const uint8_t ulaw_to_alaw_table[256] = {
{ 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36,
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, 37, 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55,
58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, 52, 53, 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6,
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26, 7, 4, 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22,
27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106, 23, 20, 21, 106, 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102,
104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120, 103, 100, 101, 122, 120, 126, 127, 124, 125, 114, 115, 112, 113, 118, 119,
126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77, 116, 117, 75, 73, 79, 77, 66, 67, 64, 65, 70, 71, 68, 69, 90,
66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93, 91, 88, 89, 94, 95, 92, 93, 82, 82, 83, 83, 80, 80, 81, 81,
82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85, 86, 86, 87, 87, 84, 84, 85, 85, 170, 171, 168, 169, 174, 175, 172,
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, 173, 162, 163, 160, 161, 166, 167, 164, 165, 186, 187, 184, 185, 190, 191,
186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181, 138, 139, 136, 137, 142,
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, 155, 152, 153, 158,
155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, 232, 233, 238,
232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, 254, 255,
254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, 194,
194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, 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 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 /* These transcoding tables are copied from the CCITT G.711 specification. To
optimal results, do not change them. */ achieve optimal results, do not change them. */
static const uint8_t alaw_to_ulaw_table[256] = {
static const WebRtc_UWord8 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,
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, 51, 52, 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6,
57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52, 7, 4, 5, 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17,
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5, 22, 23, 20, 21, 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92,
26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 92, 95, 95, 94, 94, 116, 118, 112, 114, 124, 126, 120, 122, 106, 107,
98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94, 104, 105, 110, 111, 108, 109, 72, 73, 70, 71, 76, 77, 74, 75, 64,
116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109, 65, 63, 63, 68, 69, 66, 67, 86, 87, 84, 85, 90, 91, 88, 89,
72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67, 79, 79, 78, 78, 82, 83, 80, 81, 170, 171, 168, 169, 174, 175, 172,
86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81, 173, 162, 163, 160, 161, 166, 167, 164, 165, 185, 186, 183, 184, 189, 190,
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180, 138, 139, 136, 137, 142,
185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, 154, 155, 152, 153,
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 226, 227, 224,
154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, 244, 246,
226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, 200,
244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
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,
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209 209
}; };
WebRtc_UWord8 alaw_to_ulaw(WebRtc_UWord8 alaw) uint8_t alaw_to_ulaw(uint8_t alaw) { return alaw_to_ulaw_table[alaw]; }
{
return alaw_to_ulaw_table[alaw];
}
/*- End of function --------------------------------------------------------*/
WebRtc_UWord8 ulaw_to_alaw(WebRtc_UWord8 ulaw) uint8_t ulaw_to_alaw(uint8_t ulaw) { return ulaw_to_alaw_table[ulaw]; }
{
return ulaw_to_alaw_table[ulaw];
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@@ -20,8 +20,6 @@
* -Two changes to make implementation bitexact with ITU-T reference implementation * -Two changes to make implementation bitexact with ITU-T reference implementation
*/ */
/*! \file */
/*! \page g711_page A-law and mu-law handling /*! \page g711_page A-law and mu-law handling
Lookup tables for A-law and u-law look attractive, until you consider the impact 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 on the CPU cache. If it causes a substantial area of your processor cache to get
@@ -30,7 +28,7 @@ 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 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. 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 A "find the first 1" instruction is available on most modern CPUs, and is a
much underused feature. much underused feature.
If an assembly language method of bit searching is not available, these routines 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 revert to a method that can be a little slow, so the cache thrashing might not
@@ -57,128 +55,108 @@ extern "C" {
/*! \brief Find the bit position of the highest set bit in a word /*! \brief Find the bit position of the highest set bit in a word
\param bits The word to be searched \param bits The word to be searched
\return The bit number of the highest set bit, or -1 if the word is zero. */ \return The bit number of the highest set bit, or -1 if the word is zero. */
static __inline__ int top_bit(unsigned int bits) static __inline__ int top_bit(unsigned int bits) {
{ int res;
int res;
__asm__ __volatile__(" movl $-1,%%edx;\n" __asm__ __volatile__(" movl $-1,%%edx;\n"
" bsrl %%eax,%%edx;\n" " bsrl %%eax,%%edx;\n"
: "=d" (res) : "=d" (res)
: "a" (bits)); : "a" (bits));
return res; return res;
} }
/*- End of function --------------------------------------------------------*/
/*! \brief Find the bit position of the lowest set bit in a word /*! \brief Find the bit position of the lowest set bit in a word
\param bits The word to be searched \param bits The word to be searched
\return The bit number of the lowest set bit, or -1 if the word is zero. */ \return The bit number of the lowest set bit, or -1 if the word is zero. */
static __inline__ int bottom_bit(unsigned int bits) static __inline__ int bottom_bit(unsigned int bits) {
{ int res;
int res;
__asm__ __volatile__(" movl $-1,%%edx;\n" __asm__ __volatile__(" movl $-1,%%edx;\n"
" bsfl %%eax,%%edx;\n" " bsfl %%eax,%%edx;\n"
: "=d" (res) : "=d" (res)
: "a" (bits)); : "a" (bits));
return res; return res;
} }
/*- End of function --------------------------------------------------------*/
#elif defined(__x86_64__) #elif defined(__x86_64__)
static __inline__ int top_bit(unsigned int bits) static __inline__ int top_bit(unsigned int bits) {
{ int res;
int res;
__asm__ __volatile__(" movq $-1,%%rdx;\n" __asm__ __volatile__(" movq $-1,%%rdx;\n"
" bsrq %%rax,%%rdx;\n" " bsrq %%rax,%%rdx;\n"
: "=d" (res) : "=d" (res)
: "a" (bits)); : "a" (bits));
return res; return res;
} }
/*- End of function --------------------------------------------------------*/
static __inline__ int bottom_bit(unsigned int bits) static __inline__ int bottom_bit(unsigned int bits) {
{ int res;
int res;
__asm__ __volatile__(" movq $-1,%%rdx;\n" __asm__ __volatile__(" movq $-1,%%rdx;\n"
" bsfq %%rax,%%rdx;\n" " bsfq %%rax,%%rdx;\n"
: "=d" (res) : "=d" (res)
: "a" (bits)); : "a" (bits));
return res; return res;
} }
/*- End of function --------------------------------------------------------*/
#else #else
static __inline int top_bit(unsigned int bits) static __inline int top_bit(unsigned int bits) {
{ int i;
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) if (bits == 0) {
{ return -1;
int i; }
i = 0;
if (bits == 0) if (bits & 0xFFFF0000) {
return -1; bits &= 0xFFFF0000;
i = 32; i += 16;
if (bits & 0x0000FFFF) }
{ if (bits & 0xFF00FF00) {
bits &= 0x0000FFFF; bits &= 0xFF00FF00;
i -= 16; i += 8;
} }
if (bits & 0x00FF00FF) if (bits & 0xF0F0F0F0) {
{ bits &= 0xF0F0F0F0;
bits &= 0x00FF00FF; i += 4;
i -= 8; }
} if (bits & 0xCCCCCCCC) {
if (bits & 0x0F0F0F0F) bits &= 0xCCCCCCCC;
{ i += 2;
bits &= 0x0F0F0F0F; }
i -= 4; if (bits & 0xAAAAAAAA) {
} bits &= 0xAAAAAAAA;
if (bits & 0x33333333) i += 1;
{ }
bits &= 0x33333333; return i;
i -= 2; }
}
if (bits & 0x55555555) static __inline int bottom_bit(unsigned int bits) {
{ int i;
bits &= 0x55555555;
i -= 1; if (bits == 0) {
} return -1;
return i; }
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 #endif
/* N.B. It is tempting to use look-up tables for A-law and u-law conversion. /* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
@@ -191,7 +169,7 @@ static __inline int bottom_bit(unsigned int bits)
* segment, but a little inline assembly can fix that on an i386, x86_64 and * segment, but a little inline assembly can fix that on an i386, x86_64 and
* many other modern processors. * many other modern processors.
*/ */
/* /*
* Mu-law is basically as follows: * Mu-law is basically as follows:
* *
@@ -219,68 +197,61 @@ static __inline int bottom_bit(unsigned int bits)
*/ */
//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */ //#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */
#define ULAW_BIAS 0x84 /* Bias for linear code. */ #define ULAW_BIAS 0x84 /* Bias for linear code. */
/*! \brief Encode a linear sample to u-law /*! \brief Encode a linear sample to u-law
\param linear The sample to encode. \param linear The sample to encode.
\return The u-law value. \return The u-law value.
*/ */
static __inline WebRtc_UWord8 linear_to_ulaw(int linear) static __inline uint8_t linear_to_ulaw(int linear) {
{ uint8_t u_val;
WebRtc_UWord8 u_val; int mask;
int mask; int seg;
int seg;
/* Get the sign and the magnitude of the value. */ /* Get the sign and the magnitude of the value. */
if (linear < 0) if (linear < 0) {
{ /* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */
/* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */ linear = ULAW_BIAS - linear - 1;
linear = ULAW_BIAS - linear - 1; mask = 0x7F;
mask = 0x7F; } else {
} linear = ULAW_BIAS + linear;
else mask = 0xFF;
{ }
linear = ULAW_BIAS + linear;
mask = 0xFF;
}
seg = top_bit(linear | 0xFF) - 7; seg = top_bit(linear | 0xFF) - 7;
/* /*
* Combine the sign, segment, quantization bits, * Combine the sign, segment, quantization bits,
* and complement the code word. * and complement the code word.
*/ */
if (seg >= 8) if (seg >= 8)
u_val = (WebRtc_UWord8) (0x7F ^ mask); u_val = (uint8_t)(0x7F ^ mask);
else else
u_val = (WebRtc_UWord8) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask); u_val = (uint8_t)(((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
#ifdef ULAW_ZEROTRAP #ifdef ULAW_ZEROTRAP
/* Optional ITU trap */ /* Optional ITU trap */
if (u_val == 0) if (u_val == 0)
u_val = 0x02; u_val = 0x02;
#endif #endif
return u_val; return u_val;
} }
/*- End of function --------------------------------------------------------*/
/*! \brief Decode an u-law sample to a linear value. /*! \brief Decode an u-law sample to a linear value.
\param ulaw The u-law sample to decode. \param ulaw The u-law sample to decode.
\return The linear value. \return The linear value.
*/ */
static __inline WebRtc_Word16 ulaw_to_linear(WebRtc_UWord8 ulaw) static __inline int16_t ulaw_to_linear(uint8_t ulaw) {
{ int t;
int t;
/* Complement to obtain normal u-law value. */
/* Complement to obtain normal u-law value. */ ulaw = ~ulaw;
ulaw = ~ulaw; /*
/* * Extract and bias the quantization bits. Then
* Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias.
* shift up by the segment number and subtract out the bias. */
*/ t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4); return (int16_t)((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
return (WebRtc_Word16) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
} }
/*- End of function --------------------------------------------------------*/
/* /*
* A-law is basically as follows: * A-law is basically as follows:
@@ -300,83 +271,74 @@ static __inline WebRtc_Word16 ulaw_to_linear(WebRtc_UWord8 ulaw)
* John Wiley & Sons, pps 98-111 and 472-476. * John Wiley & Sons, pps 98-111 and 472-476.
*/ */
#define ALAW_AMI_MASK 0x55 #define ALAW_AMI_MASK 0x55
/*! \brief Encode a linear sample to A-law /*! \brief Encode a linear sample to A-law
\param linear The sample to encode. \param linear The sample to encode.
\return The A-law value. \return The A-law value.
*/ */
static __inline WebRtc_UWord8 linear_to_alaw(int linear) static __inline uint8_t linear_to_alaw(int linear) {
{ int mask;
int mask; int seg;
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;
/* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference
* implementation */
linear = -linear - 1;
}
/* Convert the scaled magnitude to segment number. */ if (linear >= 0) {
seg = top_bit(linear | 0xFF) - 7; /* Sign (bit 7) bit = 1 */
if (seg >= 8) mask = ALAW_AMI_MASK | 0x80;
{ } else {
if (linear >= 0) /* Sign (bit 7) bit = 0 */
{ mask = ALAW_AMI_MASK;
/* Out of range. Return maximum value. */ /* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference
return (WebRtc_UWord8) (0x7F ^ mask); * implementation */
} linear = -linear - 1;
/* We must be just a tiny step below zero */ }
return (WebRtc_UWord8) (0x00 ^ mask);
/* 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);
} }
/* Combine the sign, segment, and quantization bits. */ /* We must be just a tiny step below zero */
return (WebRtc_UWord8) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask); 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. /*! \brief Decode an A-law sample to a linear value.
\param alaw The A-law sample to decode. \param alaw The A-law sample to decode.
\return The linear value. \return The linear value.
*/ */
static __inline WebRtc_Word16 alaw_to_linear(WebRtc_UWord8 alaw) static __inline int16_t alaw_to_linear(uint8_t alaw) {
{ int i;
int i; int seg;
int seg;
alaw ^= ALAW_AMI_MASK; alaw ^= ALAW_AMI_MASK;
i = ((alaw & 0x0F) << 4); i = ((alaw & 0x0F) << 4);
seg = (((int) alaw & 0x70) >> 4); seg = (((int) alaw & 0x70) >> 4);
if (seg) if (seg)
i = (i + 0x108) << (seg - 1); i = (i + 0x108) << (seg - 1);
else else
i += 8; i += 8;
return (WebRtc_Word16) ((alaw & 0x80) ? i : -i); 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. /*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
\param alaw The A-law sample to transcode. \param alaw The A-law sample to transcode.
\return The best matching u-law value. \return The best matching u-law value.
*/ */
WebRtc_UWord8 alaw_to_ulaw(WebRtc_UWord8 alaw); uint8_t alaw_to_ulaw(uint8_t alaw);
/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711. /*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
\param alaw The u-law sample to transcode. \param alaw The u-law sample to transcode.
\return The best matching A-law value. \return The best matching A-law value.
*/ */
WebRtc_UWord8 ulaw_to_alaw(WebRtc_UWord8 ulaw); uint8_t ulaw_to_alaw(uint8_t ulaw);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif
/*- End of file ------------------------------------------------------------*/

View File

@@ -12,170 +12,164 @@
#include "g711_interface.h" #include "g711_interface.h"
#include "typedefs.h" #include "typedefs.h"
WebRtc_Word16 WebRtcG711_EncodeA(void *state, int16_t WebRtcG711_EncodeA(void* state,
WebRtc_Word16 *speechIn, int16_t* speechIn,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *encoded) int16_t* encoded) {
{ int n;
int n; uint16_t tempVal, tempVal2;
WebRtc_UWord16 tempVal, tempVal2;
// Set and discard to avoid getting warnings // Set and discard to avoid getting warnings
(void)(state = NULL); (void)(state = NULL);
// Sanity check of input length // Sanity check of input length
if (len < 0) { if (len < 0) {
return (-1); return (-1);
} }
// Loop over all samples // Loop over all samples
for (n = 0; n < len; n++) { for (n = 0; n < len; n++) {
tempVal = (WebRtc_UWord16)linear_to_alaw(speechIn[n]); tempVal = (uint16_t) linear_to_alaw(speechIn[n]);
#ifdef WEBRTC_BIG_ENDIAN #ifdef WEBRTC_BIG_ENDIAN
if ((n & 0x1) == 1) { if ((n & 0x1) == 1) {
encoded[n>>1]|=((WebRtc_UWord16)tempVal); encoded[n >> 1] |= ((uint16_t) tempVal);
} else { } else {
encoded[n>>1]=((WebRtc_UWord16)tempVal)<<8; encoded[n >> 1] = ((uint16_t) tempVal) << 8;
} }
#else #else
if ((n & 0x1) == 1) { if ((n & 0x1) == 1) {
tempVal2 |= ((WebRtc_UWord16) tempVal) << 8; tempVal2 |= ((uint16_t) tempVal) << 8;
encoded[n >> 1] |= ((WebRtc_UWord16) tempVal) << 8; encoded[n >> 1] |= ((uint16_t) tempVal) << 8;
} else { } else {
tempVal2 = ((WebRtc_UWord16) tempVal); tempVal2 = ((uint16_t) tempVal);
encoded[n >> 1] = ((WebRtc_UWord16) tempVal); encoded[n >> 1] = ((uint16_t) tempVal);
} }
#endif #endif
} }
return (len); return (len);
} }
WebRtc_Word16 WebRtcG711_EncodeU(void *state, int16_t WebRtcG711_EncodeU(void* state,
WebRtc_Word16 *speechIn, int16_t* speechIn,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *encoded) int16_t* encoded) {
{ int n;
int n; uint16_t tempVal;
WebRtc_UWord16 tempVal;
// Set and discard to avoid getting warnings // Set and discard to avoid getting warnings
(void)(state = NULL); (void)(state = NULL);
// Sanity check of input length // Sanity check of input length
if (len < 0) { if (len < 0) {
return (-1); return (-1);
}
// Loop over all samples
for (n = 0; n < len; n++) {
tempVal = (uint16_t) linear_to_ulaw(speechIn[n]);
#ifdef WEBRTC_BIG_ENDIAN
if ((n & 0x1) == 1) {
encoded[n >> 1] |= ((uint16_t) tempVal);
} else {
encoded[n >> 1] = ((uint16_t) tempVal) << 8;
} }
#else
// Loop over all samples if ((n & 0x1) == 1) {
for (n = 0; n < len; n++) { encoded[n >> 1] |= ((uint16_t) tempVal) << 8;
tempVal = (WebRtc_UWord16)linear_to_ulaw(speechIn[n]); } else {
encoded[n >> 1] = ((uint16_t) tempVal);
#ifdef WEBRTC_BIG_ENDIAN
if ((n & 0x1) == 1) {
encoded[n>>1]|=((WebRtc_UWord16)tempVal);
} else {
encoded[n>>1]=((WebRtc_UWord16)tempVal)<<8;
}
#else
if ((n & 0x1) == 1) {
encoded[n >> 1] |= ((WebRtc_UWord16) tempVal) << 8;
} else {
encoded[n >> 1] = ((WebRtc_UWord16) tempVal);
}
#endif
} }
return (len); #endif
}
return (len);
} }
WebRtc_Word16 WebRtcG711_DecodeA(void *state, int16_t WebRtcG711_DecodeA(void* state,
WebRtc_Word16 *encoded, int16_t* encoded,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *decoded, int16_t* decoded,
WebRtc_Word16 *speechType) int16_t* speechType) {
{ int n;
int n; uint16_t tempVal;
WebRtc_UWord16 tempVal;
// Set and discard to avoid getting warnings // Set and discard to avoid getting warnings
(void)(state = NULL); (void)(state = NULL);
// Sanity check of input length // Sanity check of input length
if (len < 0) { if (len < 0) {
return (-1); return (-1);
}
for (n = 0; n < len; n++) {
#ifdef WEBRTC_BIG_ENDIAN
if ((n & 0x1) == 1) {
tempVal = ((uint16_t) encoded[n >> 1] & 0xFF);
} else {
tempVal = ((uint16_t) encoded[n >> 1] >> 8);
} }
#else
for (n = 0; n < len; n++) { if ((n & 0x1) == 1) {
#ifdef WEBRTC_BIG_ENDIAN tempVal = (encoded[n >> 1] >> 8);
if ((n & 0x1) == 1) { } else {
tempVal=((WebRtc_UWord16)encoded[n>>1] & 0xFF); tempVal = (encoded[n >> 1] & 0xFF);
} else {
tempVal=((WebRtc_UWord16)encoded[n>>1] >> 8);
}
#else
if ((n & 0x1) == 1) {
tempVal = (encoded[n >> 1] >> 8);
} else {
tempVal = (encoded[n >> 1] & 0xFF);
}
#endif
decoded[n] = (WebRtc_Word16) alaw_to_linear(tempVal);
} }
#endif
decoded[n] = (int16_t) alaw_to_linear(tempVal);
}
*speechType = 1; *speechType = 1;
return (len); return (len);
} }
WebRtc_Word16 WebRtcG711_DecodeU(void *state, int16_t WebRtcG711_DecodeU(void* state,
WebRtc_Word16 *encoded, int16_t* encoded,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *decoded, int16_t* decoded,
WebRtc_Word16 *speechType) int16_t* speechType) {
{ int n;
int n; uint16_t tempVal;
WebRtc_UWord16 tempVal;
// Set and discard to avoid getting warnings // Set and discard to avoid getting warnings
(void)(state = NULL); (void)(state = NULL);
// Sanity check of input length // Sanity check of input length
if (len < 0) { if (len < 0) {
return (-1); return (-1);
}
for (n = 0; n < len; n++) {
#ifdef WEBRTC_BIG_ENDIAN
if ((n & 0x1) == 1) {
tempVal = ((uint16_t) encoded[n >> 1] & 0xFF);
} else {
tempVal = ((uint16_t) encoded[n >> 1] >> 8);
} }
#else
for (n = 0; n < len; n++) { if ((n & 0x1) == 1) {
#ifdef WEBRTC_BIG_ENDIAN tempVal = (encoded[n >> 1] >> 8);
if ((n & 0x1) == 1) { } else {
tempVal=((WebRtc_UWord16)encoded[n>>1] & 0xFF); tempVal = (encoded[n >> 1] & 0xFF);
} else {
tempVal=((WebRtc_UWord16)encoded[n>>1] >> 8);
}
#else
if ((n & 0x1) == 1) {
tempVal = (encoded[n >> 1] >> 8);
} else {
tempVal = (encoded[n >> 1] & 0xFF);
}
#endif
decoded[n] = (WebRtc_Word16) ulaw_to_linear(tempVal);
} }
#endif
decoded[n] = (int16_t) ulaw_to_linear(tempVal);
}
*speechType = 1; *speechType = 1;
return (len); return (len);
} }
int WebRtcG711_DurationEst(void* state, int WebRtcG711_DurationEst(void* state,
const uint8_t* payload, const uint8_t* payload,
int payload_length_bytes) { int payload_length_bytes) {
(void)state; (void) state;
(void)payload; (void) payload;
/* G.711 is one byte per sample, so we can just return the number of /* G.711 is one byte per sample, so we can just return the number of bytes. */
bytes. */ return payload_length_bytes;
return payload_length_bytes;
} }
WebRtc_Word16 WebRtcG711_Version(char* version, WebRtc_Word16 lenBytes) int16_t WebRtcG711_Version(char* version, int16_t lenBytes) {
{ strncpy(version, "2.0.0", lenBytes);
strncpy(version, "2.0.0", lenBytes); return 0;
return 0;
} }

View File

@@ -14,8 +14,8 @@
#include "typedefs.h" #include "typedefs.h"
// Comfort noise constants // Comfort noise constants
#define G711_WEBRTC_SPEECH 1 #define G711_WEBRTC_SPEECH 1
#define G711_WEBRTC_CNG 2 #define G711_WEBRTC_CNG 2
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -40,10 +40,10 @@ extern "C" {
* -1 - Error * -1 - Error
*/ */
WebRtc_Word16 WebRtcG711_EncodeA(void *state, int16_t WebRtcG711_EncodeA(void* state,
WebRtc_Word16 *speechIn, int16_t* speechIn,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *encoded); int16_t* encoded);
/**************************************************************************** /****************************************************************************
* WebRtcG711_EncodeU(...) * WebRtcG711_EncodeU(...)
@@ -64,10 +64,10 @@ WebRtc_Word16 WebRtcG711_EncodeA(void *state,
* -1 - Error * -1 - Error
*/ */
WebRtc_Word16 WebRtcG711_EncodeU(void *state, int16_t WebRtcG711_EncodeU(void* state,
WebRtc_Word16 *speechIn, int16_t* speechIn,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *encoded); int16_t* encoded);
/**************************************************************************** /****************************************************************************
* WebRtcG711_DecodeA(...) * WebRtcG711_DecodeA(...)
@@ -90,11 +90,11 @@ WebRtc_Word16 WebRtcG711_EncodeU(void *state,
* -1 - Error * -1 - Error
*/ */
WebRtc_Word16 WebRtcG711_DecodeA(void *state, int16_t WebRtcG711_DecodeA(void* state,
WebRtc_Word16 *encoded, int16_t* encoded,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *decoded, int16_t* decoded,
WebRtc_Word16 *speechType); int16_t* speechType);
/**************************************************************************** /****************************************************************************
* WebRtcG711_DecodeU(...) * WebRtcG711_DecodeU(...)
@@ -117,12 +117,11 @@ WebRtc_Word16 WebRtcG711_DecodeA(void *state,
* -1 - Error * -1 - Error
*/ */
WebRtc_Word16 WebRtcG711_DecodeU(void *state, int16_t WebRtcG711_DecodeU(void* state,
WebRtc_Word16 *encoded, int16_t* encoded,
WebRtc_Word16 len, int16_t len,
WebRtc_Word16 *decoded, int16_t* decoded,
WebRtc_Word16 *speechType); int16_t* speechType);
/**************************************************************************** /****************************************************************************
* WebRtcG711_DurationEst(...) * WebRtcG711_DurationEst(...)
@@ -159,11 +158,10 @@ int WebRtcG711_DurationEst(void* state,
* *
*/ */
WebRtc_Word16 WebRtcG711_Version(char* version, WebRtc_Word16 lenBytes); int16_t WebRtcG711_Version(char* version, int16_t lenBytes);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ */ #endif /* MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ */

View File

@@ -21,158 +21,160 @@
/* Runtime statistics */ /* Runtime statistics */
#include <time.h> #include <time.h>
#define CLOCKS_PER_SEC_G711 1000 #define CLOCKS_PER_SEC_G711 1000
/* function for reading audio data from PCM file */ /* function for reading audio data from PCM file */
int readframe(WebRtc_Word16 *data, FILE *inp, int length) { int readframe(int16_t* data, FILE* inp, int length) {
short k, rlen, status = 0; short k, rlen, status = 0;
rlen = (short)fread(data, sizeof(WebRtc_Word16), length, inp); rlen = (short) fread(data, sizeof(int16_t), length, inp);
if (rlen < length) { if (rlen < length) {
for (k = rlen; k < length; k++) for (k = rlen; k < length; k++)
data[k] = 0; data[k] = 0;
status = 1; status = 1;
} }
return status; return status;
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[]) {
{ char inname[80], outname[40], bitname[40];
char inname[80], outname[40], bitname[40]; FILE* inp;
FILE *inp, *outp, *bitp = NULL; FILE* outp;
int framecnt, endfile; FILE* bitp = NULL;
int framecnt, endfile;
WebRtc_Word16 framelength = 80; int16_t framelength = 80;
int err; int err;
/* Runtime statistics */ /* Runtime statistics */
double starttime; double starttime;
double runtime; double runtime;
double length_file; double length_file;
WebRtc_Word16 stream_len = 0; int16_t stream_len = 0;
WebRtc_Word16 shortdata[480]; int16_t shortdata[480];
WebRtc_Word16 decoded[480]; int16_t decoded[480];
WebRtc_Word16 streamdata[500]; int16_t streamdata[500];
WebRtc_Word16 speechType[1]; int16_t speechType[1];
char law[2]; char law[2];
char versionNumber[40]; char versionNumber[40];
/* handling wrong input arguments in the command line */ /* handling wrong input arguments in the command line */
if ((argc!=5) && (argc!=6)) { if ((argc != 5) && (argc != 6)) {
printf("\n\nWrong number of arguments or flag values.\n\n"); printf("\n\nWrong number of arguments or flag values.\n\n");
printf("\n"); printf("\n");
printf("\nG.711 test application\n\n"); printf("\nG.711 test application\n\n");
printf("Usage:\n\n"); printf("Usage:\n\n");
printf("./testG711.exe framelength law infile outfile \n\n"); printf("./testG711.exe framelength law infile outfile \n\n");
printf("framelength: Framelength in samples.\n"); printf("framelength: Framelength in samples.\n");
printf("law : Coding law, A och u.\n"); printf("law : Coding law, A och u.\n");
printf("infile : Normal speech input file\n"); printf("infile : Normal speech input file\n");
printf("outfile : Speech output file\n\n"); printf("outfile : Speech output file\n\n");
printf("outbits : Output bitstream file [optional]\n\n"); printf("outbits : Output bitstream file [optional]\n\n");
exit(0); exit(0);
}
/* Get version and print */
WebRtcG711_Version(versionNumber, 40);
printf("-----------------------------------\n");
printf("G.711 version: %s\n\n", versionNumber);
/* Get frame length */
framelength = atoi(argv[1]);
/* Get compression law */
strcpy(law, argv[2]);
/* Get Input and Output files */
sscanf(argv[3], "%s", inname);
sscanf(argv[4], "%s", outname);
if (argc == 6) {
sscanf(argv[5], "%s", bitname);
if ((bitp = fopen(bitname, "wb")) == NULL) {
printf(" G.711: Cannot read file %s.\n", bitname);
exit(1);
} }
}
/* Get version and print */ if ((inp = fopen(inname, "rb")) == NULL) {
WebRtcG711_Version(versionNumber, 40); printf(" G.711: Cannot read file %s.\n", inname);
exit(1);
}
if ((outp = fopen(outname, "wb")) == NULL) {
printf(" G.711: Cannot write file %s.\n", outname);
exit(1);
}
printf("\nInput: %s\nOutput: %s\n", inname, outname);
if (argc == 6) {
printf("\nBitfile: %s\n", bitname);
}
printf("-----------------------------------\n"); starttime = clock() / (double) CLOCKS_PER_SEC_G711; /* Runtime statistics */
printf("G.711 version: %s\n\n", versionNumber);
/* Get frame length */
framelength = atoi(argv[1]);
/* Get compression law */
strcpy(law, argv[2]);
/* Get Input and Output files */ /* Initialize encoder and decoder */
sscanf(argv[3], "%s", inname); framecnt = 0;
sscanf(argv[4], "%s", outname); endfile = 0;
if (argc==6) { while (endfile == 0) {
sscanf(argv[5], "%s", bitname); framecnt++;
if ((bitp = fopen(bitname,"wb")) == NULL) { /* Read speech block */
printf(" G.711: Cannot read file %s.\n", bitname); endfile = readframe(shortdata, inp, framelength);
exit(1);
/* G.711 encoding */
if (!strcmp(law, "A")) {
/* A-law encoding */
stream_len = WebRtcG711_EncodeA(NULL, shortdata, framelength, streamdata);
if (argc == 6) {
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
static_cast<size_t>(stream_len)) {
return -1;
} }
} }
err = WebRtcG711_DecodeA(NULL, streamdata, stream_len, decoded,
if ((inp = fopen(inname,"rb")) == NULL) { speechType);
printf(" G.711: Cannot read file %s.\n", inname); } else if (!strcmp(law, "u")) {
exit(1); /* u-law encoding */
} stream_len = WebRtcG711_EncodeU(NULL, shortdata, framelength, streamdata);
if ((outp = fopen(outname,"wb")) == NULL) { if (argc == 6) {
printf(" G.711: Cannot write file %s.\n", outname); /* Write bits to file */
exit(1); if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
} static_cast<size_t>(stream_len)) {
printf("\nInput: %s\nOutput: %s\n", inname, outname); return -1;
if (argc==6) {
printf("\nBitfile: %s\n", bitname);
}
starttime = clock()/(double)CLOCKS_PER_SEC_G711; /* Runtime statistics */
/* Initialize encoder and decoder */
framecnt= 0;
endfile = 0;
while (endfile == 0) {
framecnt++;
/* Read speech block */
endfile = readframe(shortdata, inp, framelength);
/* G.711 encoding */
if (!strcmp(law,"A")) {
/* A-law encoding */
stream_len = WebRtcG711_EncodeA(NULL, shortdata, framelength, streamdata);
if (argc==6){
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len,
bitp) != static_cast<size_t>(stream_len)) {
return -1;
}
}
err = WebRtcG711_DecodeA(NULL, streamdata, stream_len, decoded, speechType);
} else if (!strcmp(law,"u")){
/* u-law encoding */
stream_len = WebRtcG711_EncodeU(NULL, shortdata, framelength, streamdata);
if (argc==6){
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len,
bitp) != static_cast<size_t>(stream_len)) {
return -1;
}
}
err = WebRtcG711_DecodeU(NULL, streamdata, stream_len, decoded, speechType);
} else {
printf("Wrong law mode\n");
exit (1);
}
if (stream_len < 0 || err < 0) {
/* exit if returned with error */
printf("Error in encoder/decoder\n");
} else {
/* Write coded speech to file */
if (fwrite(decoded, sizeof(short), framelength,
outp) != static_cast<size_t>(framelength)) {
return -1;
}
} }
}
err = WebRtcG711_DecodeU(NULL, streamdata, stream_len, decoded,
speechType);
} else {
printf("Wrong law mode\n");
exit(1);
} }
if (stream_len < 0 || err < 0) {
/* exit if returned with error */
printf("Error in encoder/decoder\n");
} else {
/* Write coded speech to file */
if (fwrite(decoded, sizeof(short), framelength, outp) !=
static_cast<size_t>(framelength)) {
return -1;
}
}
}
runtime = (double)(clock() / (double) CLOCKS_PER_SEC_G711 - starttime);
length_file = ((double) framecnt * (double) framelength / 8000);
printf("\n\nLength of speech file: %.1f s\n", length_file);
printf("Time to run G.711: %.2f s (%.2f %% of realtime)\n\n",
runtime,
(100 * runtime / length_file));
printf("---------------------END----------------------\n");
runtime = (double)(clock()/(double)CLOCKS_PER_SEC_G711-starttime); fclose(inp);
length_file = ((double)framecnt*(double)framelength/8000); fclose(outp);
printf("\n\nLength of speech file: %.1f s\n", length_file);
printf("Time to run G.711: %.2f s (%.2f %% of realtime)\n\n", runtime, (100*runtime/length_file));
printf("---------------------END----------------------\n");
fclose(inp); return 0;
fclose(outp);
return 0;
} }