ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PDL-Audio/xlib.c
Revision: 1.1
Committed: Tue Dec 28 01:05:16 2004 UTC (19 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_1, rel-1_2, HEAD
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "xlib.h"
2    
3     /*
4     * the following functions were originally taken from sox-12.16/libst.c
5     * license is unclear, but the header file contained this notice:
6     */
7    
8     /*
9     ** Copyright (C) 1989 by Jef Poskanzer.
10     **
11     ** Permission to use, copy, modify, and distribute this software and its
12     ** documentation for any purpose and without fee is hereby granted, provided
13     ** that the above copyright notice appear in all copies and that both that
14     ** copyright notice and this permission notice appear in supporting
15     ** documentation. This software is provided "as is" without express or
16     ** implied warranty.
17     */
18    
19     /*
20     ** This routine converts from linear to ulaw.
21     **
22     ** Craig Reese: IDA/Supercomputing Research Center
23     ** Joe Campbell: Department of Defense
24     ** 29 September 1989
25     **
26     ** References:
27     ** 1) CCITT Recommendation G.711 (very difficult to follow)
28     ** 2) "A New Digital Technique for Implementation of Any
29     ** Continuous PCM Companding Law," Villeret, Michel,
30     ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
31     ** 1973, pg. 11.12-11.17
32     ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
33     ** for Analog-to_Digital Conversion Techniques,"
34     ** 17 February 1987
35     **
36     ** Input: Signed 16 bit linear sample
37     ** Output: 8 bit ulaw sample
38     */
39    
40     #undef ZEROTRAP /* turn off the trap as per the MIL-STD */
41     #define uBIAS 0x84 /* define the add-in bias for 16 bit samples */
42     #define uCLIP 32635
43     #define ACLIP 31744
44    
45     unsigned char
46     st_linear_to_ulaw(int sample)
47     {
48     static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
49     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
50     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
51     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
52     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
53     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
54     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
55     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
56     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
57     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
58     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
61     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
62     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
63     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
64     int sign, exponent, mantissa;
65     unsigned char ulawbyte;
66    
67     /* Get the sample into sign-magnitude. */
68     sign = (sample >> 8) & 0x80; /* set aside the sign */
69     if ( sign != 0 ) sample = -sample; /* get magnitude */
70     if ( sample > uCLIP ) sample = uCLIP; /* clip the magnitude */
71    
72     /* Convert from 16 bit linear to ulaw. */
73     sample = sample + uBIAS;
74     exponent = exp_lut[( sample >> 7 ) & 0xFF];
75     mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
76     ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
77     #ifdef ZEROTRAP
78     if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
79     #endif
80    
81     return ulawbyte;
82     }
83    
84     /*
85     ** This routine converts from ulaw to 16 bit linear.
86     **
87     ** Craig Reese: IDA/Supercomputing Research Center
88     ** 29 September 1989
89     **
90     ** References:
91     ** 1) CCITT Recommendation G.711 (very difficult to follow)
92     ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
93     ** for Analog-to_Digital Conversion Techniques,"
94     ** 17 February 1987
95     **
96     ** Input: 8 bit ulaw sample
97     ** Output: signed 16 bit linear sample
98     */
99    
100     int
101     st_ulaw_to_linear(unsigned char ulawbyte)
102     {
103     static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
104     int sign, exponent, mantissa, sample;
105    
106     ulawbyte = ~ ulawbyte;
107     sign = ( ulawbyte & 0x80 );
108     exponent = ( ulawbyte >> 4 ) & 0x07;
109     mantissa = ulawbyte & 0x0F;
110     sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
111     if ( sign != 0 ) sample = -sample;
112    
113     return sample;
114     }
115    
116     /*
117     * A-law routines by Graeme W. Gill.
118     * Date: 93/5/7
119     *
120     * References:
121     * 1) CCITT Recommendation G.711
122     *
123     * These routines were used to create the fast
124     * lookup tables.
125     */
126    
127     #define ACLIP 31744
128    
129     unsigned char
130     st_linear_to_Alaw(int sample)
131     {
132     static int exp_lut[128] = {1,1,2,2,3,3,3,3,
133     4,4,4,4,4,4,4,4,
134     5,5,5,5,5,5,5,5,
135     5,5,5,5,5,5,5,5,
136     6,6,6,6,6,6,6,6,
137     6,6,6,6,6,6,6,6,
138     6,6,6,6,6,6,6,6,
139     6,6,6,6,6,6,6,6,
140     7,7,7,7,7,7,7,7,
141     7,7,7,7,7,7,7,7,
142     7,7,7,7,7,7,7,7,
143     7,7,7,7,7,7,7,7,
144     7,7,7,7,7,7,7,7,
145     7,7,7,7,7,7,7,7,
146     7,7,7,7,7,7,7,7,
147     7,7,7,7,7,7,7,7};
148    
149     int sign, exponent, mantissa;
150     unsigned char Alawbyte;
151    
152     /* Get the sample into sign-magnitude. */
153     sign = ((~sample) >> 8) & 0x80; /* set aside the sign */
154     if ( sign == 0 ) sample = -sample; /* get magnitude */
155     if ( sample > ACLIP ) sample = ACLIP; /* clip the magnitude */
156    
157     /* Convert from 16 bit linear to ulaw. */
158     if (sample >= 256)
159     {
160     exponent = exp_lut[( sample >> 8 ) & 0x7F];
161     mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
162     Alawbyte = (( exponent << 4 ) | mantissa);
163     }
164     else
165     Alawbyte = (sample >> 4);
166     Alawbyte ^= (sign ^ 0x55);
167    
168     return Alawbyte;
169     }
170    
171     int
172     st_Alaw_to_linear(unsigned char Alawbyte)
173     {
174     static int exp_lut[8] = { 0, 264, 528, 1056, 2112, 4224, 8448, 16896 };
175     int sign, exponent, mantissa, sample;
176    
177     Alawbyte ^= 0x55;
178     sign = ( Alawbyte & 0x80 );
179     Alawbyte &= 0x7f; /* get magnitude */
180     if (Alawbyte >= 16)
181     {
182     exponent = (Alawbyte >> 4 ) & 0x07;
183     mantissa = Alawbyte & 0x0F;
184     sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
185     }
186     else
187     sample = (Alawbyte << 4) + 8;
188     if ( sign == 0 ) sample = -sample;
189    
190     return sample;
191     }
192    
193     /* adapted from clm.c, by Bill Schottstaedt C<bil@ccrma.stanford.edu> */
194    
195     #define SRC_SINC_DENSITY 1000
196     #define SRC_SINC_WIDTH 10
197    
198     static Float **sinc_tables = 0;
199     static int *sinc_widths = 0;
200     static int sincs = 0;
201    
202     static Float *
203     init_sinc_table (int width)
204     {
205     int i, size, loc;
206     Float sinc_freq, win_freq, sinc_phase, win_phase;
207     for (i = 0; i < sincs; i++)
208     if (sinc_widths[i] == width)
209     return (sinc_tables[i]);
210    
211     if (sincs == 0)
212     {
213     sinc_tables = (Float **) calloc (8, sizeof (Float *));
214     sinc_widths = (int *) calloc (8, sizeof (int));
215     sincs = 8;
216     loc = 0;
217     }
218     else
219     {
220     loc = -1;
221     for (i = 0; i < sincs; i++)
222     if (sinc_widths[i] == 0)
223     {
224     loc = i;
225     break;
226     }
227    
228     if (loc == -1)
229     {
230     sinc_tables = (Float **) realloc (sinc_tables, (sincs + 8) * sizeof (Float *));
231     sinc_widths = (int *) realloc (sinc_widths, (sincs + 8) * sizeof (int));
232     for (i = sincs; i < (sincs + 8); i++)
233     {
234     sinc_widths[i] = 0;
235     sinc_tables[i] = NULL;
236     }
237    
238     loc = sincs;
239     sincs += 8;
240     }
241     }
242     sinc_tables[loc] = (Float *) calloc (width * SRC_SINC_DENSITY + 1, sizeof (Float));
243     sinc_widths[loc] = width;
244     size = width * SRC_SINC_DENSITY;
245     sinc_freq = M_PI / (Float) SRC_SINC_DENSITY;
246     win_freq = M_PI / (Float) size;
247     sinc_tables[loc][0] = 1.0;
248    
249     for (i = 1, sinc_phase = sinc_freq, win_phase = win_freq; i < size; i++, sinc_phase += sinc_freq, win_phase += win_freq)
250     sinc_tables[loc][i] = sin (sinc_phase) * (0.5 + 0.5 * cos (win_phase)) / sinc_phase;
251    
252     return (sinc_tables[loc]);
253     }
254    
255     void
256     mus_src (Float *input, int inpsize, Float *output, int outsize, Float srate, Float *sr_mod, int width)
257     {
258     int i, lim, len, fsx, k, loc;
259    
260     Float x, xx, factor, *data, *sinc_table, sum, zf, srx, incr;
261    
262     Float *in0 = input;
263     Float *in1 = input + inpsize;
264     Float *out1 = output + outsize;
265    
266     if (width == 0)
267     width = SRC_SINC_WIDTH;
268    
269     x = 0.0;
270     lim = 2 * width;
271     len = width * SRC_SINC_DENSITY;
272     data = (Float *) calloc (lim + 1, sizeof (Float));
273     sinc_table = init_sinc_table (width);
274    
275     for (i = width; i < lim; i++) data[i] = *input++;
276    
277     while (output < out1)
278     {
279     fsx = (int)x;
280     if (fsx > 0)
281     {
282     /* realign data, reset x */
283     for (i = fsx, loc = 0; i < lim; i++, loc++)
284     data[loc] = data[i];
285    
286     for (i = loc; i < lim; i++)
287     {
288     if (srx < 0)
289     input = (input > in0 ? input : in1) - 1;
290     else
291     input = input < in1 ? input+1 : in0;
292    
293     data[i] = *input;
294     }
295    
296     x -= fsx;
297     }
298    
299     srx = srate + (sr_mod ? *sr_mod++ : 0);
300     srx = srx ? fabs (srx) : 0.001;
301     factor = srx > 1 ? 1 / srx : 1;
302    
303     sum = 0.0;
304     zf = factor * SRC_SINC_DENSITY;
305     xx = zf * (1.0 - x - width);
306     for (i = 0; i < lim; i++)
307     {
308     /* we're moving backwards in the data array, so xx has to mimic that (hence the '1.0 - x') */
309     k = abs ((int)xx);
310    
311     if (k < len)
312     sum += data[i] * sinc_table[k];
313    
314     xx += zf;
315     }
316    
317     x += srx;
318     *output++ = sum * factor;
319     }
320    
321     free (data);
322     }
323    
324     static unsigned long randx = 1;
325    
326     static int
327     irandom (int amp)
328     {
329     int val;
330    
331     randx = randx * 1103515245 + 12345;
332     val = (unsigned int) (randx >> 16) & 0x7fff;
333     return ((int) (amp * (((Float) val / 32768))));
334     }
335    
336     #define max(a,b) ((a)>(b) ? (a) : (b))
337     #define min(a,b) ((a)<(b) ? (a) : (b))
338    
339     void
340     mus_granulate (Float *input, int insize,
341     Float *output, int outsize,
342     Float expansion, Float flength, Float scaler,
343     Float hop, Float ramp, Float jitter, int max_size)
344     /* hop, jitter, length (*= smapling_rate) */
345     {
346     int length = (int)ceil (flength);
347     int rmp = (int) (ramp * length);
348     int output_hop = (int)hop;
349     int input_hop = (int)(output_hop / expansion);
350     int s20 = (int) (jitter / 20);
351     int s50 = (int) (jitter / 50);
352     int outlen = max_size > 0 ? min ((int)(hop + flength), max_size) : (int)(hop + flength);
353     int in_data_len = outlen + s20 + 1;
354     int in_data_start = in_data_len;
355     Float *data = (Float *) calloc (outlen, sizeof (Float));
356     Float *in_data = (Float *) calloc (in_data_len, sizeof (Float));
357    
358     Float *in1 = input + insize;
359     Float *out1 = output + outsize;
360    
361     int ctr = 0;
362     Float cur_out = 0;
363    
364     int start, len, end, i, j, k;
365     int steady_end, curstart;
366     Float incr, result, amp;
367    
368     if (s50 > output_hop)
369     s50 = output_hop;
370    
371     for(;;)
372     {
373     while (ctr < cur_out)
374     {
375     *output++ = data[ctr++];
376     if (output >= out1)
377     goto ok;
378     }
379    
380     start = cur_out;
381     end = length - start;
382    
383     if (end <= 0)
384     end = 0;
385     else
386     for (i = 0, j = start; i < end; i++, j++)
387     data[i] = data[j];
388    
389     for (i = end; i < outlen; i++)
390     data[i] = 0;
391    
392     start = in_data_start;
393     len = in_data_len;
394    
395     if (start > len)
396     {
397     input += start - len;
398     input = input < in1 ? input : in1;
399     start = len;
400     }
401     else if (start < len)
402     for (i = 0, k = start; k < len; i++, k++)
403     in_data[i] = in_data[k];
404    
405     for (i = len - start; i < len; i++)
406     {
407     in_data[i] = *input;
408     input = input < in1 ? input+1 : input;
409     }
410    
411     in_data_start = input_hop;
412    
413     amp = 0.0;
414     incr = scaler / (Float) rmp;
415     steady_end = length - rmp;
416     curstart = irandom (s20);
417    
418     for (i = 0, j = curstart; i < length; i++, j++)
419     {
420     data[i] += (amp * in_data[j]);
421    
422     if (i < rmp)
423     amp += incr;
424     else if (i > steady_end)
425     amp -= incr;
426     }
427    
428     ctr -= cur_out;
429     cur_out = output_hop + irandom (s50) - (s50 >> 1);
430     }
431    
432     ok:
433     free (data);
434     free (in_data);
435     }
436    
437     static void
438     mus_shuffle (Float* rl, Float* im, int n)
439     {
440     /* bit reversal */
441    
442     int i,m,j;
443     Float tempr,tempi;
444     j=0;
445     for (i=0;i<n;i++)
446     {
447     if (j>i)
448     {
449     tempr = rl[j];
450     tempi = im[j];
451     rl[j] = rl[i];
452     im[j] = im[i];
453     rl[i] = tempr;
454     im[i] = tempi;
455     }
456     m = n>>1;
457     while ((m>=2) && (j>=m))
458     {
459     j -= m;
460     m = m>>1;
461     }
462     j += m;
463     }
464     }
465    
466     static void
467     mus_fft (Float *rl, Float *im, int n, int isign)
468     {
469     /* standard fft: real part in rl, imaginary in im, */
470     /* rl and im are zero-based. */
471     int mmax,j,pow,prev,lg,i,ii,jj,ipow;
472     Float wrs,wis,tempr,tempi;
473     double wr,wi,theta,wtemp,wpr,wpi;
474     ipow = (int)(ceil(log(n)/log(2.0)));
475     mus_shuffle(rl,im,n);
476     mmax = 2;
477     prev = 1;
478     pow = (int)(n*0.5);
479     theta = (M_PI*isign);
480     for (lg=0;lg<ipow;lg++)
481     {
482     wpr = cos(theta);
483     wpi = sin(theta);
484     wr = 1.0;
485     wi = 0.0;
486     for (ii=0;ii<prev;ii++)
487     {
488     wrs = (Float) wr;
489     wis = (Float) wi;
490     #ifdef LINUX
491     if (isnan(wis)) wis=0.0;
492     #endif
493     i = ii;
494     j = ii + prev;
495     for (jj=0;jj<pow;jj++)
496     {
497     tempr = wrs*rl[j] - wis*im[j];
498     tempi = wrs*im[j] + wis*rl[j];
499     rl[j] = rl[i] - tempr;
500     im[j] = im[i] - tempi;
501     rl[i] += tempr;
502     im[i] += tempi;
503     i += mmax;
504     j += mmax;
505     }
506     wtemp = wr;
507     wr = (wr*wpr) - (wi*wpi);
508     wi = (wi*wpr) + (wtemp*wpi);
509     }
510     pow = (int)(pow*0.5);
511     prev = mmax;
512     theta = theta*0.5;
513     mmax = mmax*2;
514     }
515     }
516    
517     static void
518     mus_convolution (Float* rl1, Float* rl2, int n)
519     {
520     /* convolves two real arrays. */
521     /* rl1 and rl2 are assumed to be set up correctly for the convolution */
522     /* (that is, rl1 (the "signal") is zero-padded by length of */
523     /* (non-zero part of) rl2 and rl2 is stored in wrap-around order) */
524     /* We treat rl2 as the imaginary part of the first fft, then do */
525     /* the split, scaling, and (complex) spectral multiply in one step. */
526     /* result in rl1 */
527    
528     int j,n2,nn2;
529     Float rem,rep,aim,aip,invn;
530    
531     mus_fft(rl1,rl2,n,1);
532    
533     n2=(int)(n*0.5);
534     invn = 0.25/n;
535     rl1[0] = ((rl1[0]*rl2[0])/n);
536     rl2[0] = 0.0;
537    
538     for (j=1;j<=n2;j++)
539     {
540     nn2 = n-j;
541     rep = (rl1[j]+rl1[nn2]);
542     rem = (rl1[j]-rl1[nn2]);
543     aip = (rl2[j]+rl2[nn2]);
544     aim = (rl2[j]-rl2[nn2]);
545    
546     rl1[j] = invn*(rep*aip + aim*rem);
547     rl1[nn2] = rl1[j];
548     rl2[j] = invn*(aim*aip - rep*rem);
549     rl2[nn2] = -rl2[j];
550     }
551    
552     mus_fft(rl1,rl2,n,-1);
553     }
554    
555     void
556     mus_convolve (Float * input, Float * output, int size, Float * filter, int fftsize, int filtersize)
557     {
558     int fftsize2 = fftsize >> 1;
559     Float *rl1, *rl2, *buf;
560     Float *in1 = input + size;
561     int ctr = fftsize2;
562     int i, j;
563    
564     rl1 = (Float *) calloc (fftsize, sizeof (Float));
565     rl2 = (Float *) calloc (fftsize, sizeof (Float));
566     buf = (Float *) calloc (fftsize, sizeof (Float));
567    
568     while (size > 0)
569     {
570     ctr++;
571     if (ctr >= fftsize2)
572     {
573     for (i = 0, j = fftsize2; i < fftsize2; i++, j++)
574     {
575     buf[i] = buf[j];
576     buf[j] = 0.0;
577     rl1[i] = *input;
578     rl1[j] = 0.0;
579     rl2[i] = 0.0;
580     rl2[j] = 0.0;
581    
582     input = input < in1 ? input+1 : input;
583     }
584    
585     for (i = 0; i < filtersize; i++)
586     rl2[i] = filter[i];
587    
588     mus_convolution (rl1, rl2, fftsize);
589    
590     for (i = 0, j = fftsize2; i < fftsize2; i++, j++)
591     {
592     buf[i] += rl1[i];
593     buf[j] = rl1[j];
594     }
595    
596     ctr = 0;
597     }
598    
599     *output++ = buf[ctr];
600     size--;
601     }
602     }