Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

alaw.cpp

Go to the documentation of this file.
00001 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 #include "alaw.h"
00032 
00033 #define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
00034 #define QUANT_MASK      (0xf)           /* Quantization field mask. */
00035 #define NSEGS           (8)             /* Number of A-law segments. */
00036 #define SEG_SHIFT       (4)             /* Left shift for segment number. */
00037 #define SEG_MASK        (0x70)          /* Segment field mask. */
00038 
00039 static const short alaw_seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
00040                                 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
00041 
00042 inline int Alaw::search(int val, const short *table, int size)
00043 {
00044         int i;
00045 
00046         for (i = 0; i < size; i++) {
00047                 if (val <= *table++)
00048                         return (i);
00049         }
00050         return (size);
00051 }
00052 
00053 /*
00054  * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
00055  *
00056  * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
00057  *
00058  *              Linear Input Code       Compressed Code
00059  *      ------------------------        ---------------
00060  *      0000000wxyza                    000wxyz
00061  *      0000001wxyza                    001wxyz
00062  *      000001wxyzab                    010wxyz
00063  *      00001wxyzabc                    011wxyz
00064  *      0001wxyzabcd                    100wxyz
00065  *      001wxyzabcde                    101wxyz
00066  *      01wxyzabcdef                    110wxyz
00067  *      1wxyzabcdefg                    111wxyz
00068  *
00069  * For further information see John C. Bellamy's Digital Telephony, 1982,
00070  * John Wiley & Sons, pps 98-111 and 472-476.
00071  */
00072 inline unsigned char Alaw::linear2alaw(int pcm_val)     /* 2's complement (16-bit range) */
00073 {
00074         int             mask;
00075         int             seg;
00076         unsigned char   aval;
00077 
00078         if (pcm_val >= 0) {
00079                 mask = 0xD5;            /* sign (7th) bit = 1 */
00080         } else {
00081                 mask = 0x55;            /* sign bit = 0 */
00082                 pcm_val = -pcm_val - 8;
00083         }
00084 
00085         /* Convert the scaled magnitude to segment number. */
00086         seg = search(pcm_val, alaw_seg_end, NSEGS);
00087 
00088         /* Combine the sign, segment, and quantization bits. */
00089 
00090         if (seg >= 8)           /* out of range, return maximum value. */
00091                 return (unsigned char)(0x7F ^ mask);
00092         else {
00093                 aval = (unsigned char)(seg << SEG_SHIFT);
00094                 if (seg < 2)
00095                         aval |= (pcm_val >> 4) & QUANT_MASK;
00096                 else
00097                         aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
00098                 return (unsigned char)(aval ^ mask);
00099         }
00100 }
00101 
00102 
00103 void Alaw::conv_u8bit_alaw(unsigned char *src_ptr, unsigned char *dst_ptr, size_t size)
00104 {
00105         unsigned int pcm;
00106 
00107         while (size-- > 0) {
00108                 pcm = ((*src_ptr++) ^ 0x80) << 8;
00109                 *dst_ptr++ = linear2alaw((signed short)(pcm));
00110         }
00111 }
00112 
00113 void Alaw::conv_s8bit_alaw(unsigned char *src_ptr, unsigned char *dst_ptr, size_t size)
00114 {
00115         unsigned int pcm;
00116 
00117         while (size-- > 0) {
00118                 pcm = *src_ptr++ << 8;
00119                 *dst_ptr++ = Alaw::linear2alaw((signed short)(pcm));
00120         }
00121 }
00122 
00123 void Alaw::conv_s16bit_alaw(unsigned short *src_ptr, unsigned char *dst_ptr, size_t size)
00124 {
00125         while (size-- > 0)
00126                 *dst_ptr++ = Alaw::linear2alaw((signed short)(*src_ptr++));
00127 }
00128 
00129 /*
00130 static void alaw_conv_s16bit_swap_alaw(unsigned short *src_ptr, unsigned char *dst_ptr, size_t size)
00131 {
00132         while (size-- > 0)
00133                 *dst_ptr++ = linear2alaw((signed short)(bswap_16(*src_ptr++)));
00134 }
00135 */
00136 
00137 void Alaw::conv_u16bit_alaw(unsigned short *src_ptr, unsigned char *dst_ptr, size_t size)
00138 {
00139         while (size-- > 0)
00140                 *dst_ptr++ = Alaw::linear2alaw((signed short)((*src_ptr++) ^ 0x8000));
00141 }
00142 
00143 /*
00144 static void alaw_conv_u16bit_swap_alaw(unsigned short *src_ptr, unsigned char *dst_ptr, size_t size)
00145 {
00146         while (size-- > 0)
00147                 *dst_ptr++ = linear2alaw((signed short)(bswap_16(*src_ptr++) ^ 0x8000));
00148 }
00149 */
00150 
00151 /*
00152 static void alaw_conv_alaw_u8bit(unsigned char *src_ptr, unsigned char *dst_ptr, size_t size)
00153 {
00154         while (size-- > 0)
00155                 *dst_ptr++ = (alaw2linear(*src_ptr++) >> 8) ^ 0x80;
00156 }
00157 
00158 static void alaw_conv_alaw_s8bit(unsigned char *src_ptr, unsigned char *dst_ptr, size_t size)
00159 {
00160         while (size-- > 0)
00161                 *dst_ptr++ = alaw2linear(*src_ptr++) >> 8;
00162 }
00163 
00164 static void alaw_conv_alaw_s16bit(unsigned char *src_ptr, unsigned short *dst_ptr, size_t size)
00165 {
00166         while (size-- > 0)
00167                 *dst_ptr++ = alaw2linear(*src_ptr++);
00168 }
00169 
00170 static void alaw_conv_alaw_swap_s16bit(unsigned char *src_ptr, unsigned short *dst_ptr, size_t size)
00171 {
00172         while (size-- > 0)
00173                 *dst_ptr++ = bswap_16(alaw2linear(*src_ptr++));
00174 }
00175 
00176 static void alaw_conv_alaw_u16bit(unsigned char *src_ptr, unsigned short *dst_ptr, size_t size)
00177 {
00178         while (size-- > 0)
00179                 *dst_ptr++ = alaw2linear(*src_ptr++) ^ 0x8000;
00180 }
00181 */
00182 
00183 /*
00184 static void alaw_conv_alaw_swap_u16bit(unsigned char *src_ptr, unsigned short *dst_ptr, size_t size)
00185 {
00186         while (size-- > 0)
00187                 *dst_ptr++ = bswap_16(alaw2linear(*src_ptr++) ^ 0x8000);
00188 }
00189 */

Generated on Tue Feb 8 04:13:56 2005 for Esidplay by doxygen 1.3.3