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
*/
/*! \file */
#include "g711.h"
#include "typedefs.h"
/* Copied from the CCITT G.711 specification */
static const WebRtc_UWord8 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
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 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, 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
/* 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
};
WebRtc_UWord8 alaw_to_ulaw(WebRtc_UWord8 alaw)
{
return alaw_to_ulaw_table[alaw];
}
/*- End of function --------------------------------------------------------*/
uint8_t alaw_to_ulaw(uint8_t alaw) { return alaw_to_ulaw_table[alaw]; }
WebRtc_UWord8 ulaw_to_alaw(WebRtc_UWord8 ulaw)
{
return ulaw_to_alaw_table[ulaw];
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
uint8_t ulaw_to_alaw(uint8_t ulaw) { return ulaw_to_alaw_table[ulaw]; }

View File

@ -20,8 +20,6 @@
* -Two changes to make implementation bitexact with ITU-T reference implementation
*/
/*! \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
@ -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
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.
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
@ -57,128 +55,108 @@ extern "C" {
/*! \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;
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;
__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;
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;
__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;
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;
__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;
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;
__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 top_bit(unsigned int bits) {
int i;
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;
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;
}
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.
@ -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
* many other modern processors.
*/
/*
* 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_BIAS 0x84 /* Bias for linear code. */
#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 WebRtc_UWord8 linear_to_ulaw(int linear)
{
WebRtc_UWord8 u_val;
int mask;
int seg;
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)
{
/* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */
linear = ULAW_BIAS - linear - 1;
mask = 0x7F;
}
else
{
linear = ULAW_BIAS + linear;
mask = 0xFF;
}
/* Get the sign and the magnitude of the value. */
if (linear < 0) {
/* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */
linear = ULAW_BIAS - linear - 1;
mask = 0x7F;
} else {
linear = ULAW_BIAS + linear;
mask = 0xFF;
}
seg = top_bit(linear | 0xFF) - 7;
seg = top_bit(linear | 0xFF) - 7;
/*
* Combine the sign, segment, quantization bits,
* and complement the code word.
*/
if (seg >= 8)
u_val = (WebRtc_UWord8) (0x7F ^ mask);
else
u_val = (WebRtc_UWord8) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
/*
* 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;
/* Optional ITU trap */
if (u_val == 0)
u_val = 0x02;
#endif
return u_val;
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 WebRtc_Word16 ulaw_to_linear(WebRtc_UWord8 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 (WebRtc_Word16) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
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:
@ -300,83 +271,74 @@ static __inline WebRtc_Word16 ulaw_to_linear(WebRtc_UWord8 ulaw)
* 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
\param linear The sample to encode.
\return The A-law value.
*/
static __inline WebRtc_UWord8 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;
/* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference
* implementation */
linear = -linear - 1;
}
static __inline uint8_t linear_to_alaw(int linear) {
int mask;
int seg;
/* 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 (WebRtc_UWord8) (0x7F ^ mask);
}
/* We must be just a tiny step below zero */
return (WebRtc_UWord8) (0x00 ^ mask);
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. */
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. */
return (WebRtc_UWord8) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ 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 WebRtc_Word16 alaw_to_linear(WebRtc_UWord8 alaw)
{
int i;
int seg;
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 (WebRtc_Word16) ((alaw & 0x80) ? i : -i);
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.
*/
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.
\param alaw The u-law sample to transcode.
\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
}
#endif
#endif
/*- End of file ------------------------------------------------------------*/

View File

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

View File

@ -14,8 +14,8 @@
#include "typedefs.h"
// Comfort noise constants
#define G711_WEBRTC_SPEECH 1
#define G711_WEBRTC_CNG 2
#define G711_WEBRTC_SPEECH 1
#define G711_WEBRTC_CNG 2
#ifdef __cplusplus
extern "C" {
@ -40,10 +40,10 @@ extern "C" {
* -1 - Error
*/
WebRtc_Word16 WebRtcG711_EncodeA(void *state,
WebRtc_Word16 *speechIn,
WebRtc_Word16 len,
WebRtc_Word16 *encoded);
int16_t WebRtcG711_EncodeA(void* state,
int16_t* speechIn,
int16_t len,
int16_t* encoded);
/****************************************************************************
* WebRtcG711_EncodeU(...)
@ -64,10 +64,10 @@ WebRtc_Word16 WebRtcG711_EncodeA(void *state,
* -1 - Error
*/
WebRtc_Word16 WebRtcG711_EncodeU(void *state,
WebRtc_Word16 *speechIn,
WebRtc_Word16 len,
WebRtc_Word16 *encoded);
int16_t WebRtcG711_EncodeU(void* state,
int16_t* speechIn,
int16_t len,
int16_t* encoded);
/****************************************************************************
* WebRtcG711_DecodeA(...)
@ -90,11 +90,11 @@ WebRtc_Word16 WebRtcG711_EncodeU(void *state,
* -1 - Error
*/
WebRtc_Word16 WebRtcG711_DecodeA(void *state,
WebRtc_Word16 *encoded,
WebRtc_Word16 len,
WebRtc_Word16 *decoded,
WebRtc_Word16 *speechType);
int16_t WebRtcG711_DecodeA(void* state,
int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType);
/****************************************************************************
* WebRtcG711_DecodeU(...)
@ -117,12 +117,11 @@ WebRtc_Word16 WebRtcG711_DecodeA(void *state,
* -1 - Error
*/
WebRtc_Word16 WebRtcG711_DecodeU(void *state,
WebRtc_Word16 *encoded,
WebRtc_Word16 len,
WebRtc_Word16 *decoded,
WebRtc_Word16 *speechType);
int16_t WebRtcG711_DecodeU(void* state,
int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType);
/****************************************************************************
* 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
}
#endif
#endif /* MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ */

View File

@ -21,158 +21,160 @@
/* Runtime statistics */
#include <time.h>
#define CLOCKS_PER_SEC_G711 1000
#define CLOCKS_PER_SEC_G711 1000
/* 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);
if (rlen < length) {
for (k = rlen; k < length; k++)
data[k] = 0;
status = 1;
}
rlen = (short) fread(data, sizeof(int16_t), length, inp);
if (rlen < length) {
for (k = rlen; k < length; k++)
data[k] = 0;
status = 1;
}
return status;
return status;
}
int main(int argc, char* argv[])
{
char inname[80], outname[40], bitname[40];
FILE *inp, *outp, *bitp = NULL;
int framecnt, endfile;
int main(int argc, char* argv[]) {
char inname[80], outname[40], bitname[40];
FILE* inp;
FILE* outp;
FILE* bitp = NULL;
int framecnt, endfile;
WebRtc_Word16 framelength = 80;
int16_t framelength = 80;
int err;
int err;
/* Runtime statistics */
double starttime;
double runtime;
double length_file;
/* Runtime statistics */
double starttime;
double runtime;
double length_file;
WebRtc_Word16 stream_len = 0;
WebRtc_Word16 shortdata[480];
WebRtc_Word16 decoded[480];
WebRtc_Word16 streamdata[500];
WebRtc_Word16 speechType[1];
char law[2];
char versionNumber[40];
int16_t stream_len = 0;
int16_t shortdata[480];
int16_t decoded[480];
int16_t streamdata[500];
int16_t speechType[1];
char law[2];
char versionNumber[40];
/* handling wrong input arguments in the command line */
if ((argc!=5) && (argc!=6)) {
printf("\n\nWrong number of arguments or flag values.\n\n");
/* handling wrong input arguments in the command line */
if ((argc != 5) && (argc != 6)) {
printf("\n\nWrong number of arguments or flag values.\n\n");
printf("\n");
printf("\nG.711 test application\n\n");
printf("Usage:\n\n");
printf("./testG711.exe framelength law infile outfile \n\n");
printf("framelength: Framelength in samples.\n");
printf("law : Coding law, A och u.\n");
printf("infile : Normal speech input file\n");
printf("outfile : Speech output file\n\n");
printf("outbits : Output bitstream file [optional]\n\n");
exit(0);
printf("\n");
printf("\nG.711 test application\n\n");
printf("Usage:\n\n");
printf("./testG711.exe framelength law infile outfile \n\n");
printf("framelength: Framelength in samples.\n");
printf("law : Coding law, A och u.\n");
printf("infile : Normal speech input file\n");
printf("outfile : Speech output file\n\n");
printf("outbits : Output bitstream file [optional]\n\n");
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 */
WebRtcG711_Version(versionNumber, 40);
if ((inp = fopen(inname, "rb")) == NULL) {
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");
printf("G.711 version: %s\n\n", versionNumber);
/* Get frame length */
framelength = atoi(argv[1]);
/* Get compression law */
strcpy(law, argv[2]);
starttime = clock() / (double) CLOCKS_PER_SEC_G711; /* Runtime statistics */
/* 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);
/* 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;
}
}
if ((inp = fopen(inname,"rb")) == NULL) {
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);
}
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_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;
}
}
}
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);
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");
fclose(inp);
fclose(outp);
fclose(inp);
fclose(outp);
return 0;
return 0;
}