home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "cdsend.h"
-
- #define A 1
- #define B 7
-
- static int d;
- static int prev_i, cur_i;
- static int rate_i = IN_RATE, rate_o = OUT_RATE;
- static short outbuf[(CDDA_NUMSAMPLES/2)*OUT_RATE/IN_RATE + 1];
-
- #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
-
- static unsigned char
- st_linear_to_ulaw(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 ulawbyte;
- }
-
- void
- init_convert(void)
- {
- d = -OUT_RATE;
- prev_i = cur_i = 0;
- }
-
- void
- convert_audio_and_print(short *audio, int nsamples, int linear)
- {
- int cur_o;
- short *outp = outbuf;
- #if !defined(A) || !defined(B)
- int ab = a + b;
- #endif
- int ld = d, lp = prev_i, lc = cur_i; /* local copy (register?) */
-
- #if !defined(A) || !defined(B)
- /* some efficiency hacks */
- ab *= 2;
- b *= 2;
- #endif
-
- for (;;) {
- while (ld < 0) {
- if (nsamples == 0) {
- d = ld;
- prev_i = lp;
- cur_i = lc;
-
- if (linear) {
- write(1, (char *) outbuf,
- sizeof(short) * (outp - outbuf));
- }
- return;
- }
- lp = lc;
- #if defined(A) && defined(B)
- lc = (A * (audio[0] + audio[1]) + 2*B * lp) / (2*(A+B));
- #else
- /* depends on efficiency hacks */
- lc = (a * (audio[0] + audio[1]) + b * lp) / ab;
- #endif
- nsamples--;
- audio += 2;
- ld += OUT_RATE;
- }
- #if IN_RATE < OUT_RATE
- while (ld >= 0)
- #endif
- {
- cur_o = (lp * ld + lc * (OUT_RATE - ld)) / OUT_RATE;
- if (linear) {
- *outp++ = cur_o;
- } else {
- /* not efficient at all */
- putchar(st_linear_to_ulaw(cur_o));
- }
- ld -= IN_RATE;
- }
- }
- }
-