diff options
author | murf <murf@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-08-20 22:53:48 +0000 |
---|---|---|
committer | murf <murf@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-08-20 22:53:48 +0000 |
commit | 8b5681e22acd883fc692455b460a6385e521b683 (patch) | |
tree | ba8c79a84cc6cbddcd2d849a6b9895d6124c4452 /include | |
parent | 160c516178ec81b8a2321f84b18ea8cece00f142 (diff) |
This change set fixes bug 8126 in trunk. It is implemented via compile time options, activated via the menuselect stuff, which defaults to the old way. non-zero sample data added. Translate tables expressed in microseconds instead of milliseconds, with 5-digit data now instead of 3, giving 2 more digits of precision.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@80113 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r-- | include/asterisk/alaw.h | 52 | ||||
-rw-r--r-- | include/asterisk/ulaw.h | 47 |
2 files changed, 96 insertions, 3 deletions
diff --git a/include/asterisk/alaw.h b/include/asterisk/alaw.h index 44b3bad86..34968969d 100644 --- a/include/asterisk/alaw.h +++ b/include/asterisk/alaw.h @@ -23,21 +23,67 @@ #ifndef _ASTERISK_ALAW_H #define _ASTERISK_ALAW_H + /*! Init the ulaw conversion stuff */ /*! - * To init the ulaw to slinear conversion stuff, this needs to be run. + * To init the alaw to slinear conversion stuff, this needs to be run. */ void ast_alaw_init(void); -/*! converts signed linear to mulaw */ +#define AST_ALAW_BIT_LOSS 4 +#define AST_ALAW_STEP (1 << AST_ALAW_BIT_LOSS) +#define AST_ALAW_TAB_SIZE (32768 / AST_ALAW_STEP + 1) +#define AST_ALAW_SIGN_BIT 0x80 +#define AST_ALAW_AMI_MASK 0x55 + + +/*! converts signed linear to alaw */ /*! - */ + */ +#ifndef G711_NEW_ALGORITHM extern unsigned char __ast_lin2a[8192]; +#else +extern unsigned char __ast_lin2a[AST_ALAW_TAB_SIZE]; +#endif /*! help */ extern short __ast_alaw[256]; +#ifndef G711_NEW_ALGORITHM #define AST_LIN2A(a) (__ast_lin2a[((unsigned short)(a)) >> 3]) +#else +#define AST_LIN2A_LOOKUP(mag) \ + __ast_lin2a[(mag) >> AST_ALAW_BIT_LOSS] + +/*! convert signed linear sample to sign-magnitude pair for a-Law */ +static inline void ast_alaw_get_sign_mag(short sample, unsigned *sign, unsigned *mag) +{ + /* It may look illogical to retrive the sign this way in both cases, + * but this helps gcc eliminate the branch below and produces + * faster code */ + *sign = ((unsigned short)sample >> 8) & AST_ALAW_SIGN_BIT; +#if defined(G711_REDUCED_BRANCHING) + { + unsigned dual_mag = (-sample << 16) | (unsigned short)sample; + *mag = (dual_mag >> (*sign >> 3)) & 0xffffU; + } +#else + if (sample < 0) + *mag = -sample; + else + *mag = sample; +#endif /* G711_REDUCED_BRANCHING */ + *sign ^= AST_ALAW_SIGN_BIT; +} + +static inline unsigned char AST_LIN2A(short sample) +{ + unsigned mag, sign; + ast_alaw_get_sign_mag(sample, &sign, &mag); + return (sign | AST_LIN2A_LOOKUP(mag)) ^ AST_ALAW_AMI_MASK; +} +#endif + #define AST_ALAW(a) (__ast_alaw[(int)(a)]) #endif /* _ASTERISK_ALAW_H */ diff --git a/include/asterisk/ulaw.h b/include/asterisk/ulaw.h index d9ab0d178..1ac079d54 100644 --- a/include/asterisk/ulaw.h +++ b/include/asterisk/ulaw.h @@ -23,21 +23,68 @@ #ifndef _ASTERISK_ULAW_H #define _ASTERISK_ULAW_H + /*! Init the ulaw conversion stuff */ /*! * To init the ulaw to slinear conversion stuff, this needs to be run. */ void ast_ulaw_init(void); +#define AST_ULAW_BIT_LOSS 3 +#define AST_ULAW_STEP (1 << AST_ULAW_BIT_LOSS) +#define AST_ULAW_TAB_SIZE (32768 / AST_ULAW_STEP + 1) +#define AST_ULAW_SIGN_BIT 0x80 + /*! converts signed linear to mulaw */ /*! */ +#ifndef G711_NEW_ALGORITHM extern unsigned char __ast_lin2mu[16384]; +#else +extern unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE]; +#endif /*! help */ extern short __ast_mulaw[256]; +#ifndef G711_NEW_ALGORITHM + #define AST_LIN2MU(a) (__ast_lin2mu[((unsigned short)(a)) >> 2]) + +#else + +#define AST_LIN2MU_LOOKUP(mag) \ + __ast_lin2mu[((mag) + AST_ULAW_STEP / 2) >> AST_ULAW_BIT_LOSS] + + +/*! convert signed linear sample to sign-magnitude pair for u-Law */ +static inline void ast_ulaw_get_sign_mag(short sample, unsigned *sign, unsigned *mag) +{ + /* It may look illogical to retrive the sign this way in both cases, + * but this helps gcc eliminate the branch below and produces + * faster code */ + *sign = ((unsigned short)sample >> 8) & AST_ULAW_SIGN_BIT; +#if defined(G711_REDUCED_BRANCHING) + { + unsigned dual_mag = (-sample << 16) | (unsigned short)sample; + *mag = (dual_mag >> (*sign >> 3)) & 0xffffU; + } +#else + if (sample < 0) + *mag = -sample; + else + *mag = sample; +#endif /* G711_REDUCED_BRANCHING */ +} + +static inline unsigned char AST_LIN2MU(short sample) +{ + unsigned mag, sign; + ast_ulaw_get_sign_mag(sample, &sign, &mag); + return ~(sign | AST_LIN2MU_LOOKUP(mag)); +} +#endif + #define AST_MULAW(a) (__ast_mulaw[(a)]) #endif /* _ASTERISK_ULAW_H */ |