jef@well.UUCP (Jef Poskanzer) (11/21/89)
Here's a simple sound toolbox for the SPARCstation-1 built-in speaker. --- Jef Jef Poskanzer jef@well.sf.ca.us {ucbvax, apple, hplabs}!well!jef "Grow your own, for Victory!" #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # Makefile # libst.h # libst.c # libsst.h # libsst.c # libfft.h # libfft.c # echoplex.c # echoplex.1 # lintoulaw.c # lintoulaw.1 # mix.c # mix.1 # pitch.c # pitch.1 # This archive created: Mon Nov 20 22:01:20 1989 # By: Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal) export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(2001 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \SHAR_EOF > 'README' X SPARCstation Sound Tools X Beta Distribution of 20nov89 X Previous distribution NONE X X XThis package contains some simple sound tools for the SPARCstation-1. XThe SPARCstation can record and playback telephone-quality sound using Xthe Am79C30A audio chip from AMD. Telephone-quality means 8192 samples Xper second and eight bits per sample, so don't expect Hi-Fi. The chip Xhas a few interesting abilities other than record and playback, such as Xtone generation. For full details call AMD's "literature center" at X(408)749-2264 and ask for the spec, publication #09893. X XIn addition to the tools that directly manipulate the sound chip, this Xpackage includes some simple filters for manipulating sound files. X XFeedback is welcome; send bug reports, enhancements, checks, money Xorders, etc. to the addresses below. Be sure to mention what version Xyou have when sending bug reports! X X Jef Poskanzer X jef@well.sf.ca.us X {ucbvax, lll-crg, sun!pacbell, apple, hplabs}!well!jef X X XFiles in sst.shar: X X README this X Makefile guess X X libst.h header file for portable sound tool library X libst.c portable sound tool library X libsst.h header file for SPARC sound tool library X libsst.c SPARC sound tool library X libfft.h header file for FFT library X libfft.c FFT library X X echoplex.c echo generator X lintoulaw.c convert linear to ulaw X mix.c mix multiple sound files X pitch.c change the pitch of a sound file X speed.c change the speed of a sound file X ulawtolin.c convert ulaw to linear X volume.c change the volume of a sound file X vox.c simple silence-deletion filter X dial.c generate DTMF dialing codes on the speaker X listen.c hardware loopback, connect microphone to speaker X play.c play a sound file on the speaker X record.c record from the microphone input X tones.c play sine-wave tones on the speaker X X *.1 manual entries for all the above tools SHAR_EOF if test 2001 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 2001 characters)' fi fi # end of overwriting check echo shar: extracting "'Makefile'" '(1602 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^X//' << \SHAR_EOF > 'Makefile' XCFLAGS = -O XLDLAGS = -s X XPOBJS = echoplex lintoulaw mix speed ulawtolin volume vox XFOBJS = pitch XSOBJS = dial listen play record tones X XOBJS = $(POBJS) $(FOBJS) $(SOBJS) X Xall: $(OBJS) X X$(POBJS): libst.h libst.o X $(CC) $(CFLAGS) $(LDFLAGS) $@.c libst.o -o $@ X X$(FOBJS): libst.h libst.o libfft.h libfft.o X $(CC) $(CFLAGS) $(LDFLAGS) $@.c libst.o libfft.o -lm -o $@ X X$(SOBJS): libst.h libst.o libsst.h libsst.o X $(CC) $(CFLAGS) $(LDFLAGS) $@.c libst.o libsst.o -o $@ X Xechoplex: echoplex.c Xlintoulaw: lintoulaw.c Xmix: mix.c Xspeed: speed.c Xulawtolin: ulawtolin.c Xvolume: volume.c Xvox: vox.c Xpitch: pitch.c Xdial: dial.c Xlisten: listen.c Xplay: play.c Xrecord: record.c Xtones: tones.c X X Xlibst.o: libst.c libst.h X $(CC) $(CFLAGS) -c libst.c X Xlibfft.o: libfft.c libfft.h X $(CC) $(CFLAGS) -c libfft.c X Xlibsst.o: libsst.c libsst.h X $(CC) $(CFLAGS) -c libsst.c X X Xclean: X rm -f $(OBJS) *.o X Xshar: sst.shar Xsst.shar: sst.shar1 sst.shar2 Xsst.shar1: README Makefile libst.h libst.c libsst.h libsst.c libfft.h \ X libfft.c echoplex.c echoplex.1 lintoulaw.c lintoulaw.1 mix.c \ X mix.1 pitch.c pitch.1 X shar -v -c -p X README Makefile libst.h libst.c libsst.h libsst.c libfft.h libfft.c echoplex.c echoplex.1 lintoulaw.c lintoulaw.1 mix.c mix.1 pitch.c pitch.1 > $@ Xsst.shar2: speed.c speed.1 ulawtolin.c ulawtolin.1 volume.c volume.1 \ X vox.c vox.1 dial.c dial.1 listen.c listen.1 play.c play.1 \ X record.c record.1 tones.c tones.1 X shar -v -c -p X speed.c speed.1 ulawtolin.c ulawtolin.1 volume.c volume.1 vox.c vox.1 dial.c dial.1 listen.c listen.1 play.c play.1 record.c record.1 tones.c tones.1 > $@ SHAR_EOF if test 1602 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 1602 characters)' fi fi # end of overwriting check echo shar: extracting "'libst.h'" '(3224 characters)' if test -f 'libst.h' then echo shar: will not over-write existing file "'libst.h'" else sed 's/^X//' << \SHAR_EOF > 'libst.h' X/* libst.h - include file for portable sound tools library X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#define SAMPLES_PER_SECOND 8192 X X#define MINLIN -32768 X#define MAXLIN 32767 X#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; else if ( x > MAXLIN ) x = MAXLIN; } while ( 0 ) X Xunsigned char st_linear_to_ulaw( /* int sample */ ); Xint st_ulaw_to_linear_slow( /* unsigned char ulawbyte */ ); X X/* X** This macro converts from ulaw to 16 bit linear, faster. X** X** Jef Poskanzer X** 23 October 1989 X** X** Input: 8 bit ulaw sample X** Output: signed 16 bit linear sample X*/ X#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte] X Xstatic int ulaw_table[256] = { X -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, X -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, X -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, X -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, X -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, X -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, X -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, X -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, X -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, X -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, X -876, -844, -812, -780, -748, -716, -684, -652, X -620, -588, -556, -524, -492, -460, -428, -396, X -372, -356, -340, -324, -308, -292, -276, -260, X -244, -228, -212, -196, -180, -164, -148, -132, X -120, -112, -104, -96, -88, -80, -72, -64, X -56, -48, -40, -32, -24, -16, -8, 0, X 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, X 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, X 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, X 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, X 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, X 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, X 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, X 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, X 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, X 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, X 876, 844, 812, 780, 748, 716, 684, 652, X 620, 588, 556, 524, 492, 460, 428, 396, X 372, 356, 340, 324, 308, 292, 276, 260, X 244, 228, 212, 196, 180, 164, 148, 132, X 120, 112, 104, 96, 88, 80, 72, 64, X 56, 48, 40, 32, 24, 16, 8, 0 }; SHAR_EOF if test 3224 -ne "`wc -c < 'libst.h'`" then echo shar: error transmitting "'libst.h'" '(should have been 3224 characters)' fi fi # end of overwriting check echo shar: extracting "'libst.c'" '(3471 characters)' if test -f 'libst.c' then echo shar: will not over-write existing file "'libst.c'" else sed 's/^X//' << \SHAR_EOF > 'libst.c' X/* libst.c - portable sound tools library X*/ X X/* X** This routine converts from linear to ulaw. X** X** Craig Reese: IDA/Supercomputing Research Center X** Joe Campbell: Department of Defense X** 29 September 1989 X** X** References: X** 1) CCITT Recommendation G.711 (very difficult to follow) X** 2) "A New Digital Technique for Implementation of Any X** Continuous PCM Companding Law," Villeret, Michel, X** et al. 1973 IEEE Int. Conf. on Communications, Vol 1, X** 1973, pg. 11.12-11.17 X** 3) MIL-STD-188-113,"Interoperability and Performance Standards X** for Analog-to_Digital Conversion Techniques," X** 17 February 1987 X** X** Input: Signed 16 bit linear sample X** Output: 8 bit ulaw sample X*/ X X#define ZEROTRAP /* turn on the trap as per the MIL-STD */ X#define BIAS 0x84 /* define the add-in bias for 16 bit samples */ X#define CLIP 32635 X Xunsigned char Xst_linear_to_ulaw( sample ) Xint sample; X { X static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, X 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, X 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, X 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7}; X int sign, exponent, mantissa; X unsigned char ulawbyte; X X /* Get the sample into sign-magnitude. */ X sign = (sample >> 8) & 0x80; /* set aside the sign */ X if ( sign != 0 ) sample = -sample; /* get magnitude */ X if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */ X X /* Convert from 16 bit linear to ulaw. */ X sample = sample + BIAS; X exponent = exp_lut[( sample >> 7 ) & 0xFF]; X mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F; X ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa ); X#ifdef ZEROTRAP X if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */ X#endif X X return ulawbyte; X } X X/* X** This routine converts from ulaw to 16 bit linear. X** X** Craig Reese: IDA/Supercomputing Research Center X** 29 September 1989 X** X** References: X** 1) CCITT Recommendation G.711 (very difficult to follow) X** 2) MIL-STD-188-113,"Interoperability and Performance Standards X** for Analog-to_Digital Conversion Techniques," X** 17 February 1987 X** X** Input: 8 bit ulaw sample X** Output: signed 16 bit linear sample X*/ X Xint Xst_ulaw_to_linear_slow( ulawbyte ) Xunsigned char ulawbyte; X { X static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; X int sign, exponent, mantissa, sample; X X ulawbyte = ~ ulawbyte; X sign = ( ulawbyte & 0x80 ); X exponent = ( ulawbyte >> 4 ) & 0x07; X mantissa = ulawbyte & 0x0F; X sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) ); X if ( sign != 0 ) sample = -sample; X X return sample; X } SHAR_EOF if test 3471 -ne "`wc -c < 'libst.c'`" then echo shar: error transmitting "'libst.c'" '(should have been 3471 characters)' fi fi # end of overwriting check echo shar: extracting "'libsst.h'" '(904 characters)' if test -f 'libsst.h' then echo shar: will not over-write existing file "'libsst.h'" else sed 's/^X//' << \SHAR_EOF > 'libsst.h' X/* libsst.h - include file for SPARC sound tools library X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <sys/ioctl.h> X#include <sbusdev/audioreg.h> X#include <sun/audioio.h> X X#define SAMPLES_PER_SECOND 8192 X Xint sst_open( ); Xvoid sst_close( /* int fd */ ); X Xvoid sst_set_ger( /* int fd, value */ ); Xvoid sst_set_gr( /* int fd, value */ ); Xvoid sst_set_gx( /* int fd, value */ ); X Xvoid sst_tones( /* int fd, dhz1, dhz2, thz, rhz, usec */ ); Xvoid sst_dtmf( /* int fd, char *dial, int usecper, usecpause */ ); SHAR_EOF if test 904 -ne "`wc -c < 'libsst.h'`" then echo shar: error transmitting "'libsst.h'" '(should have been 904 characters)' fi fi # end of overwriting check echo shar: extracting "'libsst.c'" '(10463 characters)' if test -f 'libsst.c' then echo shar: will not over-write existing file "'libsst.c'" else sed 's/^X//' << \SHAR_EOF > 'libsst.c' X/* libsst.c - SPARC sound tools library X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <stdio.h> X#include <fcntl.h> X#include "libsst.h" X X#define AUDBUF 1024 X Xint Xsst_open( ) X { X int fd, i, play_level, record_level, gr, ger, gx; X struct audio_ioctl ai; X char *getenv(), *ep; X X fd = open( "/dev/audio", O_RDWR ); X if ( fd < 0 ) X { X perror( "sst_open: open /dev/audio" ); X exit( 1 ); X } X X /* Shrink audio device's queue size, to cut down time delay. */ X i = AUDBUF; X if ( ioctl( fd, AUDIOSETQSIZE, &i ) < 0 ) X { X perror( "sst_open: SETQSIZE" ); X exit( 1 ); X } X X /* Set gains. -10 <= ger <= 18, -18 <= gr <= 12, -18 <= gx <= 12. */ X play_level = 75; X record_level = 75; X if ( (ep = getenv( "SST_PLAY" )) != NULL ) X { X play_level = atoi( ep ); X if ( play_level < 0 || play_level > 99 ) X { X fprintf( stderr, "sst_open: SST_PLAY must be between 0 and 99\n" ); X exit( 1 ); X } X } X if ( (ep = getenv( "SST_RECORD" )) != NULL ) X { X record_level = atoi( ep ); X if ( record_level < 0 || record_level > 99 ) X { X fprintf( stderr, "sst_open: SST_RECORD must be between 0 and 99\n" ); X exit( 1 ); X } X } X X play_level = play_level * 59 / 100 - 28; X ger = play_level / 2; X gr = play_level - ger; X if ( ger < -10 ) X { X ger = -10; X gr = play_level - ger; X } X if ( gr > 12 ) X { X gr = 12; X ger = play_level - gr; X } X gx = record_level * 31 / 100 - 18; X sst_set_gr( fd, gr ); X sst_set_ger( fd, ger ); X sst_set_gx( fd, gx ); X X /* Initialize the MMR2 register to send the output to either X ** the speaker or the earphone jack, depending on SST_EARPHONES. X */ X ai.control = AUDIO_MAP_MMR2; X if ( ioctl( fd, AUDIOGETREG, &ai ) < 0 ) X { X perror( "sst_open: GETREG MMR2" ); X exit( 1 ); X } X if ( (ep = getenv( "SST_EARPHONES" )) != NULL ) X ai.data[0] &= ~AUDIO_MMR2_BITS_LS; X else X ai.data[0] |= AUDIO_MMR2_BITS_LS; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_open: SETREG MMR2" ); X exit( 1 ); X } X X return fd; X } X Xvoid Xsst_close( fd ) Xint fd; X { X struct audio_ioctl ai; X X ai.control = AUDIO_MAP_MMR1; X ai.data[0] = 0; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_close: SETREG MMR1" ); X exit( 1 ); X } X ai.control = AUDIO_MAP_MMR2; X ai.data[0] = 0; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_close: SETREG MMR2" ); X exit( 1 ); X } X close( fd ); X } X X/* These are tables of values to be loaded into various gain registers. X*/ X Xstatic unsigned char ger_table[][2] = { X 0xaa, 0xaa, /* -10db */ X 0x79, 0xac, X 0x41, 0x99, X 0x9c, 0xde, X 0x74, 0x9c, /* -6db */ X 0x6a, 0xae, X 0xab, 0xdf, X 0x64, 0xab, X 0x2a, 0xbd, X 0x5c, 0xce, X 0x00, 0x99, /* 0db */ X 0x43, 0xdd, X 0x52, 0xef, X 0x55, 0x42, X 0x31, 0xdd, X 0x43, 0x1f, X 0x40, 0xdd, /* 6db */ X 0x44, 0x0f, X 0x31, 0x1f, X 0x10, 0xdd, X 0x41, 0x0f, X 0x60, 0x0b, X 0x42, 0x10, /* 12db */ X 0x11, 0x0f, X 0x72, 0x00, X 0x21, 0x10, X 0x22, 0x00, X 0x00, 0x0b, X 0x00, 0x0f, /* 18db */ X }; X X Xstatic unsigned char gr_gx_table[][2] = { X 0x8b, 0x7c, /* -18db */ X 0x8b, 0x35, X 0x8b, 0x24, X 0x91, 0x23, X 0x91, 0x2a, X 0x91, 0x3b, X 0x91, 0xf9, /* -12db */ X 0x91, 0xb6, X 0x91, 0xa4, X 0x92, 0x32, X 0x92, 0xaa, X 0x93, 0xb3, X 0x9f, 0x91, /* -6db */ X 0x9b, 0xf9, X 0x9a, 0x4a, X 0xa2, 0xa2, X 0xaa, 0xa3, X 0xbb, 0x52, X 0x08, 0x08, /* 0db */ X 0x3d, 0xac, X 0x25, 0x33, X 0x21, 0x22, X 0x12, 0xa2, X 0x11, 0x3b, X 0x10, 0xf2, /* 6db */ X 0x02, 0xca, X 0x01, 0x5a, X 0x01, 0x12, X 0x00, 0x32, X 0x00, 0x13, X 0x00, 0x0e, /* 12db */ X }; X Xvoid Xsst_set_ger( fd, value ) Xint fd, value; X { X struct audio_ioctl ai; X X if ( ( value < -10 ) || ( value > 18 ) ) X { X fprintf( stderr, "sst_set_ger: GER %d out of range\n", value ); X return; X } X X /* Add 10 to the value to get the index into the table. */ X ai.control = AUDIO_MAP_GER; X ai.data[0] = ger_table[value + 10][1]; X ai.data[1] = ger_table[value + 10][0]; X X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_set_ger: SETREG GER" ); X exit( 1 ); X } X X ai.control = AUDIO_MAP_MMR1; X if ( ioctl( fd, AUDIOGETREG, &ai ) < 0 ) X { X perror( "sst_set_ger: GETREG MMR1" ); X exit( 1 ); X } X ai.data[0] |= AUDIO_MMR1_BITS_LOAD_GER; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_set_ger: SETREG MMR1" ); X exit( 1 ); X } X } X Xvoid Xsst_set_gr( fd, value ) Xint fd, value; X { X struct audio_ioctl ai; X X if ( ( value < -18 ) || ( value > 12 ) ) X { X fprintf( stderr, "sst_set_gr: GR %d out of range\n", value ); X return; X } X X ai.control = AUDIO_MAP_GR; X ai.data[0] = gr_gx_table[value + 18][1]; X ai.data[1] = gr_gx_table[value + 18][0]; X X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_set_gr: SETREG GR" ); X exit( 1 ); X } X X ai.control = AUDIO_MAP_MMR1; X if ( ioctl( fd, AUDIOGETREG, &ai ) < 0 ) X { X perror( "sst_set_gr: GETREG MMR1" ); X exit( 1 ); X } X ai.data[0] |= AUDIO_MMR1_BITS_LOAD_GR; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_set_gr: SETREG MMR1" ); X exit( 1 ); X } X } X Xvoid Xsst_set_gx( fd, value ) Xint fd, value; X { X struct audio_ioctl ai; X X if ( ( value < -18 ) || ( value > 12 ) ) X { X fprintf( stderr, "sst_set_gx: GX %d out of range\n", value ); X return; X } X X /* We add 18 to get the index into the table, since entry 0 represents X * -18db. X */ X ai.control = AUDIO_MAP_GX; X ai.data[0] = gr_gx_table[value + 18][1]; X ai.data[1] = gr_gx_table[value + 18][0]; X X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_set_gx: SETREG GX" ); X exit( 1 ); X } X X ai.control = AUDIO_MAP_MMR1; X if ( ioctl( fd, AUDIOGETREG, &ai ) < 0 ) X { X perror( "sst_set_gx: GETREG MMR1" ); X exit( 1 ); X } X ai.data[0] |= AUDIO_MMR1_BITS_LOAD_GX; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_set_gx: SETREG MMR1" ); X exit( 1 ); X } X } X Xvoid Xsst_tones( fd, dhz1, dhz2, thz, rhz, usec ) Xint fd, dhz1, dhz2, thz, rhz, usec; X { X struct audio_ioctl ai; X int dval1, dval2, tval, rval; X unsigned char oldmmr2, newmmr2; X X if ( dhz1 == 0 ) X dval1 = 0; X else X { X dval1 = ( dhz1 * 128 + 63 ) / 1000; X if ( ( dval1 < 1 ) || ( dval1 > 255 ) ) X { X fprintf(stderr, "sst_tones: dhz1 %d out of range\n", dhz1 ); X return; X } X } X X if ( dhz2 == 0 ) X dval2 = 0; X else X { X dval2 = ( dhz2 * 128 + 63 ) / 1000; X if ( ( dval2 < 1 ) || ( dval2 > 255 ) ) X { X fprintf(stderr, "sst_tones: dhz2 %d out of range\n", dhz2 ); X return; X } X } X X if ( thz == 0 ) X tval = 0; X else X { X tval = ( thz * 128 + 63 ) / 2000; X if ( ( tval < 1 ) || ( tval > 255 ) ) X { X fprintf(stderr, "sst_tones: thz %d out of range\n", thz ); X return; X } X } X X if ( rhz == 0 ) X rval = 0; X else X { X rval = ( rhz * 128 + 63 ) / 2000; X if ( ( rval < 1 ) || ( rval > 255 ) ) X { X fprintf(stderr, "sst_tones: rhz %d out of range\n", dhz2 ); X return; X } X } X X if ( ( dval1 != 0 || dval2 != 0 ) && ( tval != 0 || rval != 0 ) ) X { X fprintf(stderr, "sst_tones: cannot use DTMF and TONE or RINGER at the same time\n", dhz2 ); X return; X } X X if ( tval != 0 && rval != 0 ) X { X fprintf(stderr, "sst_tones: cannot use TONE and RINGER at the same time\n", dhz2 ); X return; X } X X ai.control = AUDIO_MAP_MMR2; X if ( ioctl( fd, AUDIOGETREG, &ai ) < 0 ) X { X perror( "sst_tones: GETREG MMR2" ); X exit( 1 ); X } X oldmmr2 = newmmr2 = ai.data[0]; X X if ( dval1 != 0 || dval2 != 0 ) X { X newmmr2 |= AUDIO_MMR2_BITS_DTMF; X ai.control = AUDIO_MAP_FTGR; X ai.data[0] = dval1; X ai.data[1] = dval2; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_tones: SETREG FTGR" ); X exit( 1 ); X } X } X X if ( tval != 0 ) X { X newmmr2 |= AUDIO_MMR2_BITS_TONE; X ai.control = AUDIO_MAP_FTGR; X ai.data[0] = tval; X ai.data[1] = 0; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_tones: SETREG FTGR" ); X exit( 1 ); X } X } X X if ( rval != 0 ) X { X newmmr2 |= AUDIO_MMR2_BITS_RINGER; X ai.control = AUDIO_MAP_FTGR; X ai.data[0] = rval; X ai.data[1] = 0; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_tones: SETREG FTGR" ); X exit( 1 ); X } X } X X ai.control = AUDIO_MAP_MMR2; X ai.data[0] = newmmr2; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_tones: SETREG MMR2" ); X exit( 1 ); X } X X usleep( usec ); X X ai.data[0] = oldmmr2; X if ( ioctl( fd, AUDIOSETREG, &ai ) < 0 ) X { X perror( "sst_tones: SETREG MMR2" ); X exit( 1 ); X } X } X Xvoid Xsst_dtmf( fd, dial, usecper, usecpause ) Xint fd, usecper, usecpause; Xchar *dial; X { X char *cp; X X for ( cp = dial; *cp != '\0'; cp++ ) X { X switch ( *cp ) X { X case '1': sst_tones( fd, 703, 1211, 0, 0, usecper ); break; X case '2': sst_tones( fd, 703, 1336, 0, 0, usecper ); break; X case '3': sst_tones( fd, 703, 1492, 0, 0, usecper ); break; X case 'A': sst_tones( fd, 703, 1648, 0, 0, usecper ); break; X case '4': sst_tones( fd, 773, 1211, 0, 0, usecper ); break; X case '5': sst_tones( fd, 773, 1336, 0, 0, usecper ); break; X case '6': sst_tones( fd, 773, 1492, 0, 0, usecper ); break; X case 'B': sst_tones( fd, 773, 1648, 0, 0, usecper ); break; X case '7': sst_tones( fd, 859, 1211, 0, 0, usecper ); break; X case '8': sst_tones( fd, 859, 1336, 0, 0, usecper ); break; X case '9': sst_tones( fd, 859, 1492, 0, 0, usecper ); break; X case 'C': sst_tones( fd, 859, 1648, 0, 0, usecper ); break; X case '*': sst_tones( fd, 945, 1211, 0, 0, usecper ); break; X case '0': sst_tones( fd, 945, 1336, 0, 0, usecper ); break; X case '#': sst_tones( fd, 945, 1492, 0, 0, usecper ); break; X case 'D': sst_tones( fd, 945, 1648, 0, 0, usecper ); break; X X case ' ': case '-': case '(': case ')': case '+': X continue; /* ignore */ X X case ',': usleep( usecper ); break; /* big pause */ X X default: X fprintf( stderr, "sst_dtmf: unknown dialing code '%c'\n", *cp ); X } X usleep( usecpause ); X } X } SHAR_EOF if test 10463 -ne "`wc -c < 'libsst.c'`" then echo shar: error transmitting "'libsst.c'" '(should have been 10463 characters)' fi fi # end of overwriting check echo shar: extracting "'libfft.h'" '(526 characters)' if test -f 'libfft.h' then echo shar: will not over-write existing file "'libfft.h'" else sed 's/^X//' << \SHAR_EOF > 'libfft.h' X/* libfft.h - include file for fast Fourier transform library X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X Xvoid initfft(); Xvoid fft(); SHAR_EOF if test 526 -ne "`wc -c < 'libfft.h'`" then echo shar: error transmitting "'libfft.h'" '(should have been 526 characters)' fi fi # end of overwriting check echo shar: extracting "'libfft.c'" '(2380 characters)' if test -f 'libfft.c' then echo shar: will not over-write existing file "'libfft.c'" else sed 's/^X//' << \SHAR_EOF > 'libfft.c' X/* libfft.c - fast Fourier transform library X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <stdio.h> X#include <math.h> X X#define MAXFFTSIZE 32768 X#define LOG2_MAXFFTSIZE 15 X Xstatic int bitreverse[MAXFFTSIZE], bits; X X/* initfft - initialize for fast Fourier transform X** X** b power of two such that 2**nu = number of samples X*/ Xvoid Xinitfft( b ) Xint b; X { X register int i, j, k; X X bits = b; X if ( bits > LOG2_MAXFFTSIZE ) X { X fprintf( X stderr, "%d is too many bits, max is %d\n", bits, LOG2_MAXFFTSIZE ); X exit( 1 ); X } X X for ( i = ( 1 << bits ) - 1; i >= 0; --i ) X { X k = 0; X for ( j = 0; j < bits; ++j ) X { X k *= 2; X if ( i & ( 1 << j ) ) X k += 1; X } X bitreverse[i] = k; X } X } X X/* fft - a fast Fourier transform routine X** X** xr real part of data to be transformed X** xi imaginary part (normally zero, unless inverse transform in effect) X** inv flag for inverse X*/ X Xvoid Xfft( xr, xi, inv ) Xfloat xr[], xi[]; Xint inv; X { X int n, n2, i, k, kn2, l, p; X float ang, s, c, tr, ti; X double ds, dc; X X n = 1 << bits; X n2 = n / 2; X X for ( l = 0; l < bits; ++l ) X { X for ( k = 0; k < n; k += n2 ) X { X for( i = 0; i < n2; ++i, ++k ) X { X p = bitreverse[k / n2]; X ang = 6.283185 * p / n; X#ifdef notdef X c = cos( ang ); X s = sin( ang ); X#else notdef X sincos( ang, &ds, &dc ); X s = ds; X c = dc; X#endif notdef X kn2 = k + n2; X if ( inv ) X s = -s; X tr = xr[kn2] * c + xi[kn2] * s; X ti = xi[kn2] * c - xr[kn2] * s; X xr[kn2] = xr[k] - tr; X xi[kn2] = xi[k] - ti; X xr[k] += tr; X xi[k] += ti; X } X } X n2 /= 2; X } X X for ( k = 0; k < n; ++k ) X { X i = bitreverse[k]; X if ( i <= k ) X continue; X tr = xr[k]; X ti = xi[k]; X xr[k] = xr[i]; X xi[k] = xi[i]; X xr[i] = tr; X xi[i] = ti; X } X X /* Finally, multiply each value by 1/n, if this is the forward transform. */ X if ( ! inv ) X { X register float f; X X f = 1.0 / n; X for( i = 0; i < n ; ++i ) X { X xr[i] *= f; X xi[i] *= f; X } X } X } SHAR_EOF if test 2380 -ne "`wc -c < 'libfft.c'`" then echo shar: error transmitting "'libfft.c'" '(should have been 2380 characters)' fi fi # end of overwriting check echo shar: extracting "'echoplex.c'" '(2880 characters)' if test -f 'echoplex.c' then echo shar: will not over-write existing file "'echoplex.c'" else sed 's/^X//' << \SHAR_EOF > 'echoplex.c' X/* echoplex.c - echo generator X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <stdio.h> X#include "libst.h" X X#define abs(a) ((a) >= 0 ? (a) : -(a)) X X#define FADE_THRESH 30 X#define MYBUFSIZ 256 X#define DELAYBUFSIZ ( 50 * SAMPLES_PER_SECOND ) X#define MAXDELAYS 1000 X Xmain( argc, argv ) Xint argc; Xchar *argv[]; X { X FILE *f; X char mybuf[MYBUFSIZ]; X int argn, numdelays; X register int i, j, c, lc, plc, pplc, ppplc; X static int delaybuf[DELAYBUFSIZ]; X float delay[MAXDELAYS], atten[MAXDELAYS]; X int samples[MAXDELAYS], maxsamples; X double atof(); X char *usage = "usage: %s <delay> <atten> [<delay> <atten>] ... [<file>]\n"; X X argn = 1; X numdelays = 0; X maxsamples = 0; X X while ( argn + 1 < argc ) X { X delay[numdelays] = atof( argv[argn++] ); X atten[numdelays] = atof( argv[argn++] ); X samples[numdelays] = delay[numdelays] * SAMPLES_PER_SECOND; X if ( samples[numdelays] < 1 ) X { X fprintf( stderr, "%s: delay must positive, aye!\n", argv[0] ); X exit( 1 ); X } X if ( samples[numdelays] > DELAYBUFSIZ ) X { X fprintf( X stderr, "%s: delay must be less than %g seconds\n", X argv[0], DELAYBUFSIZ / (float) SAMPLES_PER_SECOND ); X exit( 1 ); X } X if ( atten[numdelays] < 0.0 ) X { X fprintf( stderr, "%s: attenuation must positive, aye!\n", argv[0] ); X exit( 1 ); X } X if ( samples[numdelays] > maxsamples ) X maxsamples = samples[numdelays]; X ++numdelays; X } X X if ( argn == argc ) X f = stdin; X else X { X f = fopen( argv[argn], "r" ); X if ( f == NULL ) X { X perror( argv[argn] ); X exit( 1 ); X } X ++argn; X } X X if ( argn != argc ) X { X fprintf( stderr, usage, argv[0] ); X exit( 1 ); X } X X X setbuffer( stdout, mybuf, MYBUFSIZ ); X X for ( i = 0; i < maxsamples; ++i ) X delaybuf[i] = 0; X X for ( i = 0; (c = getc( f )) != EOF; i = ( i + 1 ) % maxsamples ) X { X lc = st_ulaw_to_linear( c ); X for ( j = 0; j < numdelays; ++j ) X lc = lc + delaybuf[( i + maxsamples - samples[j] ) % maxsamples] * atten[j]; X LINCLIP( lc ); X delaybuf[i] = lc; X putchar( st_linear_to_ulaw( lc ) ); X } X X for ( ppplc = pplc = plc = MAXLIN; X abs(lc) + abs(plc) + abs(pplc) + abs(ppplc) > FADE_THRESH / 4; X i = ( i + 1 ) % maxsamples ) X { X lc = 0; X for ( j = 0; j < numdelays; ++j ) X lc = lc + delaybuf[( i + maxsamples - samples[j] ) % maxsamples] * atten[j]; X LINCLIP( lc ); X delaybuf[i] = lc; X putchar( st_linear_to_ulaw( lc ) ); X ppplc = pplc; X pplc = plc; X plc = lc; X } X X exit( 0 ); X } SHAR_EOF if test 2880 -ne "`wc -c < 'echoplex.c'`" then echo shar: error transmitting "'echoplex.c'" '(should have been 2880 characters)' fi fi # end of overwriting check echo shar: extracting "'echoplex.1'" '(871 characters)' if test -f 'echoplex.1' then echo shar: will not over-write existing file "'echoplex.1'" else sed 's/^X//' << \SHAR_EOF > 'echoplex.1' X.TH echoplex 1 "20 November 1989" X.SH NAME Xechoplex - echo generator for sound files X.SH SYNOPSIS Xechoplex <delay> <atten> [<delay> <atten>] ... [<file>] X.SH DESCRIPTION XFilters input to output with an echo added for each <delay> <atten> pair Xspecified. X<delay> is in seconds, while <atten> is an attenuation factor between Xzero and one. XWhen using multiple delays, be careful that the attenuations sum to Xless than one, or positive feedback may result. X.SH AUTHOR XCopyright (C) 1989 by Jef Poskanzer. X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, provided Xthat the above copyright notice appear in all copies and that both that Xcopyright notice and this permission notice appear in supporting Xdocumentation. This software is provided "as is" without express or Ximplied warranty. SHAR_EOF if test 871 -ne "`wc -c < 'echoplex.1'`" then echo shar: error transmitting "'echoplex.1'" '(should have been 871 characters)' fi fi # end of overwriting check echo shar: extracting "'lintoulaw.c'" '(1080 characters)' if test -f 'lintoulaw.c' then echo shar: will not over-write existing file "'lintoulaw.c'" else sed 's/^X//' << \SHAR_EOF > 'lintoulaw.c' X/* lintoulaw.c - convert linear to ulaw X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <stdio.h> X#include "libst.h" X X#define MYBUFSIZ 256 X Xmain( argc, argv ) Xint argc; Xchar *argv[]; X { X FILE *f; X char mybuf[MYBUFSIZ]; X double atof(); X int c; X float lc; X X if ( argc == 1 ) X f = stdin; X else if ( argc == 2 ) X { X f = fopen( argv[1], "r" ); X if ( f == NULL ) X { X perror( argv[1] ); X exit( 1 ); X } X } X else X { X fprintf( stderr, "usage: %s [<file>]\n", argv[0] ); X exit( 1 ); X } X setbuffer( stdout, mybuf, MYBUFSIZ ); X X while ( fscanf( f, "%g", &lc ) == 1 ) X { X c = st_linear_to_ulaw( (int) lc ); X putchar( c ); X } X X exit( 0 ); X } SHAR_EOF if test 1080 -ne "`wc -c < 'lintoulaw.c'`" then echo shar: error transmitting "'lintoulaw.c'" '(should have been 1080 characters)' fi fi # end of overwriting check echo shar: extracting "'lintoulaw.1'" '(695 characters)' if test -f 'lintoulaw.1' then echo shar: will not over-write existing file "'lintoulaw.1'" else sed 's/^X//' << \SHAR_EOF > 'lintoulaw.1' X.TH lintoulaw 1 "20 November 1989" X.SH NAME Xlintoulaw - convert linear sound file to ulaw X.SH SYNOPSIS Xlintoulaw [<file>] X.SH DESCRIPTION XConverts a file of numbers between -32768 and 32767, as produced for example Xby ulawtolin(1), into ulaw format. X.SH "SEE ALSO" Xulawtolin(1) X.SH AUTHOR XCopyright (C) 1989 by Jef Poskanzer. X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, provided Xthat the above copyright notice appear in all copies and that both that Xcopyright notice and this permission notice appear in supporting Xdocumentation. This software is provided "as is" without express or Ximplied warranty. SHAR_EOF if test 695 -ne "`wc -c < 'lintoulaw.1'`" then echo shar: error transmitting "'lintoulaw.1'" '(should have been 695 characters)' fi fi # end of overwriting check echo shar: extracting "'mix.c'" '(1627 characters)' if test -f 'mix.c' then echo shar: will not over-write existing file "'mix.c'" else sed 's/^X//' << \SHAR_EOF > 'mix.c' X/* mix.c - mix multiple sound files X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <stdio.h> X#include <strings.h> X#include "libst.h" X X#define MAXFILES 64 /* the kernel's got a limit, why shouldn't I? */ X#define MYBUFSIZ 256 X Xmain( argc, argv ) Xint argc; Xchar *argv[]; X { X FILE *files[MAXFILES]; X char mybuf[MYBUFSIZ]; X int nfiles, i, c, sum, gotone; X X nfiles = argc - 1; X if ( nfiles < 2 ) X { X fprintf( stderr, "usage: %s <file1> <file2> [<fileN> ...]\n", argv[0] ); X exit( 1 ); X } X X for ( i = 0; i < nfiles; ++i ) X { X if ( strcmp( argv[i + 1], "-" ) == 0 ) X files[i] = stdin; X else X { X files[i] = fopen( argv[i + 1], "r" ); X if ( files[i] == NULL ) X { X perror( argv[i + 1] ); X exit( 1 ); X } X } X } X setbuffer( stdout, mybuf, MYBUFSIZ ); X X for ( ; ; ) X { X sum = 0; X gotone = 0; X for ( i = 0; i < nfiles; ++i ) X { X if ( files[i] != NULL ) X { X c = getc( files[i] ); X if ( c == EOF ) X { X fclose( files[i] ); X files[i] = NULL; X } X else X { X gotone = 1; X sum += st_ulaw_to_linear( (unsigned char) c ); X } X } X } X if ( gotone == 0 ) X break; X LINCLIP( sum ); X putchar( st_linear_to_ulaw( sum ) ); X } X X exit( 0 ); X } SHAR_EOF if test 1627 -ne "`wc -c < 'mix.c'`" then echo shar: error transmitting "'mix.c'" '(should have been 1627 characters)' fi fi # end of overwriting check echo shar: extracting "'mix.1'" '(665 characters)' if test -f 'mix.1' then echo shar: will not over-write existing file "'mix.1'" else sed 's/^X//' << \SHAR_EOF > 'mix.1' X.TH mix 1 "20 November 1989" X.SH NAME Xmix - mix multiple sound files X.SH SYNOPSIS Xmix <file1> <file2> ... X.SH DESCRIPTION XCombines multiple sound files into one. XThe combination is done by converting to linear, adding, and Xconverting back to ulaw. X.SH AUTHOR XCopyright (C) 1989 by Jef Poskanzer. X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, provided Xthat the above copyright notice appear in all copies and that both that Xcopyright notice and this permission notice appear in supporting Xdocumentation. This software is provided "as is" without express or Ximplied warranty. SHAR_EOF if test 665 -ne "`wc -c < 'mix.1'`" then echo shar: error transmitting "'mix.1'" '(should have been 665 characters)' fi fi # end of overwriting check echo shar: extracting "'pitch.c'" '(2825 characters)' if test -f 'pitch.c' then echo shar: will not over-write existing file "'pitch.c'" else sed 's/^X//' << \SHAR_EOF > 'pitch.c' X/* pitch.c - change the pitch of a sound file X** X** Copyright (C) 1989 by Jef Poskanzer. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include <stdio.h> X#include "libst.h" X X#define MYBUFSIZ 256 X X#define SAMPLES_PER_CHUNK 1024 X#define LOG2_SPC 10 X#define HALF_SPC 512 X X#define CHUNK_USE_FRAC 0.333333 /* only use the middle 1/3 of each chunk */ X Xmain( argc, argv ) Xint argc; Xchar *argv[]; X { X FILE *f; X char mybuf[MYBUFSIZ]; X float scale; X double atof(); X int c, i, j, k, pstart, pend, plen; X int linbuf[SAMPLES_PER_CHUNK]; X float xr[SAMPLES_PER_CHUNK], xi[SAMPLES_PER_CHUNK]; X X if ( argc < 2 || argc > 3 ) X { X fprintf( stderr, "usage: %s <factor> [<file>]\n", argv[0] ); X exit( 1 ); X } X X scale = atof( argv[1] ); X if ( scale == 0.0 ) X { X fprintf( stderr, "%s: scale factor required\n", argv[0] ); X exit( 1 ); X } X X if ( argc == 2 ) X f = stdin; X else if ( argc == 3 ) X { X f = fopen( argv[2], "r" ); X if ( f == NULL ) X { X perror( argv[2] ); X exit( 1 ); X } X } X initfft( LOG2_SPC ); X X i = 0; X pstart = 0; X pend = SAMPLES_PER_CHUNK * 0.5 + SAMPLES_PER_CHUNK * CHUNK_USE_FRAC * 0.5; X while ( (c = getc( f )) != EOF ) X { X linbuf[i] = st_ulaw_to_linear( c ); X ++i; X if ( i == SAMPLES_PER_CHUNK ) X { X shiftchunk( linbuf, i, scale, pstart, pend ); X if ( pstart == 0 ) X { X pstart = SAMPLES_PER_CHUNK * 0.5 - SAMPLES_PER_CHUNK * CHUNK_USE_FRAC * 0.5; X plen = pend - pstart; X } X for ( j = 0, k = j + plen; k < SAMPLES_PER_CHUNK; j++, k++ ) X linbuf[j] = linbuf[k]; X i -= plen; X } X } X if ( i > 0 ) X { X pend = i; X shiftchunk( linbuf, i, scale, pstart, pend ); X } X X exit( 0 ); X } X Xshiftchunk( linbuf, i, scale, pstart, pend ) Xint linbuf[SAMPLES_PER_CHUNK]; Xfloat scale; Xint i, pstart, pend; X { X register int j, k; X float xr[SAMPLES_PER_CHUNK], xi[SAMPLES_PER_CHUNK]; X float sxr[SAMPLES_PER_CHUNK], sxi[SAMPLES_PER_CHUNK]; X X for ( j = 0; j < i; ++j ) X { X xr[j] = linbuf[j]; X xi[j] = 0.0; X } X for ( ; j < SAMPLES_PER_CHUNK; ++j ) X { X xr[j] = 0.0; X xi[j] = 0.0; X } X X fft( xr, xi, 0 ); X X for ( j = 0; j < SAMPLES_PER_CHUNK; ++j ) X { X k = (int) ( ( j - HALF_SPC ) * scale + 0.5 ) + HALF_SPC; X if ( k >= 0 && k < SAMPLES_PER_CHUNK ) X { X sxr[j] = xr[k]; X sxi[j] = xi[k]; X } X else X { X sxr[j] = 0.0; X sxi[j] = 0.0; X } X } X X fft( sxr, sxi, 1 ); X X for ( j = pstart; j < pend; ++j ) X putchar( st_linear_to_ulaw( (int) sxr[j] ) ); X } SHAR_EOF if test 2825 -ne "`wc -c < 'pitch.c'`" then echo shar: error transmitting "'pitch.c'" '(should have been 2825 characters)' fi fi # end of overwriting check echo shar: extracting "'pitch.1'" '(830 characters)' if test -f 'pitch.1' then echo shar: will not over-write existing file "'pitch.1'" else sed 's/^X//' << \SHAR_EOF > 'pitch.1' X.TH pitch 1 "20 November 1989" X.SH NAME Xpitch - change the pitch of a sound file X.SH SYNOPSIS Xpitch <factor> [<file>] X.SH DESCRIPTION XUses the fast Fourier transform to scale the frequencies in a sound file Xby the specified factor. X.SH "SEE ALSO" Xspeed(1), volume(1) X.SH BUGS XDoesn't work. Perhaps someone will be kind enough to send me a fixed version, XI admit my understanding of the FFT is extremely limited. X.SH AUTHOR XCopyright (C) 1989 by Jef Poskanzer. X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, provided Xthat the above copyright notice appear in all copies and that both that Xcopyright notice and this permission notice appear in supporting Xdocumentation. This software is provided "as is" without express or Ximplied warranty. SHAR_EOF if test 830 -ne "`wc -c < 'pitch.1'`" then echo shar: error transmitting "'pitch.1'" '(should have been 830 characters)' fi fi # end of overwriting check # End of shell archive exit 0