Newsgroups: comp.speech
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!europa.eng.gtefsd.com!darwin.sura.net!metropolis!cfreese
From: cfreese@super.org (Craig F. Reese)
Subject: FAQ ulaw code is *WRONG* !!!!
Message-ID: <1994Dec14.234851.23837@super.org>
Summary: HTML eats code?  Film at 11....
Sender: cfreese@super.org
Nntp-Posting-Host: hume
Cc: cfreese@super.org andrewh@speech.su.oz.au maz@sst.ll.mit.edu jpcampb@afterlife.ncsc.mil
Organization: Supercomputing Research Center (Bowie, MD)
Date: Wed, 14 Dec 1994 23:48:51 GMT
Lines: 172


As Marc Zissman so kindly pointed out, the following code (attributed
to Joe and me) is very WRONG!  For some very bizarre reason, it
looks like someone executed 'tr "><" "<>"' on it.

Most notably:

>  /* Get the sample into sign-magnitude. */
>  sign = (sample << 8) & 0x80;          /* set aside the sign */
>  if(sign != 0) sample = -sample;               /* get magnitude */
>  if(sample < CLIP) sample = CLIP;              /* clip the magnitude */

Should be:

    /** get the sample into sign-magnitude **/
    sign = (sample >> 8) & 0x80;        /* set aside the sign */
    if (sign != 0) sample = -sample;    /* get magnitude */
    if (sample > CLIP) sample = CLIP;   /* clip the magnitude */

In any case, don't expect it to work as posted.  I've included a 
_correct_ version at the end.

(Is this an HTML-ism?  I don't know much about HTML other than
(it contains lots of '<' and '>'.  Boy I sure hope we aren't putting
(heart pacemaker C code on WWW servers... ;^)

Craig

    
    Path: super!cfreese
    From: cfreese@super.ORG (Craig F. Reese)
    Newsgroups: comp.dsp
    Subject: SPARCStation audio conversion (ulaw <-> linear)
    Message-ID: <14899@super.ORG>
    Date: 29 Sep 89 23:23:49 GMT
    Sender: news@super.ORG
    Reply-To: cfreese@super.UUCP (Craig F. Reese)
    Distribution: na
    Organization: Supercomputing Research Center, Bowie, Md.
    Lines: 120
    
    TWIMC,
    
    Below are two routines I wrote for converting between ulaw and linear. 
    I use them with the SparcStation and they seem to work fine.
    I am pretty sure (99.9%) that they implement the standard as specified
    in the references. 
    
    Note that the standard deals with converting between 12 bit linear
    and 8 bit ulaw.  These routines assume 16 bit linear.  Thus, some
    bit shifting may be necessary.
    
    craig
    
    ------------------------------------------------------------------
    /**
     ** Signal conversion routines for use with the Sun4/60 audio chip
     **/
    
    /*
     * This routine converts from linear to ulaw
     * 29 September 1989
     *
     * Craig Reese: IDA/Supercomputing Research Center
     * Joe Campbell: Department of Defense
     *
     * References:
     * 1) CCITT Recommendation G.711  (very difficult to follow)
     * 2) "A New Digital Technique for Implementation of Any 
     *     Continuous PCM Companding Law," Villeret, Michel,
     *     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
     *     1973, pg. 11.12-11.17
     * 3) MIL-STD-188-113,"Interoperability and Performance Standards
     *     for Analog-to_Digital Conversion Techniques,"
     *     17 February 1987
     *
     * Input: Signed 16 bit linear sample
     * Output: 8 bit ulaw sample
     */
    
    #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
    #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
    #define CLIP 32635
    
    unsigned char
    linear2ulaw(sample)
    int sample;
    {
        static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
                                   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
                                   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
                                   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
                                   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                                   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                                   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                                   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
        int sign, exponent, mantissa;
        unsigned char ulawbyte;
    
        /** get the sample into sign-magnitude **/
        sign = (sample >> 8) & 0x80;        /* set aside the sign */
        if (sign != 0) sample = -sample;    /* get magnitude */
        if (sample > CLIP) sample = CLIP;   /* clip the magnitude */
        /** convert from 16 bit linear to ulaw **/
        sample = sample + BIAS;
        exponent = exp_lut[(sample>>7) & 0xFF];
        mantissa = (sample >> (exponent+3)) & 0x0F;
        ulawbyte = ~(sign | (exponent << 4) | mantissa);
    #ifdef ZEROTRAP
        if (ulawbyte == 0 ) ulawbyte = 0x02;  /* optional CCITT trap */
    #endif
        /** return the result **/
        return(ulawbyte);
        }
    
    /*
     * This routine converts from ulaw to 16 bit linear
     * 29 September 1989
     *
     * Craig Reese: IDA/Supercomputing Research Center
     *
     * References:
     * 1) CCITT Recommendation G.711  (very difficult to follow)
     * 2) MIL-STD-188-113,"Interoperability and Performance Standards
     *     for Analog-to_Digital Conversion Techniques,"
     *     17 February 1987
     *
     * Input: 8 bit ulaw sample
     * Output: signed 16 bit linear sample
     */
    
    int
    ulaw2linear(ulawbyte)
    unsigned char ulawbyte;
    {
        static int exp_lut[8]={0,132,396,924,1980,4092,8316,16764};
        int sign, exponent, mantissa, sample;
    
        ulawbyte = ~ulawbyte;
        sign = (ulawbyte & 0x80);
        exponent = (ulawbyte >> 4) & 0x07;
        mantissa = ulawbyte & 0x0F;
        sample = exp_lut[exponent] + (mantissa << (exponent+3));
        if (sign != 0) sample = -sample;
        return(sample);
        }
    
    -----------------

TheeDaDeeDaDeeee That's all folx....

*** The opinions expressed are my own and do not necessarily reflect 
*** those of any other land dwelling mammals....

"The problem ain't what we don't know; it's what we know that just ain't so
Either we take familiar things so much for granted that we never think about 
how they originated, or we "know" too much about them to investigate closely."
 -Unknown
-----------------
Craig F. Reese                           Email: cfreese@super.org
Institute for Defense Analyses/
Supercomputing Research Center
17100 Science Dr.
Bowie, MD  20715-4300
