home *** CD-ROM | disk | FTP | other *** search
- /* common.c */
-
- /* common repository of code/macros for all architectures audio */
- /* $Id: common.c,v 1.9 1995/05/12 20:40:33 espie Exp espie $ */
- /* $Log: common.c,v $
- * Revision 1.9 1995/05/12 20:40:33 espie
- * Added audio_ui capability.
- *
- * Revision 1.8 1995/05/12 13:52:19 espie
- * New synchronization for sparc.
- * News ulaw conversion function.
- *
- * Revision 1.7 1995/03/17 00:30:59 espie
- * Fixed multiple stupid bugs in common.c (thanks Rolf)
- *
- * Revision 1.6 1995/02/27 14:25:37 espie
- * Rolf Grossmann patch.
- *
- * Revision 1.5 1995/02/26 23:07:14 espie
- * Changed sync to tsync.
- *
- * Revision 1.4 1995/02/23 23:33:01 espie
- * Linear resampling changed.
- *
- * Revision 1.3 1995/02/23 22:41:45 espie
- * Added # of bits.
- *
- * Revision 1.2 1995/02/23 17:03:14 espie
- * Continuing changes for a standard file.
- *
- * Revision 1.1 1995/02/23 16:42:10 espie
- * Initial revision
- *
- *
- */
-
- #define abs(x) ((x) < 0 ? -(x) : (x))
-
- /* f' = best_frequency(f, table, def):
- * return nearest frequency in sorted table,
- * unless f == 0 -> return def
- */
- LOCAL int best_frequency(f, table, def)
- int f;
- int table[];
- int def;
- {
- int best = table[0];
- int i;
-
- if (f == 0)
- return def;
- for (i = 0; i < table[i]; i++)
- if (abs(table[i] - f) < abs(best - f))
- best = table[i];
- return best;
- }
-
-
-
- LOCAL short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
- 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
-
- LOCAL int search(val, table, size)
- int val;
- short *table;
- int size;
- {
- int i;
-
- for (i = 0; i < size; i++)
- {
- if (val <= *table++)
- return i;
- }
- return size;
- }
-
- #define BIAS (0x84) /* Bias for linear code. */
-
- /*
- * linear2ulaw() - Convert a linear PCM value to u-law
- *
- * In order to simplify the encoding process, the original linear magnitude
- * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
- * (33 - 8191). The result can be seen in the following encoding table:
- *
- * Biased Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 00000001wxyza 000wxyz
- * 0000001wxyzab 001wxyz
- * 000001wxyzabc 010wxyz
- * 00001wxyzabcd 011wxyz
- * 0001wxyzabcde 100wxyz
- * 001wxyzabcdef 101wxyz
- * 01wxyzabcdefg 110wxyz
- * 1wxyzabcdefgh 111wxyz
- *
- * Each biased linear code has a leading 1 which identifies the segment
- * number. The value of the segment number is equal to 7 minus the number
- * of leading 0's. The quantization interval is directly available as the
- * four bits wxyz. * The trailing bits (a - h) are ignored.
- *
- * Ordinarily the complement of the resulting code word is used for
- * transmission, and so the code word is complemented before it is returned.
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
- LOCAL unsigned char linear2ulaw(pcm_val)
- int pcm_val; /* 2's complement (16-bit range) */
- {
- int mask;
- int seg;
- unsigned char uval;
-
-
- /* Get the sign and the magnitude of the value. */
- if (pcm_val < 0)
- {
- pcm_val = BIAS - pcm_val;
- mask = 0x7F;
- }
- else
- {
- pcm_val += BIAS;
- mask = 0xFF;
- }
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_end, 8);
-
- /*
- * Combine the sign, segment, quantization bits;
- * and complement the code word.
- */
- if (seg >= 8) /* out of range, return maximum value. */
- return 0x7F ^ mask;
- else {
- uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
- return uval ^ mask;
- }
-
- }
-
- LOCAL unsigned int cvt(ch)
- int ch;
- {
- return linear2ulaw(ch * 2);
- }
-
- #ifdef DEFAULT_SET_MIX
- LOCAL int stereo;
-
- #ifdef NEW_OUTPUT_SAMPLES_AWARE
-
- LOCAL int pps[32], pms[32];
-
- void set_mix(percent)
- int percent;
- {
- int i;
-
- for (i = 8; i < 32; i++)
- {
- pps[i] = 1 << (31 - i);
- if (i < 29)
- pms[i] = pps[i] - (percent << (29 - i) )/25;
- else
- pms[i] = pps[i] - (percent >> (i - 29) )/25;
- }
- }
-
- #else /* NEW_OUTPUT_SAMPLES_AWARE */
- /* old code: optimized away */
- /* LOCAL int primary, secondary; */
- LOCAL int pps, pms; /* 1/2 primary+secondary, 1/2 primary-secondary */
-
- void set_mix(percent)
- int percent;
- {
- percent *= 256;
- percent /= 100;
- /*
- secondary = percent;
- primary = 512 - percent;
- */
- pps = 256;
- pms = 256 - percent;
- }
- #endif /* NEW_OUTPUT_SAMPLES_AWARE */
-
- #endif /* DEFAULT_SET_MIX */
-
- #ifdef UNSIGNED_BUFFERS
- #define UNSIGNED8
- #define UNSIGNED16
- #endif
-
- #ifdef DEFAULT_BUFFERS
-
- #ifdef UNSIGNED16
- LOCAL unsigned short *buffer16;
- #define VALUE16(x) ((x)+32768)
- #else
- LOCAL short *buffer16;
- #define VALUE16(x) (x)
- #endif
-
- #ifdef UNSIGNED8
- LOCAL unsigned char *buffer;
- #define VALUE8(x) ((x)+128)
- #else
- LOCAL char *buffer;
- #define VALUE8(x) (x)
- #endif
- LOCAL int idx;
- LOCAL int dsize; /* current data size */
- LOCAL int samples_max; /* number of samples in buffer */
-
- LOCAL int tsync = FALSE;
- #endif /* DEFAULT_BUFFERS */
-
- #ifdef SEPARATE_BUFFERS
- LOCAL char *buffer, *buffer_l, *buffer_r;
- LOCAL int idx;
- #endif
-
-
-
- #ifdef NEW_OUTPUT_SAMPLES_AWARE
-
- LOCAL void add_samples16_stereo(left, right, n)
- int left, right, n;
- {
- if (pms[n] == pps[n]) /* no mixing */
- {
- if (n<16)
- {
- buffer16[idx++] = VALUE16(left << (16-n) );
- buffer16[idx++] = VALUE16(right << (16-n) );
- }
- else
- {
- buffer16[idx++] = VALUE16(left >> (n-16) );
- buffer16[idx++] = VALUE16(right >> (n-16) );
- }
- }
- else
- {
- int s1, s2;
-
- s1 = (left+right)*pps[n];
- s2 = (left-right)*pms[n];
-
- buffer16[idx++] = VALUE16( (s1 + s2) >> 16);
- buffer16[idx++] = VALUE16( (s1 - s2) >> 16);
- }
- }
-
- LOCAL void add_samples16_mono(left, right, n)
- int left, right, n;
- {
- if (n<15) /* is this possible? */
- buffer16[idx++] = VALUE16( (left + right) << (15-n) );
- else
- buffer16[idx++] = VALUE16( (left + right) >> (n-15) );
- }
-
- LOCAL void add_samples16(left, right, n)
- int left, right, n;
- {
- if (stereo)
- add_samples16_stereo(left, right, n);
- else
- add_samples16_mono(left, right, n);
- }
-
- LOCAL void add_samples8_stereo(left, right, n)
- int left, right, n;
- {
- if (pms[n] == pps[n]) /* no mixing */
- {
- /* if n<8 -> same problem as above,
- but that won't happen, right? */
- buffer[idx++] = VALUE8(left >> (n-8) );
- buffer[idx++] = VALUE8(right >> (n-8) );
- }
- else
- {
- int s1, s2;
-
- s1 = (left+right)*pps[n];
- s2 = (left-right)*pms[n];
-
- buffer[idx++] = VALUE8( (s1 + s2) >> 24);
- buffer[idx++] = VALUE8( (s1 - s2) >> 24);
- }
- }
-
- LOCAL void add_samples8_mono(left, right, n)
- int left, right, n;
- {
- buffer[idx++] = VALUE8( (left+right) >> (n-7) );
- }
-
- LOCAL void add_samples8(left, right, n)
- int left, right, n;
- {
- if (stereo)
- add_samples8_stereo(left, right, n);
- else
- add_samples8_mono(left, right, n);
- }
-
- #else
-
- /* don't ask me if this code is correct then (I guess it is) ...
- anyone still using it? */
- LOCAL void add_samples16_stereo(left, right)
- int left, right;
- {
- if (pms == pps) /* no mixing */
- {
- buffer16[idx++] = VALUE16(left/256);
- buffer16[idx++] = VALUE16(right/256);
- }
- else
- {
- int s1, s2;
-
- s1 = (left+right)*pps;
- s2 = (left-right)*pms;
-
- buffer16[idx++] = VALUE16( (s1 + s2)/65536 );
- buffer16[idx++] = VALUE16( (s1 - s2)/65536 );
- }
- }
-
- LOCAL void add_samples16_mono(left, right)
- int left, right;
- {
- buffer16[idx++] = VALUE16( (left + right)/256);
- }
-
- LOCAL void add_samples16(left, right)
- int left, right;
- {
- if (stereo)
- add_samples16_stereo(left, right);
- else
- add_samples16_mono(left, right);
- }
-
- LOCAL void add_samples8_stereo(left, right)
- int left, right;
- {
- if (pms == pps) /* no mixing */
- {
- buffer[idx++] = VALUE8(left/65536);
- buffer[idx++] = VALUE8(right/65536);
- }
- else
- {
- int s1, s2;
-
- s1 = (left+right)*pps;
- s2 = (left-right)*pms;
-
- buffer[idx++] = VALUE8( (s1 + s2) >> 24);
- buffer[idx++] = VALUE8( (s1 + s2) >> 24);
- }
- }
-
- LOCAL void add_samples8_mono(left, right)
- int left, right;
- {
- buffer[idx++] = VALUE8( (left+right) >> 16);
- }
-
- LOCAL void add_samples8(left, right)
- int left, right;
- {
- if (stereo)
- add_samples8_stereo(left, right);
- else
- add_samples8_mono(left, right);
- }
-
- #endif
-
- #ifndef NEW_OUTPUT_SAMPLES_AWARE
-
- XT void output_samples P((int left, int right, int n));
-
- void output_samples(left, right, n)
- int left, right, n;
- {
- old_output_samples(left >> (n-23), right >> (n-23));
- }
- #define output_samples old_output_samples
-
- #endif
-
- #ifndef NEW_FUNCS
- void sync_audio(function, parameter)
- void (*function) P((void *));
- GENERIC parameter;
- {
- (*function)(parameter);
- }
-
- void audio_ui(c)
- int c;
- {
- }
-
- #endif
-