ref: 98267de439714fcdff94c9588f34fb8a67df70c1
author: cbagwell <cbagwell>
date: Mon Feb 1 23:03:34 EST 1999
Initial revision
--- /dev/null
+++ b/CHEAT
@@ -1,0 +1,105 @@
+CHEAT SHEET
+-----------
+
+This is a cheat sheet of examples using SOX to do various common
+sound file conversions. The file format examples are starting
+to become dated. Any offers to update this document to explain
+the ends and outs of each format would be appreciated.
+
+In general, sox will attempt to take an input sound file format and
+convert it to a new file format using a similar data types and sample
+rates. For instance "sox monkey.au monkey.wav" would try and convert
+the mono 8000Hz u-law .au file to a 8000Hz u-law .wav file.
+
+If an output format doesn't support the same data types as the input
+file then Sox will generally select a default format to save it in.
+You can select a data type of your choice using command line options.
+You can also override data type values to have a output file of
+higher or lower percision data (and thus higher or lower file size).
+
+Most file formats that contain complete headers will automatically
+convert to a similar format. This means .wav, .aiff, and .voc files
+will readily convert to each other without the need of complex
+command lines.
+
+If you create a sound file and you can not play it, check to make
+sure your sound card to play a file using this data type.
+
+SOX is great to use along with other command line programs. The
+currently most used example is to use mpg123 to convert mp3 files
+in to wav files. The following command line will do this:
+
+mpg123 -b 10000 -s filename.mp3 | sox -t raw -r 44100 -s -w -c 2 - filename.wav
+
+The SUN examples below all assume you have the old SUN voice-quality 8khz
+u-law hardware. If you do then you will want to have all your .au
+files in this format so that you cat do thinks like
+"cat soundfile.au > /dev/audio" and you will hear a good file.
+If the .AU file doesn't have a proper header, then you'll need the second
+command line to let sox know the values. If the .AU has a proper
+header then you can remove the "-r 8000 -U -b" in front of
+"file.au".
+
+SUN .au to Mac .snd:
+
+ sox file.au -r 11025 -t ub file.snd
+or:
+ sox -t ul -r 8000 file.au -r 11025 -t ub file.snd
+
+When you copy the file to the Mac, you'll have to set
+the sample rate by hand.
+
+Mac .snd to SUN .au
+
+ sox -r 11025 -t ub file.snd -r 8000 -U -b file.au
+
+The Mac file might also be at sample rates 5012, 22050, or 44100.
+
+PC .voc to SUN .au
+
+ sox file.voc -r 8000 -U -b file.au
+
+SUN .au to PC .voc
+
+ sox file.au file.voc
+or:
+ sox -r 8000 -t ul file.au file.voc
+
+SUN .au to WAV - without clipping
+
+ sox file.au -s -w file.wav
+or:
+ sox -t ul -r 8000 file.au -s -w file.wav
+
+WAV to SUN .au
+
+ sox file.wav -r 8000 -U -b file.au
+
+WAV to VOC
+ sox file.wav -u -b file.voc
+
+VOC to WAV
+ sox file.voc file.wav
+
+Any file to SUN .au
+
+sox -t auto file.X -c 1 -t aiff - | sox -t aiff - -r 8000 -U -b -t au file.au
+
+Just convert file format without making a disk file.
+Example: convert input stream in AIFF format to output stream in WAV format:
+
+sox -t aiff - -t wav -
+
+Some people try to put this kind of command in scripts.
+
+It is important to understand how the internals of Sox work when
+working with compressed audio, including u-law, a-law, ADPCM, or GSM.
+Sox takes ALL input data types and converts them to uncompressed
+32-bit signed data. It will then convert this internal version into
+the requested output format. This means unneeded noise can be introduced
+from decompressing data and then recompressing, such as would happen
+when reading u-law data and writing back out u-law data. If possible,
+specify the output data to be uncompressed PCM.
+
+Good luck!
+
--- /dev/null
+++ b/CHEAT.eft
@@ -1,0 +1,280 @@
+This is a cheat sheet of examples using SOX to
+add effects on sound files.
+
+Introduction:
+
+The core problem is that you need some experience in using effects
+in order to say "that any old sound file sounds with effects
+absolutely hip". There isn't any rule-based system which tell you
+the correct setting of all the parameters for every effect.
+But after some time you will become an expert in using effects.
+
+Here are some examples which can be used with any music sample.
+(For a sample where only a single instrument is playing, extreme
+parameter setting may make well-known "typically" or "classical"
+sounds. Likewise, for drums, vocals or guitars.)
+Single effects will be explained and some given parameter settings
+that can be used to understand the theorie by listening to the sound file
+with the added effect.
+
+Using multiple effects in parallel or in sequel can result either
+in very perfect sound or ( mostly ) in a dramatic overloading in
+variations of sounds such that your ear may follow the sound but
+you will feel unsatisfied. Hence, for the first time using effects
+try to compose them as less as possible. We don't regard the
+composition of effects in the examples because to many combinations
+are possible and you really need a very fast maschine and a lot of
+memory to play them in real-time.
+
+And real-time playing of sounds will speed up learning the parameter
+setting.
+
+Basically, we will use the "play" front-end of SOX since it is easier
+to listen sounds coming out of the speaker or earphone instead
+of looking at cryptical data in sound files.
+
+For easy listening of file.xxx ( "xxx" is any sound format ):
+
+ play file.xxx effect-name effect-parameters
+
+Or more SOX-like ( for "dsp" output ):
+
+ sox file.xxx -t ossdsp -w -s /dev/dsp effect-name effect-parameters
+
+or ( for "au" output ):
+
+ sox file.xxx -t sunau -w -s /dev/audio effect-name effect-parameters
+
+And for date freaks:
+
+ sox file.xxx file.yyy effect-name effect-parameters
+
+Additional options can be used. However, in this case, for real-time
+playing you'll need a very fast machine.
+
+Notes:
+
+I played all examples in real-time on a Pentium 100 with 32 Mb and
+Linux 2.0.30 using a self-recorded sample ( 3:15 min long in "wav"
+format with 44.1 kHz sample rate and stereo 16 bit ).
+The sample should not contain any of the effects. However,
+if you take any recording of a sound track from radio or tape or cd,
+and it sounds like a live concert or ten people are playing the same
+rhythm with their drums or funky-groves, then take any other sample.
+(Typically, less then four different intruments and no synthesizer
+in the sample is suitable. Likewise, the combination vocal, drums, bass
+and guitar.)
+
+Effects:
+
+Echo
+----
+
+An echo effect can be naturally found in the mountains, standing somewhere
+on a moutain and shouting a single word will result in one or more repetitions
+of the word ( if not, turn a bit around ant try next, or climb to the next
+mountain ).
+
+However, the time difference between shouting and repeating is the delay
+(time), its loudness is the decay. Multiple echos can have different delays and
+decays.
+
+Very popular is using echos to play an instrument with itself together, like
+some guitar players ( Brain May from Queen ) or vocalists are doing.
+For music samples of more than one instrument, echo can be used to add a
+second sample shortly after the original one.
+This will sound as doubling the number of instruments playing the same sample:
+
+ play file.xxx echo 0.8 0.88 60.0 0.4
+
+If the delay is very short then it sound like a (metallic) roboter playing
+music:
+
+ play file.xxx echo 0.8 0.88 6.0 0.4
+
+Longer delay will sound like a open air concert in the mountains:
+
+ play file.xxx echo 0.8 0.9 1000.0 0.3
+
+One mountain more, and:
+
+ play file.xxx echo 0.8 0.9 1000.0 0.3 1800.0 0.25
+
+Echos
+-----
+
+Like the echo effect, echos stand for "ECHO in Sequel", that is the first echos
+takes the input, the second the input and the first echos, the third the input
+and the first and the second echos, ... and so on.
+Care should be taken using many echos ( see introduction ); a single echos
+has the same effect as a single echo.
+The sample will be bounced twice in symmetric echos:
+
+ play file.xxx echos 0.8 0.7 700.0 0.25 700.0 0.3
+
+The sample will be bounced twice in asymmetric echos:
+
+ play file.xxx echos 0.8 0.7 700.0 0.25 900.0 0.3
+
+The sample will sound as played in a garage:
+
+ play file.xxx echos 0.8 0.7 40.0 0.25 63.0 0.3
+
+Chorus
+------
+
+The chorus effect has its name because it will often be used to make a single
+vocal sound like a chorus. But it can be applied to other instrument samples
+too.
+
+It works like the echo effect with a short delay, but the delay isn't constant.
+The delay is varied using a sinodial or triangular modulation. The modulation
+depth defines the range the modulated delay is played before or after the
+delay. Hence the delayed sound will sound slower or faster, that is the delayed
+sound tuned around the original one, like in a chorus where some vocal are
+a bit out of tune.
+
+The typical delay is around 40ms to 60ms, the speed of the modualtion is best
+near 0.25Hz and the modulation depth around 2ms.
+
+A single delay will make the sample more overloaded:
+
+ play file.xxx chorus 0.7 0.9 55.0 0.4 0.25 2.0 -t
+
+Two delays of the original samples sound like this:
+
+ play file.xxx chorus 0.6 0.9 50.0 0.4 0.25 2.0 -t 60.0 0.32 0.4 1.3 -s
+
+A big chorus of the sample is ( three additional samples ):
+
+ play file.xxx chorus 0.5 0.9 50.0 0.4 0.25 2.0 -t 60.0 0.32 0.4 2.3 -t \
+ 40.0 0.3 0.3 1.3 -s
+
+Flanger
+-------
+
+The flanger effect is like the chorus effect, but the delay varies between
+0ms and maximal 5ms. It sound like wind blowing, sometimes faster or slower
+including changes of the speed.
+
+The flanger effect is widely used in funk and soul music, where the guitar
+sound varies frequently slow or a bit faster.
+
+The typical delay is around 3ms to 5ms, the speed of the modulation is best
+near 0.5Hz.
+
+Now, let's groove the sample:
+
+ play file.xxx flanger 0.6 0.87 3.0 0.9 0.5 -s
+
+listen carefully between the difference of sinodial and triangular modulation:
+
+ play file.xxx flanger 0.6 0.87 3.0 0.9 0.5 -t
+
+If the decay is a bit lower, than the effect sounds more popular:
+
+ play file.xxx flanger 0.8 0.88 3.0 0.4 0.5 -t
+
+The drunken loundspeaker system:
+
+ play file.xxx flanger 0.9 0.9 4.0 0.23 1.3 -s
+
+Reverb
+------
+
+The reverb effect is often used in audience hall which are to small or to many
+visitors disturb the reflection of sound at the walls to make the sound played
+more monumental. You can try the reverb effect in your bathroom or garage or
+sport halls by shouting loud some words. You'll hear the words reflected from
+the walls.
+
+The biggest problem in using the reverb effect is the correct setting of the
+(wall) delays such that the sound is relistic an doesn't sound like music
+playing in a tin or overloaded feedback distroys any illusion of any big hall.
+To help you for much realisitc reverb effects, you should decide first, how
+long the reverb should take place until it is not loud enough to be registered
+by your ears. This is be done by the reverb time "t", in small halls 200ms in
+bigger one 1000ms, if you like. Clearly, the walls of such a hall aren't far
+away, so you should define its setting be given every wall its delay time.
+However, if the wall is to far eway for the reverb time, you won't hear the
+reverb, so the nearest wall will be best "t/4" delay and the farest "t/2".
+You can try other distances as well, but it won't sound very realistic.
+The walls shouldn't stand to close to each other and not in a multiple interger
+distance to each other ( so avoid wall like: 200.0 and 202.0, or something
+like 100.0 and 200.0 ).
+
+Since audience halls do have a lot of walls, we will start designing one
+beginning with one wall:
+
+ play file.xxx reverb 1.0 600.0 180.0
+
+One wall more:
+
+ play file.xxx reverb 1.0 600.0 180.0 200.0
+
+Next two walls:
+
+ play file.xxx reverb 1.0 600.0 180.0 200.0 220.0 240.0
+
+Now, why not a futuristic hall with six walls:
+
+ play file.xxx reverb 1.0 600.0 180.0 200.0 220.0 240.0 280.0 300.0
+
+If you run out of machine power or memory, then stop as much applications
+as possible ( every interupt will consume a lot of cpu time which for
+bigger halls is absolutely neccessary ).
+
+Phaser
+------
+
+The phaser effect is like the flanger effect, but it uses a reverb instead of
+an echo and does phase shifting. You'll hear the difference in the examples
+comparing both effects ( simply change the effect name ).
+The delay modulation can be done sinodial or triangular, preferable is the
+later one for multiple instruments playing. For single instrument sounds
+the sinodial phaser effect will give a sharper phasing effect.
+The decay shouln't be to close to 1.0 which will cause dramatic feedback.
+A good range is about 0.5 to 0.1 for the decay.
+
+We will take a parameter setting as for the flanger before ( gain-out is
+lower since feedback can raise the output dramatically ):
+
+ play file.xxx phaser 0.8 0.74 3.0 0.4 0.5 -t
+
+The drunken loundspeaker system ( now less alkohol ):
+
+ play file.xxx phaser 0.9 0.85 4.0 0.23 1.3 -s
+
+A popular sound of the sample is as follows:
+
+ play file.xxx phaser 0.89 0.85 1.0 0.24 2.0 -t
+
+The sample sounds if ten springs are in your ears:
+
+ play file.xxx phaser 0.6 0.66 3.0 0.6 2.0 -t
+
+Other effects ( copy, rate, avg, stat, vibro, lowp, highp, band, reverb )
+-------------
+
+The other effects are simply to use. However, an "easy to use manual" should
+be given here.
+
+More effects ( to do ! )
+------------
+
+There are a lot of effects around like noise gates, compressors, waw-waw,
+stereo effects and so on. They should be implemented making SOX to be more
+useful in sound mixing technics coming together with a great varity of
+different sound effects.
+
+Combining effects be using then in parallel or sequel on different channels
+needs some easy mechanism which is real-time stable.
+
+Really missing, is the changing of the parameters, starting and stoping of
+effects while playing samples in real-time!
+
+
+Good luck and have fun with all the effects!
+
+ Juergen Mueller (jmueller@uia.ua.ac.be)
+
--- /dev/null
+++ b/Changelog
@@ -1,0 +1,169 @@
+Change History
+--------------
+
+This file contains a list of all changes starting after the release of
+sox-11gamma.
+
+sox-12.16
+---------
+
+ o Fixed a bug in .au's handling of G.723. It wasn't using the correct
+ number of bits.
+ o Quoted $filename in play/rec scripts so that files with spaces in
+ their names can be given.
+ o Old OS/2 support didn't work. Replaced with known working EMX
+ GCC compatible code.
+ o ADPCM WAV files were defaulting to 8-bit outputs and thus losing
+ some persision. Now defaults to 16-bit signed uncompressed data.
+ o Fixed a couple cross-platform compiler issues.
+ o Minor correction for -r example in manual page.
+ o Renamed sox.sh to soxeffect and rewrote. Symbolic links can be made
+ from this file to the name of a sox effect. It will then run that
+ effect on STDIN and output the results to STDOUT.
+ o Fixed up some makefiles and 16-bit support from patches sent by
+ Mark Morgan Lloyd (markMLl.in@telemetry.co.uk). Also added some
+ nice DOS test bat files from him as well.
+ o Cleaned up some more cross-platform compile problems. In the process
+ got it working with Turbo C again, kinda. It still locks DOS up at times.
+
+
+sox-12.15
+---------
+
+ o Juergen Mueller moved Sox forward quite a bit by adding all the
+ most commonly known "Guitar Effects". He enhanced echo support,
+ added chorus, flanger, and reverb effects. He also wrote a very
+ handy CHEAT.eft file for using various effects.
+ o Incorporated Yamaha TX-16W sampler file support provided by
+ Rob Talley (rob@aii.com) and Mark Lakata (lakata@physics.berkeley.edu).
+ o Fixed a small bug in hcom compression, dependent on sign
+ extension. Leigh Smith (leigh@psychokiller.dialix.oz.au).
+ o sox -h now prints out the file formats and effects supported.
+ Leigh Smith and Chris Bagwell.
+ o smp transfers comments more completely. Leigh Smith.
+ o aiff manages markers and loops correctly and produces more
+ verbose output. Leigh Smith.
+ o Added polyphase resampler (kb@ece.cmu.edu). This adds a slightly
+ different resampling algorithm to the mix.
+ o Michael Brown (mjb@pootle.demon.co.uk) sent a patch to stop crashes
+ from happening when reading mono MS ADPCM files.
+ o Fabrice Bellard has added a less buggy 'rate' conversion. I've left
+ the old rate code included but if all goes well this will become
+ the new 'rate'. Please test and let me know how it works. Resample
+ effect needs to be reworked now.
+ o Heiko Eissfeldt: Implemented a simple deemphasis effect for
+ certain audio cd samples.
+ o Matija Nalis (mnalis@public.srce.hr) sent a patch to fix volume adjustment
+ (-v) option of sox.
+ o Fixed typo in optimazation flag in unix makefile, as pointed out by
+ Manoj Kasichainula (manojk@io.com).
+ o Fixed missing ';;' in play script. cbagwell
+ o Fixed bug in determining length of IMA and MS ADPCM WAVE files. cbagwell
+ o Fixed bug in how stereo effects were drained which fixed the
+ "reverse" effect from only saving half of stereo files. cbagwell
+ o Can use "-e" without an effect again.
+ o Added -g and -a options for new style support of GSM and ADPCM. Added
+ error checking to various formats to avoid allowing these types.
+
+sox-12.14
+---------
+
+ o Bumped major version number up and shortened name. The shorter name
+ should help the various distributions using this package.
+ o Added support for MS ADPCM and IMA (or DVI) ADPCM for .wav files.
+ Thanks to Mark Podlipec's xanim for this code (podlipec@ici.net).
+ o Change Lance Norskog's email address to thinman@meer.net. The old
+ one was bouncing.
+ o Added path string to play and rec strings so that it could be run by
+ users without complete paths setup (i.e. Ran by "rc" files during bootup
+ or shutdown)
+ o Fixed -e option from Richard Guenther
+ (richard.guenther@student.uni-tuebingen.de) and fixed a small bug
+ in stat.
+ o Fixed a bug in the mask effect for ULAW/ALAW files.
+ o Fixed a bug in cdr output files that appended trash to end of file.
+ o Guenter Geiger (geiger@iem.mhsg.ac.at) made a rather large patch to
+ allow sox to work on 64-bit alphas. It was done the easiest meathod
+ by changing all long declarations to use a macro that knows to
+ make it 32-bits. Want to port to another 64-bit-but-not-alpha
+ machine? Grep for "alpha" to see changes. There are most likely
+ several bugs left for alphas. Guenter is also supporting this
+ package for the Debian distribution.
+ o Did some major code cleanups to clear out some warning messages
+ during compile. This is to clear up problems I'm finding under
+ both alpha and dos. Some warning messages are actually useful
+ now (pointing out possible data loss). Hopefully, I didn't
+ break anything.
+ o Code clean up allows me to finally compile code under Turbo C
+ again. Too bad the EXE gets a currupted stack somewhere and locks
+ up the system. Anyone want to try it with Borland C for me?
+ If you get a working EXE I would like to start distributing a DOS
+ package like there used to be.
+ o Speaking of cleanups, anyone want to help cleanup the makefiles for
+ various platforms? They are quite outdated right now and it is
+ very obvious that Sox hasn't been able to compile under all the
+ platforms it once did for several releases. Please send in
+ the cleaned-up makefile versions along with what programs you
+ used to compile it with.
+ o There is a known bug in hcom's compress() function. It is allocating
+ memory that can't be free'd under some OS's. It causes a core dump.
+
+sox-11gamma-cb3
+---------------
+
+This release of sox is mainly a bugfix release. The following things
+have changed:
+
+ o Documentation has been updated when it was obviously wrong.
+ Much more work could be done. Man pages were updated to
+ work correctly on Solaris and add some missing info.
+ o Several people sent me patches to fix compiling on Solaris
+ as well as fix a few bugs.
+ o Change USS driver's name to OSS. Man, does that driver
+ like to change names! This could cause problems if you
+ have made your own custom play and rec scripts.
+ o Updated my email address. Sorry if I haven't responded to
+ any emails as I no longer have access to my old address.
+ Please use cbagwell@sprynet.com.
+ o Fixed unix test scripts so that they worked again.
+ o Fixed endian bug in psion .wve code.
+ o Replaced outdated voc info file with detailed format info
+ inside voc code.
+ o Added new sound format, cvsd (Continuously Variable Slope Delta)
+ from Thomas Sailer (sailer@ife.ee.ethz.ch).
+
+sox-11gamma-cb2
+---------------
+
+This release of sox is based on the latest gamma version released
+plus some patches I've made to support the following new features:
+
+I would like to thank everyone that wrote me about the long
+standing bug in Sox that could DELETE your /dev/* file if the
+program was aborted for reason such as invalid audio file. Special
+thanks for Bryan Franklin for sending in a patch when I was
+to busy to even look for it.
+
+
+ o Better play support for 8-bit stereo voc files. New support
+ for outputing both 8-bit and 16-bit stereo voc files.
+ o Built-in support for playing and recording from Linux /dev/dsp.
+ This is a re-write and seperate module from the previous
+ support included inside the sbdsp module. Also fixes a buffer
+ size bug that showed up when using newer versions of OSS.
+ This driver will work with OSS (and older versions called USS, TASD
+ and Voxware).
+ o Support for audio playing and recording with SunOS /dev/audio.
+ o Fixes a bug were /dev/audio or /dev/dsp could be deleted
+ when playing an invalid format audio file.
+ o Expanded options for play and rec scripts. You can now specify
+ sox effects after the filename and hear them in real time.
+ Please be sure that an older version of sox is not in your path
+ because these script will possibly find it first and
+ incorrectly use it.
+ o Setting play/record volume still requires an external program.
+ If you have one a command line program to do this (such as
+ "mixer" for Linux) then you will want to edit the play and rec
+ to use this. The current support for it is only in example
+ form of how it can be done.
+
--- /dev/null
+++ b/INSTALL
@@ -1,0 +1,75 @@
+SOX: Sound Tools Installation
+
+October 16, 1998
+
+The sox program is just a batch utility that reads & writes
+files. It's very easy to port to new computers.
+
+This distribution will compile and run on most Unix systems.
+It was originally developed on a Unix/386 machine running AT&T V.3.2
+but it currently developed under Linux. With little work it should
+work with most SVR4 systems, BSD-derived Unix's and DOS systems that
+use the GNU tool set.
+
+Sox supports the following operating systems. Use the listed
+Makefile when compiling.
+
+ AMIGA Makefile.ami (hasn't been verified lately)
+ DOS Makefile.dos (Borland and Turbo C, almost Microsoft C++)
+ or Makefile.unx (using GCC compatible compiler)
+ OS/2 Makefile.unx (using EMX GCC compiler)
+ OS9 Makefile.os9
+ UNIX Makefile.unx (or most platforms using GCC compatible compiler)
+ VMS descrip.mms & sox.opt (Support is outdated. Read vms.lis)
+ WIN95/NT Makefile.unx (using Cynus GCC for Win32)
+ or Makefile.dos (with a little modifying for Visual C++)
+
+You can run the makefile on most systems by using the following
+command line:
+
+make -f Makefile.name or
+make -fmakefile.name
+
+Before compiling you will need to edit the Makefile and uncomment
+the compiler define section related to your operating system
+and possibly comment out any previous system defines.
+
+There are a few additional defines available for your operating
+system to add things such as sound playing support. This is
+generally documented in the Makefiles. Look at Makefile.unx for
+the most complete set of optional defines that Sox supports.
+
+There is optional GSM support as a data type but you must first
+install the GSM library on your system. More information on it
+can be obtained from http://www.cs.tu-berlin.de/~jutta/toast.html
+After installing the GSM library you must point to this file by
+commenting and modifying the appropriate section of the Makefile.
+
+After successfully compiling SOX, try translating a sound file.
+If you can play one of the supported sound file formats,
+translate 'monkey.voc' to your format (we'll use 'xxx'):
+
+ sox monkey.voc monkey.xxx
+
+You may have to give the word size and rate for the file.
+For example, this command will make a sound file with a data rate of
+12,500 samples per second and the data formatted as signed shorts:
+
+ sox monkey.voc -r 12500 -s -w monkey.xxx
+
+If monkey.xxx plays properly (it's a very short monkey screech),
+congratulations! SOX works. Now you should run the 'tests.sh'
+shell script to exercise various test scenarios. It should
+print nothing out. You can only run this script under Unix.
+It shows alternate uses of the (far too) many options to sox.
+After that, 'testall.sh' tests most of the implemented file
+handlers to make sure that some portability issue haven't popped up.
+
+After testing with a sound file, try compiling sox with the
+optimizer (-O instead of -g). It should run a little faster.
+
+If you're processing lots of u-law or a-law files, you should
+define FAST_ULAW_COMPRESSION and/or FAST_ALAW_COMPRESSION in your
+Makefile. These substitute a table-based method for the standard method.
+The tables are 32K, so if you don't want them, you don't have to
+use them.
--- /dev/null
+++ b/Makefile
@@ -1,0 +1,256 @@
+#
+# Sound Tools Makefile
+#
+# builds libst.a and sox
+#
+# Updated on 02/24/97 - by Chris Bagwell (cbagwell@sprynet.com)
+# Inhanced Makefile to install software and documented a little better.
+#
+# Updated on 05 May 1998 by Chris Bagwell (cbagwell@sprynet.com)
+# Made some changes for various platforms based on others sugestions
+# and made my home system (Linux) the default. ;-)
+#
+# July 19, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+# Redid makefile so that libraries could be optionally linked in.
+# Also made each specific portion of system specifics a seperate
+# line to comment/uncomment so that it will be easier to see how
+# to compiler on a wider array of systems (he says with a grin).
+#
+
+# These things are site dependant so you may want to change.
+PREFIX = /usr/local
+BINDIR = $(PREFIX)/bin
+LIBDIR = $(PREFIX)/lib
+MANDIR = $(PREFIX)/man
+
+SRCDIR = sox-12.16
+
+##############################################################################
+
+FSRC = 8svx.c aiff.c au.c auto.c cdr.c cvsd.c dat.c g711.c g721.c \
+ g723_24.c g723_40.c g72x.c gsm.c hcom.c maud.c oss.c raw.c \
+ sbdsp.c sf.c smp.c sndrtool.c sunaudio.c tx16w.c voc.c wav.c wve.c
+
+ESRC = avg.c band.c chorus.c copy.c cut.c deemphas.c dyn.c echo.c echos.c \
+ flanger.c highp.c lowp.c map.c mask.c phaser.c pick.c \
+ polyphas.c rate.c resample.c reverb.c reverse.c split.c \
+ stat.c vibro.c
+
+PSRC = sox.c
+
+SOURCES = $(PSRC) $(FSRC) $(ESRC) handlers.c libst.c misc.c util.c getopt.c
+
+##############################################################################
+
+HEADERS = st.h libst.h sfheader.h sfircam.h patchlvl.h version.h wav.h \
+ g72x.h resdefs.h resampl.h
+
+TESTS = tests.sh testall.sh monkey.au monkey.voc
+
+MISC = README INSTALL TODO TIPS CHEAT CHEAT.eft Changelog sox.1 sox.txt \
+ libst.3 libst.txt play.1 Makefile.unx Makefile.dos Makefile.b30 \
+ Makefile.c70 soxeffect play rec
+
+SKEL = skel.c skeleff.c
+
+AMIGA = Makefile.ami amiga.h
+
+DOS = tests.bat testall.bat
+
+OS9 = Makefile.os9
+
+VMS = descrip.mms sound2au.com sound2sun.c sound2sun.opt \
+ sox.opt tests.com vms.lis
+
+FILES = $(MISC) $(HEADERS) $(SOURCES) \
+ $(AMIGA) $(DOS) $(OS9) $(VMS) \
+ $(SKEL) $(TESTS)
+
+##############################################################################
+
+FOBJ = 8svx.o aiff.o au.o auto.o cdr.o cvsd.o dat.o g711.o g721.o \
+ g723_24.o g723_40.o g72x.o gsm.o hcom.o maud.o oss.o raw.o \
+ sbdsp.o sf.o smp.o sndrtool.o sunaudio.o tx16w.o voc.o wav.o wve.o
+
+EOBJ = avg.o band.o chorus.o copy.o cut.o deemphas.o dyn.o echo.o echos.o \
+ flanger.o highp.o lowp.o map.o mask.o phaser.o pick.o \
+ polyphas.o rate.o resample.o reverb.o reverse.o split.o \
+ stat.o vibro.o
+
+SOUNDLIB = libst.a
+LIBOBJS = $(FOBJ) $(EOBJ) handlers.o libst.o misc.o util.o getopt.o
+
+##############################################################################
+
+#
+# System dependency parameters
+# Find anything related to your system and uncomment.
+#
+
+# Default way to delete files.
+RM = rm -f
+
+# Chose the best compiler you got from the following:
+#
+# GCC with all warnings and debug info
+CC = gcc -g -Wall
+#
+# GCC with no special options
+# CC = gcc
+#
+# Generic compiler on your system
+# CC = cc
+#
+# EMX GCC under OS/2 seems to need the following
+# CC = gcc -Zcrtdll -Zexe
+
+# For optimized compilation, uncomment one of the following that your
+# compiler understands.
+#
+# gcc's all understand this as do lots of standard compilers. Try this one
+# first.
+# O = -O2
+
+# getopt() support is defined here. If you have a built-in
+# getopt() that is compatible with SVR5 then you don't need to
+# do anything special.
+#
+# If you don't have any getopt() function then use the following
+# define to use Sox's builtin version
+# GETOPT_DEFINES = -DNEED_GETOPT
+#
+# If your system has the more advanced version of getopt() that
+# also has its own getopt.h file (Such as the case with GNU libc 2.0)
+# then uncomment the following line. Don't uncomment anything if
+# its in stdlib.h.
+GETOPT_DEFINES = -DHAS_GETOPT_H
+
+# Uncomment the following if your system does not have a built in
+# strerror(). This includes SunOS.
+#
+# STRERR_DEFINES = -DNEED_STRERROR
+
+# Uncomment the following if your system does not have a built in
+# MEMMOVE function. Sox will attempt to use bcopy instead.
+# SunOS has this problem.
+#
+# MEMMOVE_DEFINES = -DNEED_MEMMOVE
+
+# If you have the GSM 6.10 libraries installed then uncomment the follow
+# 4 lines, and change to reflect your installation paths.
+#
+GSM_PRE_LIBS = -L/usr/local/lib
+GSM_POST_LIBS = -lgsm
+GSM_INCLUDES = -I/usr/local/include/
+GSM_DEFINES = -DHAS_GSM
+
+# For sound support on machines that include the OSS sound driver
+# (such as Linux) then uncomment the following line.
+#
+OSS_DEFINES = -DOSS_PLAYER
+
+# For sound support under SunOS and Solaris then uncomment the following line.
+#
+# SUNAUDIO_DEFINES = -DSUNAUDIO_PLAYER
+
+# For sound support on 386 AT&T Unix then uncomment the following line
+#
+# BLASTER_DEFINES = -DBLASTER
+
+# For sound support on Intel BSD-derived Unix's using Steve Haenichen's SBLAST
+# driver uncomment the following line.
+#
+# SBLAST_DEFINES = -DSBLAST
+
+# Uncomment the following lines if your compiling under DOS or Windows.
+# defines .snd to mean a DOS soundtool file (starts with SOUND)
+#
+# DOS_DEFINES = -DDOS
+# RM = del /q
+
+# Uncomment the following line if compiling under NeXT.
+# defines .snd to mean a NeXT sound format file only.
+#
+# NEXT_DEFINES = -DNeXT
+
+# Uncomment the following line if compling under MacIntosh
+# defines .snd to mean a Mac-style headerless unsigned byte
+# sample, probably at 11050 hertz. You'll have to set
+# the speed on the command line.
+# MAC_DEFINES = -DMAC
+
+# MISC DEFINES - The catch all for things that make even less sense
+# then normal under unix. If you need more than one of the following
+# MISC DEFINES remember to include them on one line so it isn't just
+# redefined.
+#
+# Testing new improved rate code. You can use the older version if ther
+# are problems.
+# MISC_DEFINES = -DUSE_OLD_RATE
+#
+# For an extra 32k memory, you can include u-law/a-law lookup
+# tables to speed compressiong/decompression of this type data.
+# MISC_DEFINES = -DFAST_ULAW_COMPRESSION -DFAST_ALAW_COMPRESSION
+
+
+##############################################################################
+
+# Library setup
+
+# How should libaries be created. Most systems can simply use the following.
+AR = ar r
+
+# How should 'ranlib' be performed. HPUX, Linux, BSD-ish, SunOS, Solaris
+RANLIB = ranlib
+
+# AT&T System V and GCC on DOS or OS/2 based systems
+# RANLIB = ar ts
+
+# Some systems don't have a ranlib that you can run. Use the following
+# for those systems.
+# RANLIB = true
+
+##############################################################################
+
+SOX_PRE_LIBS = $(GSM_PRE_LIBS)
+SOX_POST_LIBS = $(GSM_POST_LIBS) -lm
+SOX_INCLUDES = $(GSM_INCLUDES)
+SOX_DEFINES = $(GSM_DEFINES) $(OSS_DEFINES) $(SUNAUDIO_DEFINES) \
+ $(BLASTER) $(GETOPT_DEFINES) $(STRERR_DEFINES) $(MEMMOVE_DEFINES) \
+ $(NEXT_DEFINES) $(MAC_DEFINES) $(MISC_DEFINES)
+
+CFLAGS = $O $(SOX_DEFINES) $(SOX_INCLUDES)
+
+all: sox
+
+sox: sox.o $(SOUNDLIB)
+ $(CC) $(CFLAGS) -o sox sox.o $(SOUNDLIB) $(SOX_PRE_LIBS) $(SOX_POST_LIBS)
+
+$(SOUNDLIB): $(LIBOBJS)
+ $(RM) $(SOUNDLIB)
+ $(AR) $(SOUNDLIB) $(LIBOBJS)
+ $(RANLIB) $(SOUNDLIB)
+
+sox.o: sox.c st.h
+
+$(LIBOBJS): st.h version.h patchlvl.h
+
+man: sox.1 libst.3
+ $(RM) sox.txt libst.txt
+ nroff -man sox.1 | col -b > sox.txt
+ nroff -man libst.3 | col -b > libst.txt
+
+install: sox
+ -install -c -m 755 sox play rec $(BINDIR)
+ -install -c -m 644 sox.1 play.1 $(MANDIR)/man1
+
+install-lib: libst.a
+ -install -c -m 644 libst.a $(LIBDIR)
+ -install -c -m 644 libst.3 $(MANDIR)/man3
+
+clean:
+ $(RM) *~ *.o *.raw *.sf core sox libst.a
+
+tar: clean
+ $(RM) ../$(SRCDIR).tar
+ cd ..; tar cvf $(SRCDIR).tar $(SRCDIR)
--- /dev/null
+++ b/Makefile.ami
@@ -1,0 +1,143 @@
+##
+## Sound Tools Makefile for AMIGA with SAS/C 6.1
+## builds libst.lib and sox
+##
+## This must be redone to compile with DICE, GCC, etc.
+##
+## Choose the version you wish to compile with:
+## <make-tool> -f Makefile.ami (for basic version)
+## <make-tool> -f Makefile.ami CPU=030 (for 68030 version)
+## <make-tool> -f Makefile.ami FPU=881 (for 68881 FPU version)
+## <make-tool> -f Makefile.ami CPU=030 FPU=881 (for 030/881 version)
+##
+## Note: This makefile does not work with SAS's 'smake' utility, because
+## 'smake' is weak. Get yourself a real 'make' tool, such as the port of
+## 'dmake'. If you can't find one, use the commented-out section below to
+## rewrite this makefile for 'smake'.
+##
+
+FSRC = 8svx.c aiff.c au.c auto.c cdr.c cvsd.c dat.c g711.c g721.c \
+ g723_24.c g723_40.c g72x.c gsm.c hcom.c maud.c oss.c raw.c \
+ sbdsp.c sf.c smp.c sndrtool.c sunaudio.c tx16w.c voc.c wav.c wve.c
+
+ESRC = avg.c band.c chorus.c copy.c cut.c deemphas.c dyn.c echo.c echos.c \
+ flanger.c highp.c lowp.c map.c mask.c phaser.c pick.c \
+ polyphas.c rate.c resample.c reverb.c reverse.c split.c \
+ stat.c vibro.c
+
+PSRC= sox.c
+
+SOURCES = $(PSRC) $(FSRC) $(ESRC) handlers.c libst.c misc.c getopt.c util.c
+
+HEADERS = st.h libst.h sfheader.h version.h patchlvl.h
+
+TESTS = tests.sh testall.sh monkey.au monkey.voc
+
+MISC = README INSTALL TODO TIPS CHEAT CHEAT.eft Changelog sox.1 sox.txt \
+ libst.3 libst.txt play.1 Makefile.unx Makefile.dos Makefile.b30 \
+ Makefile.c70 soxeffect play rec
+
+SKEL = skel.c skeleff.c
+
+AMIGA = Makefile.ami amiga.h
+
+DOS = tests.bat testall.bat
+
+VMS = descrip.mms sound2au.com sound2sun.c sound2sun.opt \
+ sox.opt tests.com vms.lis
+
+FILES = $(MISC) $(HEADERS) $(SOURCES) $(AMIGA) $(DOS) $(VMS) \
+ $(SKEL) $(TESTS)
+
+FOBJ = 8svx.o aiff.o au.o auto.o cdr.o cvsd.o dat.o g711.o g721.o \
+ g723_24.o g723_40.o g72x.o gsm.o hcom.o maud.o oss.o raw.o \
+ sbdsp.o sf.o smp.o sndrtool.o sunaudio.o tx16w.o voc.o wav.o wve.o
+
+EOBJ = avg.o band.o chorus.o copy.o cut.o deemphas.o dyn.o echo.o echos.o \
+ flanger.o highp.o lowp.o map.o mask.o phaser.o pick.o \
+ polyphas.o rate.o resample.o reverb.o reverse.o split.o \
+ stat.o vibro.o
+
+##SOUNDLIB is defined below
+LIBOBJS = $(FOBJ) $(EOBJ) handlers.o libst.o misc.o getopt.o util.o
+
+##
+## System dependency parameters
+##
+##
+## Amiga vars for SAS 6.1.
+## Lots of funky stuff here. Unnecessary, but keeps it neat.
+## Also matches unix makefile more closely.
+##
+CC = sc DEF=__STDC__ DEF=AMIGA
+##IGNore some warnings due to lack of prototyping in SOX code
+O = IGN=85 IGN=93 IGN=100 IGN=154 IGN=161 OPTIMIZE OPTIMIZERINLINELOCAL OPTIMIZERTIME OPTIMIZERALIAS
+AR = oml
+AR_ARGS = a
+RM = delete
+MATH =
+MATH881 = MATH=68881
+CPUF =
+CPUF030 = CPU=68030
+MATHLIB = lib:scm.lib
+MATHLIB881 = lib:scm881.lib
+DEFS =
+DEFS881 = DEF=AMIGA_MC68881
+DEFS030 = DEF=AMIGA_MC68030
+##
+SOX = sox$(CPU)$(FPU)
+SOUNDLIB= libst$(CPU)$(FPU).lib
+CFLAGS += $(O) DEF=AMIGA $(DEFS$(FPU)) $(DEFS$(CPU)) $(MATH$(FPU)) $(CPUF$(CPU))
+LIBS = $(MATHLIB$(FPU)) lib:sc.lib lib:amiga.lib
+##
+
+###################################################
+##This is unnecessary if you have a serious 'make'.
+##If you don't, use it as a guide to building your
+##own makefile.
+###################################################
+##
+## 68000, no FPU
+#SOX = sox
+#SOUNDLIB= libst.lib
+#MATHLIB = lib:scm.lib
+#CFLAGS += $(O) DEF=AMIGA
+##
+## 68000, 68881 FPU
+#SOX = sox881
+#SOUNDLIB= libst881.lib
+#MATHLIB = lib:scm881.lib lib:scm.lib
+#CFLAGS += $(O) MATH=68881 DEF=AMIGA DEF=AMIGA_MC68881
+##
+## 68030, no FPU
+#SOX = sox030
+#SOUNDLIB= libst030.lib
+#MATHLIB = lib:scm.lib
+#CFLAGS += $(O) CPU=68030 DEF=AMIGA
+##
+## 68030, 68881 FPU
+#SOX = sox030881
+#SOUNDLIB= libst030881.lib
+#MATHLIB = lib:scm881.lib lib:scm.lib
+#CFLAGS += $(O) MATH=68881 CPU=68030 DEF=AMIGA DEF=AMIGA_MC68881
+
+##
+## start your engines
+##
+all: $(SOX)
+
+$(SOX): sox.o $(SOUNDLIB)
+ slink lib:c.o sox.o to $(SOX) lib $(SOUNDLIB) $(LIBS) SMALLCODE SMALLDATA STRIPDEBUG NOICONS
+
+$(SOUNDLIB): $(LIBOBJS)
+ $(AR) $(SOUNDLIB) $(AR_ARGS) $(LIBOBJS)
+
+sox.o: sox.c st.h
+
+sox.txt: sox.man
+ $(RM) sox.txt
+ nroff -man sox.man > sox.txt
+ nroff -man st.man > st.txt
+
+clean:
+ $(RM) #?.o
--- /dev/null
+++ b/Makefile.dos
@@ -1,0 +1,79 @@
+# Sound Tools Makefile - builds libst.lib and sox.exe
+#
+# Short and Sweat makefile - cbagwell@sprynet.com 9/28/98
+# With a little editing this makefile should compile under both
+# pre and post Borland 3.0.
+#
+# Also some support for MS VC based on info from Mark Morgan Lloyd
+# <markMLl.in@telemetry.co.uk> 1/24/99
+
+# Need object files to know what libst.lib depends on. All .c files
+# are compiled from default rules of make.
+
+FOBJ = 8svx.obj aiff.obj au.obj auto.obj cdr.obj cvsd.obj dat.obj \
+ g711.obj g721.obj g723_24.obj g723_40.obj g72x.obj gsm.obj \
+ hcom.obj maud.obj oss.obj raw.obj sbdsp.obj sf.obj smp.obj \
+ sndrtool.obj sunaudio.obj tx16w.obj voc.obj wav.obj wve.obj
+
+EOBJ = avg.obj band.obj chorus.obj copy.obj cut.obj deemphas.obj \
+ dyn.obj echo.obj echos.obj flanger.obj highp.obj lowp.obj \
+ map.obj mask.obj phaser.obj pick.obj polyphas.obj \
+ rate.obj resample.obj reverb.obj reverse.obj split.obj \
+ stat.obj vibro.obj
+
+LIBOBJS = $(FOBJ) $(EOBJ) handlers.obj libst.obj misc.obj getopt.obj util.obj
+
+
+# The following defines tell where compiler files are kept, not where
+# things should be installed like Unix usually specifies.
+BINDIR = d:\tc\bin
+LIBDIR = d:\tc\lib
+INCDIR = d:\tc\include
+
+#BINDIR = d:\bc\bin
+#LIBDIR = d:\bc\lib
+#INCDIR = d:\bc\include
+
+# Use the following if you don't really need to define paths.
+#BINDIR = .
+#LIBDIR = .
+#INCDIR = .
+
+
+# Standard Borland options for Huge Memory Mode (more than 64k for both
+# code and data), Word aligned, compile to Objects only, Speed and Jump
+# optimized.
+# -v is for debuging and -N is to add stack corruption detection code.
+# both add unneeded size to code.
+#
+# Pick one of the next two defines for pre/post Borland C 3.0
+CC = $(BINDIR)\tcc
+#CC = $(BINDIR)\bcc
+LDD = $(BINDIR)\tlib
+CFLAGS = -DDOS -DNEED_GETOPT -D__STDC__=1 -a -c -mh -G -O -v -N
+LFLAGS = -v -mh
+
+# MS VC needs the following. /AL uses large memory model.
+#CC = cl
+#LDD = lib
+#CFLAGS = -DDOS -D__STDC__=1 -DNEED_GETOPT -c -O /AL /Gt8192
+#LFLAGS = /AL /Gt8192
+
+.c.obj:
+ $(CC) $(CFLAGS) -I$(INCDIR) -L$(LIBDIR) $*.c
+ $(LDD) libst -$* +$*
+
+all: sox.exe
+
+sox.exe: sox.obj libst.lib
+ $(CC) $(LFLAGS) -L$(LIBDIR) sox.obj libst.lib
+
+libst.lib: $(LIBOBJS)
+
+sox.obj: sox.c st.h
+ $(CC) $(CFLAGS) -I$(INCDIR) -L$(LIBDIR) $*.c
+
+clean:
+ del *.obj
+ del sox.exe
+ del libst.lib
--- /dev/null
+++ b/Makefile.os9
@@ -1,0 +1,56 @@
+
+# Sound Tools Makefile
+# builds libst.a and sox
+# This makefile assumes Microware Ultra C
+#
+# NOTE! You have to rename 8svx.c to svx8.c
+#
+# Boisy G. Pitre (boisy@microware.com)
+
+RDIR = RELS
+CFLAGS = -ai -DOS9 -DNEED_GETOPT # use strict ANSI mode, shared libraries
+LFLAGS = $(CFLAGS) -l=/dd/lib/sys_clib.l
+CC = cc
+
+FOBJ = $(RDIR)/8svx.r $(RDIR)/aiff.r $(RDIR)/au.r $(RDIR)/auto.r \
+ $(RDIR)/cdr.r $(RDIR)/cvsd.r $(RDIR)/dat.r $(RDIR)/g711.r \
+ $(RDIR)/g721.r $(RDIR)/g723_24.r $(RDIR)/g723_40.r \
+ $(RDIR)/g72x.r $(RDIR)/gsm.r $(RDIR)/hcom.r $(RDIR)/maud.r \
+ $(RDIR)/oss.r $(RDIR)/raw.r $(RDIR)/sbdsp.r $(RDIR)/sf.r \
+ $(RDIR)/smp.r $(RDIR)/sndrtool.r $(RDIR)/sunaudio.r \
+ $(RDIR)/tx16w.r $(RDIR)/voc.r $(RDIR)/wav.r $(RDIR)/wve.r
+
+EOBJ = $(RDIR)/avg.r $(RDIR)/band.r $(RDIR)/chorus.r \
+ $(RDIR)/copy.r $(RDIR)/cut.r $(RDIR)/deemphas.r $(RDIR)/dyn.r \
+ $(RDIR)/echo.r $(RDIR)/echos.r $(RDIR)/flanger.r $(RDIR)/highp.r \
+ $(RDIR)/lowp.r $(RDIR)/map.r $(RDIR)/mask.r $(RDIR)/phaser.r \
+ $(RDIR)/pick.r $(RDIR)/polyphas.r $(RDIR)/rate.r \
+ $(RDIR)/resample.r $(RDIR)/reverb.r $(RDIR)/reverse.r \
+ $(RDIR)/split.r $(RDIR)/stat.r $(RDIR)/vibro.r
+
+
+LIBOBJS = $(FOBJ) $(EOBJ) $(RDIR)/handlers.r $(RDIR)/libst.r \
+ $(RDIR)/misc.r $(RDIR)/getopt.r $(RDIR)/util.r
+
+all: sox
+ @echo Done
+
+sox: $(RDIR)/sox.r $(LIBOBJS)
+ $(CC) -f=$@ $(RDIR)/sox.r $(LIBOBJS) $(LFLAGS)
+
+sox.r: sox.c st.h
+
+$(LIBOBJS): st.h version.h patchlvl.h
+
+# OS-9 systems need the appropriate programs
+# to make use of this section.
+man: sox.1 libst.3
+ del sox.txt
+ del libst.txt
+ nroff -man sox.1 ! col -b > sox.txt
+ nroff -man libst.3 ! col -b > libst.txt
+
+# Just guessing here
+svx8.c: 8svx.c
+ @echo Hey! You need to copy 8svx.c to svx8.c
+ # what's the cp command?
--- /dev/null
+++ b/Makefile.unx
@@ -1,0 +1,256 @@
+#
+# Sound Tools Makefile
+#
+# builds libst.a and sox
+#
+# Updated on 02/24/97 - by Chris Bagwell (cbagwell@sprynet.com)
+# Inhanced Makefile to install software and documented a little better.
+#
+# Updated on 05 May 1998 by Chris Bagwell (cbagwell@sprynet.com)
+# Made some changes for various platforms based on others sugestions
+# and made my home system (Linux) the default. ;-)
+#
+# July 19, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+# Redid makefile so that libraries could be optionally linked in.
+# Also made each specific portion of system specifics a seperate
+# line to comment/uncomment so that it will be easier to see how
+# to compiler on a wider array of systems (he says with a grin).
+#
+
+# These things are site dependant so you may want to change.
+PREFIX = /usr/local
+BINDIR = $(PREFIX)/bin
+LIBDIR = $(PREFIX)/lib
+MANDIR = $(PREFIX)/man
+
+SRCDIR = sox-12.16
+
+##############################################################################
+
+FSRC = 8svx.c aiff.c au.c auto.c cdr.c cvsd.c dat.c g711.c g721.c \
+ g723_24.c g723_40.c g72x.c gsm.c hcom.c maud.c oss.c raw.c \
+ sbdsp.c sf.c smp.c sndrtool.c sunaudio.c tx16w.c voc.c wav.c wve.c
+
+ESRC = avg.c band.c chorus.c copy.c cut.c deemphas.c dyn.c echo.c echos.c \
+ flanger.c highp.c lowp.c map.c mask.c phaser.c pick.c \
+ polyphas.c rate.c resample.c reverb.c reverse.c split.c \
+ stat.c vibro.c
+
+PSRC = sox.c
+
+SOURCES = $(PSRC) $(FSRC) $(ESRC) handlers.c libst.c misc.c util.c getopt.c
+
+##############################################################################
+
+HEADERS = st.h libst.h sfheader.h sfircam.h patchlvl.h version.h wav.h \
+ g72x.h resdefs.h resampl.h
+
+TESTS = tests.sh testall.sh monkey.au monkey.voc
+
+MISC = README INSTALL TODO TIPS CHEAT CHEAT.eft Changelog sox.1 sox.txt \
+ libst.3 libst.txt play.1 Makefile.unx Makefile.dos Makefile.b30 \
+ Makefile.c70 soxeffect play rec
+
+SKEL = skel.c skeleff.c
+
+AMIGA = Makefile.ami amiga.h
+
+DOS = tests.bat testall.bat
+
+OS9 = Makefile.os9
+
+VMS = descrip.mms sound2au.com sound2sun.c sound2sun.opt \
+ sox.opt tests.com vms.lis
+
+FILES = $(MISC) $(HEADERS) $(SOURCES) \
+ $(AMIGA) $(DOS) $(OS9) $(VMS) \
+ $(SKEL) $(TESTS)
+
+##############################################################################
+
+FOBJ = 8svx.o aiff.o au.o auto.o cdr.o cvsd.o dat.o g711.o g721.o \
+ g723_24.o g723_40.o g72x.o gsm.o hcom.o maud.o oss.o raw.o \
+ sbdsp.o sf.o smp.o sndrtool.o sunaudio.o tx16w.o voc.o wav.o wve.o
+
+EOBJ = avg.o band.o chorus.o copy.o cut.o deemphas.o dyn.o echo.o echos.o \
+ flanger.o highp.o lowp.o map.o mask.o phaser.o pick.o \
+ polyphas.o rate.o resample.o reverb.o reverse.o split.o \
+ stat.o vibro.o
+
+SOUNDLIB = libst.a
+LIBOBJS = $(FOBJ) $(EOBJ) handlers.o libst.o misc.o util.o getopt.o
+
+##############################################################################
+
+#
+# System dependency parameters
+# Find anything related to your system and uncomment.
+#
+
+# Default way to delete files.
+RM = rm -f
+
+# Chose the best compiler you got from the following:
+#
+# GCC with all warnings and debug info
+CC = gcc -g -Wall
+#
+# GCC with no special options
+# CC = gcc
+#
+# Generic compiler on your system
+# CC = cc
+#
+# EMX GCC under OS/2 seems to need the following
+# CC = gcc -Zcrtdll -Zexe
+
+# For optimized compilation, uncomment one of the following that your
+# compiler understands.
+#
+# gcc's all understand this as do lots of standard compilers. Try this one
+# first.
+# O = -O2
+
+# getopt() support is defined here. If you have a built-in
+# getopt() that is compatible with SVR5 then you don't need to
+# do anything special.
+#
+# If you don't have any getopt() function then use the following
+# define to use Sox's builtin version
+# GETOPT_DEFINES = -DNEED_GETOPT
+#
+# If your system has the more advanced version of getopt() that
+# also has its own getopt.h file (Such as the case with GNU libc 2.0)
+# then uncomment the following line. Don't uncomment anything if
+# its in stdlib.h.
+GETOPT_DEFINES = -DHAS_GETOPT_H
+
+# Uncomment the following if your system does not have a built in
+# strerror(). This includes SunOS.
+#
+# STRERR_DEFINES = -DNEED_STRERROR
+
+# Uncomment the following if your system does not have a built in
+# MEMMOVE function. Sox will attempt to use bcopy instead.
+# SunOS has this problem.
+#
+# MEMMOVE_DEFINES = -DNEED_MEMMOVE
+
+# If you have the GSM 6.10 libraries installed then uncomment the follow
+# 4 lines, and change to reflect your installation paths.
+#
+GSM_PRE_LIBS = -L/usr/local/lib
+GSM_POST_LIBS = -lgsm
+GSM_INCLUDES = -I/usr/local/include/
+GSM_DEFINES = -DHAS_GSM
+
+# For sound support on machines that include the OSS sound driver
+# (such as Linux) then uncomment the following line.
+#
+OSS_DEFINES = -DOSS_PLAYER
+
+# For sound support under SunOS and Solaris then uncomment the following line.
+#
+# SUNAUDIO_DEFINES = -DSUNAUDIO_PLAYER
+
+# For sound support on 386 AT&T Unix then uncomment the following line
+#
+# BLASTER_DEFINES = -DBLASTER
+
+# For sound support on Intel BSD-derived Unix's using Steve Haenichen's SBLAST
+# driver uncomment the following line.
+#
+# SBLAST_DEFINES = -DSBLAST
+
+# Uncomment the following lines if your compiling under DOS or Windows.
+# defines .snd to mean a DOS soundtool file (starts with SOUND)
+#
+# DOS_DEFINES = -DDOS
+# RM = del /q
+
+# Uncomment the following line if compiling under NeXT.
+# defines .snd to mean a NeXT sound format file only.
+#
+# NEXT_DEFINES = -DNeXT
+
+# Uncomment the following line if compling under MacIntosh
+# defines .snd to mean a Mac-style headerless unsigned byte
+# sample, probably at 11050 hertz. You'll have to set
+# the speed on the command line.
+# MAC_DEFINES = -DMAC
+
+# MISC DEFINES - The catch all for things that make even less sense
+# then normal under unix. If you need more than one of the following
+# MISC DEFINES remember to include them on one line so it isn't just
+# redefined.
+#
+# Testing new improved rate code. You can use the older version if ther
+# are problems.
+# MISC_DEFINES = -DUSE_OLD_RATE
+#
+# For an extra 32k memory, you can include u-law/a-law lookup
+# tables to speed compressiong/decompression of this type data.
+# MISC_DEFINES = -DFAST_ULAW_COMPRESSION -DFAST_ALAW_COMPRESSION
+
+
+##############################################################################
+
+# Library setup
+
+# How should libaries be created. Most systems can simply use the following.
+AR = ar r
+
+# How should 'ranlib' be performed. HPUX, Linux, BSD-ish, SunOS, Solaris
+RANLIB = ranlib
+
+# AT&T System V and GCC on DOS or OS/2 based systems
+# RANLIB = ar ts
+
+# Some systems don't have a ranlib that you can run. Use the following
+# for those systems.
+# RANLIB = true
+
+##############################################################################
+
+SOX_PRE_LIBS = $(GSM_PRE_LIBS)
+SOX_POST_LIBS = $(GSM_POST_LIBS) -lm
+SOX_INCLUDES = $(GSM_INCLUDES)
+SOX_DEFINES = $(GSM_DEFINES) $(OSS_DEFINES) $(SUNAUDIO_DEFINES) \
+ $(BLASTER) $(GETOPT_DEFINES) $(STRERR_DEFINES) $(MEMMOVE_DEFINES) \
+ $(NEXT_DEFINES) $(MAC_DEFINES) $(MISC_DEFINES)
+
+CFLAGS = $O $(SOX_DEFINES) $(SOX_INCLUDES)
+
+all: sox
+
+sox: sox.o $(SOUNDLIB)
+ $(CC) $(CFLAGS) -o sox sox.o $(SOUNDLIB) $(SOX_PRE_LIBS) $(SOX_POST_LIBS)
+
+$(SOUNDLIB): $(LIBOBJS)
+ $(RM) $(SOUNDLIB)
+ $(AR) $(SOUNDLIB) $(LIBOBJS)
+ $(RANLIB) $(SOUNDLIB)
+
+sox.o: sox.c st.h
+
+$(LIBOBJS): st.h version.h patchlvl.h
+
+man: sox.1 libst.3
+ $(RM) sox.txt libst.txt
+ nroff -man sox.1 | col -b > sox.txt
+ nroff -man libst.3 | col -b > libst.txt
+
+install: sox
+ -install -c -m 755 sox play rec $(BINDIR)
+ -install -c -m 644 sox.1 play.1 $(MANDIR)/man1
+
+install-lib: libst.a
+ -install -c -m 644 libst.a $(LIBDIR)
+ -install -c -m 644 libst.3 $(MANDIR)/man3
+
+clean:
+ $(RM) *~ *.o *.raw *.sf core sox libst.a
+
+tar: clean
+ $(RM) ../$(SRCDIR).tar
+ cd ..; tar cvf $(SRCDIR).tar $(SRCDIR)
--- /dev/null
+++ b/README
@@ -1,0 +1,201 @@
+ SOX: Sound eXchange
+
+
+SOX (also known as Sound eXchange) translates sound samples between different
+file formats, and optionally performs various sound effects.
+
+This release understands:
+
+ o Raw files in various binary formats
+ o Raw textual data
+ o Microsoft .WAV files
+ o PCM, u-law, a-law
+ o MS ADPCM (Read only)
+ o IMA ADPCM (Read only)
+ o MAUD files
+ o Sound Blaster .VOC files
+ o IRCAM SoundFile files
+ o SUN .au files
+ o PCM, u-law, a-law
+ o G7xx ADPCM files (read only)
+ o mutant DEC .au files
+ o Apple/SGI AIFF files
+ o CD-R (music CD format)
+ o Macintosh HCOM files
+ o Sounder files
+ o NeXT .snd files
+ o Soundtool (DOS) files
+ o Psion (palmtop) A-law files
+
+The sound effects include:
+
+ o Channel Averaging
+ o Band-pass filter
+ o Chorus effect
+ o Cut out loop samples
+ o Add an echo
+ o Add a sequence of echos
+ o Apply a flanger effect
+ o Apply a high-pass filter
+ o Apply a low-pass filter
+ o Display a list of loops in a file
+ o Add masking noise to a signal
+ o Apply a phaser effect
+ o Convert from stereo to mono
+ o Change sampling rates using several different algorithms.
+ o Apply a reverb effect
+ o Reverse the sound samples (to search for Satanic messages ;-)
+ o Convert from mono to stereo
+ o Display general stats on a sound sample
+ o Add the world-famous Fender Vibro-Champ effect
+
+Big news! Lots of new effects have been added. This includes most the
+popular "Guitar Effects" talked about in the same named FAQ available.
+
+The 'resample' and 'polyphase' effect does high-grade signal rate
+changes using real signal theory. Yes, it's very slow. There seems
+to be a small problem with aliasing with 'resample' currently.
+
+More big news! Sample loops are now supported in a few
+file formats: SMP and AIFF. WAV and VOC needs it. I don't know
+what other formats actually know about sampler notes & loops.
+(To make a loop, you need a waveform editor that knows about
+them and has special features.)
+
+History:
+
+This is the 12th release, Patchlevel 16 of the Sound Tools.
+Sox was originally written and maintained by Lance Norskog but
+unfortunetly he has stopped maintaining it since 1995. I, Chris
+Bagwell (cbagwell@sprynet.com), have started maintaining it since
+1996 to the present. Lance may take supporting it back up in the future
+but until that time I will keep pushing its development forward.
+
+Caveats:
+SOX is intended as the Swiss Army knife of sound processing tools. It
+doesn't do anything very well, but sooner or later it comes in very handy.
+SOX is really only usable day-to-day if you hide the wacky options with
+one-line shell scripts.
+
+Installing:
+Unless your using a precompiled binary version, you will need to use
+the Amiga, DOS, OS9, or Unix Makefile as appropriate to compile SOX.
+Please read the Makefile's for several options that may need to be customized
+for your setup. See the INSTALL file for more detailed instructions.
+
+Now, read TIPS, CHEAT.eft and CHEAT. These give a background on how
+SOX deals with sound files and how to convert this format
+to that format, and apply various effects with examples for the most
+popular formats.
+
+SOX uses file suffices to determine the nature of a sound sample file.
+If it finds the suffix in its list, it uses the appropriate read
+or write handler to deal with that file. You may override the suffix
+by giving a different type via the '-t type' argument. See the manual
+page for more information.
+
+SOX has an auto-detect feature that attempts to figure out
+the nature of an unmarked sound sample. It works very well.
+This is the 'auto' file format.
+
+I hope to inspire the creation of a common base of sound processing
+tools for computer multimedia work, similar to the PBM toolkit for
+image manipulation.
+
+Sound Tools may be used for any purpose. Source
+distributions must include the copyright notices. Binary
+distributions must include acknowledgements to the creators.
+Files are copyright by their respective authors.
+
+If you have bug fixes/enhancements, please send it to me as I would like
+to coordinate the releases. Please document your changes. I don't
+possess every kind of computer currently sold, and SOX is now beyond
+the phase where I can understand and test most of your contributions.
+
+The majority of SOX features and source code are contributed
+by you the user. Thank you very much for making SOX a success!
+
+ Creator:
+ Lance Norskog thinman@meer.net (inactive currently)
+
+ Mantainer:
+ Chris Bagwell cbagwell@sprynet.com
+
+ Contributors:
+ Juergen Mueller jmueller@uia.ua.ac.be
+ chorus, echo, echos, flanger, phaser, and reverb
+ effects.
+ Guido Van Rossum guido@cwi.nl
+ AU, AIFF, AUTO, HCOM, reverse,
+ many bug fixes
+ Jef Poskanzer jef@well.sf.ca.us
+ original code for u-law and delay line
+ Bill Neisius bill%solaria@hac2arpa.hac.com
+ DOS port, 8SVX, Sounder, Soundtool formats
+ Apollo fixes, stat with auto-picker
+ Rick Richardson rick@digibd.com
+ WAV and SB driver handlers, fixes
+ David Champion dgc3@midway.uchicago.edu
+ Amiga port
+ Pace Willisson pace@blitz.com
+ Fixes for ESIX
+ Leigh Smith leigh@psychokiller.dialix.oz.au
+ SMP and comment movement support.
+ AIFF Loop/MIDI support
+ David Sanderson dws@ssec.wisc.edu
+ AIX3.1 fixes
+ (Note that to my knowledge AIX on RS/6000s has
+ NO SUPPORT for playing any sort of sound file,
+ so please don't write to me any more to ask
+ "how do I play sound files on my AIX box". I
+ ported sox to AIX solely to use it to translate
+ between sound file formats.)
+ Glenn Lewis glewis@pcocd2.intel.com
+ AIFF chunking fixes
+ Brian Campbell brianc@quantum.qnx.com
+ QNX port and 16-bit fixes
+ Chris Adams gt8741@prism.gatech.edu
+ DOS port fixes
+ John Kohl jtkohl@kolvir.elcr.ca.us
+ BSD386 port, VOC stereo support
+ Ken Kubo ken@hmcvax.claremont.edu
+ VMS port, VOC stereo support
+ Frank Gadegast <phade@cs.tu-berlin.de>
+ Microsoft C 7.0 & C Borland 3.0 ports
+ David Elliot <dce@scmc.sony.com>
+ CD-R format support
+ David Sears <dns@essnj3.essnjay.com>
+ Linux support
+ Tom Littlejohn <tlit@seq1.loc.gov>
+ Raw textual data
+ Boisy G. Pitre boisy@microware.com
+ OS9 port
+ Sun Microsystems, Guido Van Rossum
+ CCITT G.711, G.721, G.723 implementation
+ Graeme Gill graeme@labtam.labtam.oz.au
+ A-LAW format, Good .WAV handling,
+ avg channel expansion
+ Allen Grider grider@hfsi.hfsi.com
+ VOC stereo mode, WAV file handling
+ Michel Fingerhut Michel.Fingerhut@ircam.fr
+ Upgrade 'sf' format to current IRCAM format.
+ Float file support.
+ Chris Knight
+ Achimedes Acorn support
+ Richard Caley R.Caley@ed.ac.uk
+ Psion WVE handler
+ Lutz Vieweg lkv@mania.RoBIN.de
+ MAUD (Amiga) file handler
+ Tim Gardner timg@tpi.com
+ Windows NT port for V7
+ Jimen Ching jiching@wiliki.eng.hawaii.edu
+ Libst porting bugs
+ Lauren Weinstein lauren@vortex.com
+ DOS porting, scripts, professional use
+ Chris Bagwell cbagwell@sprynet.com
+ OSS and Sun players, bugfixes, ADPCM support,
+ patch collection and maintance.
+ (your name could be here, too)
+ (I've probably lost a few, and several people fixed
+ the same bugs.)
+
--- /dev/null
+++ b/TIPS
@@ -1,0 +1,145 @@
+
+SOX usage:
+ sox [options] from-file-args to-file-args [ effect [effect-args]]
+
+First off: the -V option makes SOX print out its idea of
+what it is doing. -V is your friend.
+
+ sox -V from-file-args to-file-args
+
+From-file-args and to-file-args are the same.
+They are a series of options followed by a file name.
+The suffix on the file name usually is the file format type.
+The '-t xx' option overrides this and tells sox
+the the file format is 'xx'. The '-u/-s/-U' arguments
+say that the file is in unsigned, signed, or u-law format.
+The '-b/-w' arguments say that the file is in byte- or
+word-size (2 byte) samples. The '-r number' argument
+says that the sample rate of the file is 'number'.
+
+The extensions ub, uw, sb, sw, and ul correspond
+to raw data files of formats unsigned byte, unsigned
+word, signed byte, signed word, and u-law byte.
+Thus, '-t ul' is shorthand for '-t raw -U -b'.
+
+These conversions clip data and thus reduce sound quality,
+so be careful:
+
+ Word to u-law.
+ Word to byte.
+ U-law to byte.
+ Reduction in sample rate.
+
+Any reduction in the sample data rate loses information
+and adds noise. An increase in the data rate doesn't
+lose much information, but does add noise. See the
+note below on low-pass filtering.
+
+To convert U-law to something else without clipping,
+you'll have to convert it to (signed or unsigned) words,
+which will double the size of the file.
+
+AUTO files:
+The 'AUTO' file type reads an unknown file and
+attempts to discern its binary format.
+
+AIFF files:
+AIFF files come with complete headers and other
+info. They can in fact have multiple sound
+chunks and picture chunks. SOX only reads
+the first sound chunk.
+
+WAV files:
+WAVs use the RIFF format, which is Microsoft's
+needless imitation of AIFF. See above comments.
+
+AIFF and RIFF files need their own librarian
+programs; SOX can only do a small fraction of
+what they need.
+
+It's best if you can copy or store files in
+AIFF or WAV format. The sample rate and
+binary format are marked; also comments may
+be added to the file.
+
+SUN AU files:
+Most AU files you find are in 8khz 8-bit u-law format.
+This format was the first sound hardware SUN made available.
+Some of the files have correct headers; some do not.
+If the file has the header, this should convert it to
+another format:
+
+ sox file.au to-file-args
+
+If not, this reads a raw u-law 8khz file:
+
+ sox -t ul -r 8000 file.au to-file-args
+
+To convert a file to an old-style SUN .au file:
+
+ sox from-file-args -r 8000 -U -b file.au
+
+AU format can have any speed and several data sizes;
+you need to specify '-r 8000 -U -b' to force SOX to
+use the old SUN format.
+
+Mac files:
+Mac files come in .snd, .aiff, and .hcom formats,
+among others; these are the most common.
+
+SND files are in unsigned byte format with no
+header. They are either 11025, 22050, or 44100 hz.
+The speed seems to be a "resource" and doesn't
+get transported to Unix when the files are.
+Thus, you just have to know.
+
+ sox -r 11025 -t ub file.snd to-file-args
+ sox from-file-args -r 11025 -t ub file.snd
+
+PC files:
+There are several PC sound file formats. VOC is
+common; it has headers. SND and SNDR are for
+some DOS sound package; I don't know much about them.
+WAV is the official Microsoft Windows format.
+WAV has format options for compressed sound;
+SOX doesn't implement this yet.
+
+
+Effects:
+A sound effect may be applied to the sound sample
+while it is being copied from one file to another.
+Copy is the default effect; i.e. do nothing.
+Changing the sample rate requires the 'rate'
+effect. This applies a simple linear interpolation
+to the sample. This is a poor-quality sample
+changer. After doing a rate conversion,
+you should try doing a low-pass filter to throw
+away some of the induced noise. Pick a 'center'
+frequency about 85% of the lower of the two
+frequencies, or 42.5% of the lower of the
+two sample rates. (The maximum frequency
+in a sample is 1/2 of the sample rate).
+
+ sox -r 8000 file.xx -r 22050 tmp.yy
+ sox tmp.yy file.yy lowp 3400
+or:
+ sox -r 44100 file.xx -r 22050 tmp.yy
+ sox tmp.yy file.yy lowp 9592
+
+Listen to both tmp.yy and file.yy and see if
+the low-pass filter helps. Be sure to do the
+low-pass filter before clipping the data to
+a smaller binary word size. Say you have a 16-bit
+CD-quality (44100 hz) AIFF file that you want
+to convert to a Mac sound resource:
+
+ sox -r 44100 file.aiff -r 11025 tmp.sw
+ sox tmp.sw -t ub file.mac lowp 9371
+
+not:
+
+ sox -r 44100 file.aiff -r 11025 tmp.ub
+ sox tmp.ub -t ub file.mac lowp 9371
+
+because you want to do the low-pass filter while
+you still have sixteen-bit data.
--- /dev/null
+++ b/TODO
@@ -1,0 +1,87 @@
+People are encouraged to pick some of these and implement it. Send
+all patches to cbagwell@sprynet.com.
+
+ o Add support for writing ADPCM output in .wav files. It really only
+ feasible to add one version of ADPCM to output. I'm leaning towards
+ IMA since it could support streaming and be used in other formats.
+ But of course, MS is pushing very hard to make their version the
+ standard, weither inferer or not.
+
+ o Add GSM support to WAV format.
+
+ o highpass and lowpass filters don't let you specify the cut
+ of freq. Need some improvements to these filters.
+
+ o Grab latest stand alone version of resample and replace Sox's
+ outdated version.
+
+ o Find a mantainer for each supported platform. Try hard to shrink
+ the number of makefiles by having all systems compile using one
+ makefile.
+
+ o Change all code that sets up auto-swapping of bytes (-x option) to match
+ that of cdr.c driver. Current method fails on certain endian machines.
+
+ o Fix for how include files are found when fseek() is used. In most
+ configs it has to hardcode the values for things like SEEK_SET. *BAD*
+ Include files are a mess, i.e. fseek problem. Need to resort to
+ something like autoconf to really support all these platforms.
+
+ o Create a version of OSS and Sun driver that can play and record from the
+ same device in duplex.
+
+ o Internally sox can handle multiple effects on a given sound file.
+ Add support for this from the command line. Will probably need to
+ break out the MCHAN to MCHAN and VCHAN to distingish effects that
+ can handle Multiple channels and effects that can change the number
+ of resulting channels to Various values.
+
+ o Enhance sox for better interactive support. This includes updating
+ effect parameters in real time and ablity to start/stop/scan
+ file handlers in real time.
+
+ o More handlers! Everyone who adds sound hardware to a computer has
+ the urge to come up with their own file format.
+
+ o More effects! I don't know DSP at all. A Pitch Shifter is high
+ on the list.
+
+ o Loop support for all formats that know about it. WAV has
+ some support for loops ("cue-points") but no support for
+ MIDI note numbers. Someone needs to add this in.
+
+ o Comment strings. Some file formats have space for embedded comments.
+ These are currently thrown away. Printing them out, carrying them
+ forward, and an to add new ones would be handy.
+
+ o Update auto file type to include detection of .wve and .smp files.
+
+ o An effect loop for mixing mono -> stereo -> quad with sound
+ placement features: differential volume, phasing, and Doppler
+ shifting when the sound moves. Static placement would work as
+ a SOX effect loop, but dynamic placement involves some scripting
+ feature, or joystick input etc.
+
+ o This software wants to be a dataflow system with signal
+ sources, sinks, and processors. It wants to be class-based.
+ It wants to have a scripting control language.
+ It's really a shame I hate C++.
+
+ o Keep sox from using "fail" on errors. Sox was supposed to be
+ a sound library called "ST" but libraries shouldn't exit a program,
+ they should return error codes for users to handle.
+
+ o Enhance general robustness... For instance, malloc is called in
+ lots of places without checking its return value.
+
+SOX includes skeleton format files to assist you in supporting new
+formats, sound effect loops, and special-purpose programs.
+The full skeleton format, skel.c, helps you write a driver
+for a new format which has data structures. Skeleff.c is
+a starting point for writing a sound effect loop. Sox.c is
+a good starting point for new programs. (Someone finally
+did this and told me what was wrong...)
+
+In handlers.c, note that many formats set up the header and then
+use the raw driver for reading and writing.
+
--- /dev/null
+++ b/amiga.h
@@ -1,0 +1,61 @@
+#ifdef AMIGA
+
+#include <fcntl.h>
+
+#ifdef AMIGA_MC68881
+#include <m68881.h>
+#endif /* AMIGA_MC68881 */
+
+#include "patchlvl.h" /* yeah, I know it's not really a header...but why not? */
+
+/* Following is a really screwy way of incorporating compile-time info into *
+ * the binary as an Amiga version string. Unfortunately, it was the only *
+ * method I could find. --dgc, 13 Jan 93 */
+
+#define AmiVerChars1 {'$', 'V', 'E', 'R', ':', ' ', 'S', 'o', 'u', 'n', 'd', ' ', 'E', 'x', 'c', 'h', 'a', 'n', 'g', 'e', ' ',
+#define AmiVerChars2 '6', '8', '0', '3', '0',
+#define AmiVerChars3 '/',
+#define AmiVerChars4 '6', '8', '8', '8', '1',
+#define AmiVerChars5 ' ', 'P', 'a', 't', 'c', 'h', 'l', 'e', 'v', 'e', 'l',
+ ' ', '0'+(PATCHLEVEL/10), '0'+(PATCHLEVEL%10), '\0'}
+
+#ifdef AMIGA_MC68881
+#ifdef AMIGA_MC68030
+#define AmiVerChars AmiVerChars1 AmiVerChars2 AmiVerChars3 AmiVerChars4 AmiVerChars5
+#else
+#define AmiVerChars AmiVerChars1 AmiVerChars4 AmiVerChars5
+#endif /* AMIGA_MC68030 */
+#else
+#ifdef AMIGA_MC68030
+#define AmiVerChars AmiVerChars1 AmiVerChars2 AmiVerChars5
+#else
+#define AmiVerChars AmiVerChars1 AmiVerChars5
+#endif /* AMIGA_MC68030 */
+#endif /*AMIGA_MC68881*/
+
+/* if you change these strings, be sure to change the size here! */
+/* (and remember, sizeof() won't work) */
+#define AmiVerSize 46
+
+/* stdarg adjustments */
+#ifndef va_dcl
+#define va_dcl int va_alist;
+#endif /* !va_dcl*/
+
+/* BSD compat */
+#include <string.h>
+/* SAS/C does these; other might not */
+#ifndef bcopy
+#define bcopy(from, to, len) memmove(to, from, len)
+#endif
+
+/* SAS/C library code includes unlink(). *
+ * If your compiler doesn't have unlink(), *
+ * uncomment this section. */
+/*
+#ifndef unlink
+#define unlink DeleteFile
+#endif
+*/
+
+#endif /*AMIGA*/
--- /dev/null
+++ b/cut.c
@@ -1,0 +1,116 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools cut effect file.
+ *
+ * Pull loop #n from a looped sound file.
+ * Not finished, don't use it yet.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct cutstuff {
+ int which; /* Loop # to pull */
+ int where; /* current sample # */
+ ULONG start; /* first wanted sample */
+ ULONG end; /* last wanted sample + 1 */
+} *cut_t;
+
+/*
+ * Process options
+ */
+void cut_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ cut_t cut = (cut_t) effp->priv;
+
+ /* parse it */
+ cut->which = 0; /* for now */
+}
+
+/*
+ * Prepare processing.
+ */
+void cut_start(effp)
+eff_t effp;
+{
+ cut_t cut = (cut_t) effp->priv;
+ /* nothing to do */
+
+ cut->where = 0;
+ cut->start = effp->loops[0].start;
+ cut->end = effp->loops[0].start + effp->loops[0].length;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void cut_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ cut_t cut = (cut_t) effp->priv;
+ int len, done;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ if ((cut->where + len <= cut->start) ||
+ (cut->where >= cut->end)) {
+ *isamp = len;
+ *osamp = 0;
+ cut->where += len;
+ return;
+ }
+ *isamp = len; /* We will have processed all inputs */
+ if (cut->where < cut->start) {
+ /* skip */
+ ibuf += cut->start - cut->where;
+ len -= cut->start - cut->where;
+ }
+ if (cut->where + len >= cut->end) {
+ /* shorten */
+ len = cut->end - cut->where;
+ }
+ for(done = 0; done < len; done++) {
+ *obuf++ = *ibuf++;
+ }
+ *osamp = len;
+}
+
+/*
+ * Drain out remaining samples if the effect generates any.
+ */
+
+void cut_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ *osamp = 0;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * (free allocated memory, etc.)
+ */
+void cut_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+
--- /dev/null
+++ b/descrip.mms
@@ -1,0 +1,284 @@
+#
+# MMS description file for SOX/SoundTools (and Gopstein/Harris sound2sun)
+#
+# Modification History
+# 12 Dec 1992, K. S. Kubo, Created
+#
+# NOTES (todo):
+# * This does not yet provide support for VMS distribution (e.g. shar
+# target).
+# * It may be nice to link the library as a shareable image.
+# * To do this "right" this should also provide support for sounds
+# in the DDIF format... someday, maybe.
+#
+# !!!!!!!! IMPORTANT !!!!!!!!!! This file is outdated. Please refer
+# to Makefile.unx to see which source files need to be compiled
+# and update accordingly. Please send any updates to cbagwell@sprynet.com
+
+.IFDEF DEBUG
+DEBUGFLAGS = /debug/nooptimize
+LINKDBGFLAGS = /nouserlibrary/traceback/debug
+.ELSE
+DEBUGFLAGS = /nodebug/optimize
+LINKDBGFLAGS = /nouserlibrary/notraceback/nodebug
+.ENDIF
+
+CC = cc
+CFLAGS = /object=$*.OBJ$(DEBUGFLAGS)
+LINK = link
+LINKFLAGS = /executable=$*.EXE$(LINKDBGFLAGS)
+
+
+FSRC = raw.c, \
+ voc.c, \
+ au.c, \
+ sf.c, \
+ aiff.c, \
+ hcom.c, \
+ 8svx.c, \
+ sndrtool.c, \
+ wav.c, \
+ sbdsp.c, \
+ sunaduo.c, \
+ oss.c, \
+ smp.c, \
+ auto.c
+
+ESRC = copy.c, \
+ avg.c, \
+ stat.c, \
+ vibro.c, \
+ echo.c, \
+ rate.c, \
+ band.c, \
+ lowp.c, \
+ highp.c, \
+ reverse.c, \
+ dyn.c, \
+ cut.c, \
+ map.c, \
+ split.c, \
+ pick.c, \
+ mask.c, \
+ resample.c
+
+PSRC = sox.c
+
+OSRC = sound2sun.c
+
+SOURCES = $(FSRC),$(ESRC),$(PSRC), \
+ handlers.c, libst.c, misc.c, getopt.c, \
+ $(OSRC)
+
+HDRS = st.h, \
+ libst.h, \
+ sfheader.h, \
+ sfircam.h, \
+ patchlevel.h, \
+ version.h, \
+ wav.h, \
+ g72x.h,\
+ resdefs.h, \
+ resampl.h
+
+TESTS = tests.sh, \
+ testall.sh, \
+ monkey.au, \
+ monkey.voc
+
+MISC = readme., readme2., install., todo, tips, cheat, sox.1, \
+ sox.txt, libst.3, libst.txt, makefile.unx, makefile.bor, \
+ Makefile.b30, Makefile.c70, soxeffect, play, rec
+
+VMS = descrip.mms, sox.opt, vms.lis, sound2au.com, sound2sun.opt, \
+ sound2sun.c, tests.com
+
+SKEL = skel.c skeleff.c
+
+SOUNDLIB = soundtools.olb
+
+LIBMODS = \
+ $(SOUNDLIB)(raw) \
+ $(SOUNDLIB)(voc) \
+ $(SOUNDLIB)(au) \
+ $(SOUNDLIB)(sf) \
+ $(SOUNDLIB)(aiff) \
+ $(SOUNDLIB)(hcom) \
+ $(SOUNDLIB)(8svx) \
+ $(SOUNDLIB)(sndrtool) \
+ $(SOUNDLIB)(wav) \
+ $(SOUNDLIB)(sbdsp) \
+ $(SOUNDLIB)(sunaudio) \
+ $(SOUNDLIB)(oss) \
+ $(SOUNDLIB)(smp) \
+ $(SOUNDLIB)(auto) \
+ $(SOUNDLIB)(copy) \
+ $(SOUNDLIB)(avg) \
+ $(SOUNDLIB)(stat) \
+ $(SOUNDLIB)(vibro) \
+ $(SOUNDLIB)(echo) \
+ $(SOUNDLIB)(rate) \
+ $(SOUNDLIB)(band) \
+ $(SOUNDLIB)(lowp) \
+ $(SOUNDLIB)(reverse) \
+ $(SOUNDLIB)(handlers) \
+ $(SOUNDLIB)(libst) \
+ $(SOUNDLIB)(misc) \
+ $(SOUNDLIB)(getopt)
+
+.FIRST
+ @ if F$TrnLnm("VAXC$INCLUDE") .eqs. "" then define VAXC$INCLUDE sys$library
+ @ if F$TrnLnm("SYS") .eqs. "" then define SYS sys$library
+
+#
+# Actual targets
+#
+all : sox.exe sound2sun.exe
+ @ ! dummy argument
+
+clean :
+ - delete *.obj;
+ - delete *.raw;
+ - delete *.sf;
+
+depend : $(HDRS) $(SOURCES)
+ set command/replace clddir:depend
+ depend $(SOURCES)
+ ! dependencies updated
+
+sox.exe : sox.obj $(SOUNDLIB) descrip.mms sox.opt
+ $(LINK) $(LINKFLAGS) sox.obj, sox.opt/options
+
+sound2sun.exe : sound2sun.obj descrip.mms sound2sun.opt
+ $(LINK) $(LINKFLAGS) sound2sun.obj, sound2sun.opt/options
+
+$(SOUNDLIB) : $(LIBMODS)
+ ! $(SOUNDLIB) updated
+
+#DO NOT DELETE THIS LINE!
+
+raw.obj : libst.h
+raw.obj : raw.c
+raw.obj : st.h
+raw.obj : sys$library:stddef.h
+raw.obj : sys$library:stdio.h
+voc.obj : st.h
+voc.obj : voc.c
+voc.obj : sys$library:stddef.h
+voc.obj : sys$library:stdio.h
+au.obj : au.c
+au.obj : st.h
+au.obj : sys$library:stddef.h
+au.obj : sys$library:stdio.h
+sf.obj : sf.c
+sf.obj : sfheader.h
+sf.obj : st.h
+sf.obj : sys$library:stddef.h
+sf.obj : sys$library:stdio.h
+aiff.obj : aiff.c
+aiff.obj : st.h
+aiff.obj : sys$library:math.h
+aiff.obj : sys$library:stddef.h
+aiff.obj : sys$library:stdio.h
+hcom.obj : hcom.c
+hcom.obj : st.h
+hcom.obj : sys$library:stddef.h
+hcom.obj : sys$library:stdio.h
+8svx.obj : 8svx.c
+8svx.obj : st.h
+8svx.obj : sys$library:errno.h
+8svx.obj : sys$library:math.h
+8svx.obj : sys$library:perror.h
+8svx.obj : sys$library:stddef.h
+8svx.obj : sys$library:stdio.h
+8svx.obj : sys:types.h
+sndrtool.obj : sndrtool.c
+sndrtool.obj : st.h
+sndrtool.obj : sys$library:errno.h
+sndrtool.obj : sys$library:math.h
+sndrtool.obj : sys$library:perror.h
+sndrtool.obj : sys$library:stddef.h
+sndrtool.obj : sys$library:stdio.h
+wav.obj : st.h
+wav.obj : wav.c
+wav.obj : sys$library:stddef.h
+wav.obj : sys$library:stdio.h
+sbdsp.obj : sbdsp.c
+smp.obj : st.h
+smp.obj : smp.c
+smp.obj : sys$library:stddef.h
+smp.obj : sys$library:stdio.h
+smp.obj : sys$library:string.h
+auto.obj : st.h
+auto.obj : wav.c
+auto.obj : sys$library:stddef.h
+auto.obj : sys$library:stdio.h
+copy.obj : copy.c
+copy.obj : st.h
+copy.obj : sys$library:stddef.h
+copy.obj : sys$library:stdio.h
+avg.obj : avg.c
+avg.obj : st.h
+avg.obj : sys$library:stddef.h
+avg.obj : sys$library:stdio.h
+stat.obj : st.h
+stat.obj : stat.c
+stat.obj : sys$library:stddef.h
+stat.obj : sys$library:stdio.h
+vibro.obj : st.h
+vibro.obj : vibro.c
+vibro.obj : sys$library:math.h
+vibro.obj : sys$library:stddef.h
+vibro.obj : sys$library:stdio.h
+echo.obj : echo.c
+echo.obj : st.h
+echo.obj : sys$library:math.h
+echo.obj : sys$library:stddef.h
+echo.obj : sys$library:stdio.h
+rate.obj : rate.c
+rate.obj : st.h
+rate.obj : sys$library:math.h
+rate.obj : sys$library:stddef.h
+rate.obj : sys$library:stdio.h
+band.obj : band.c
+band.obj : st.h
+band.obj : sys$library:math.h
+band.obj : sys$library:stddef.h
+band.obj : sys$library:stdio.h
+lowp.obj : lowp.c
+lowp.obj : st.h
+lowp.obj : sys$library:math.h
+lowp.obj : sys$library:stddef.h
+lowp.obj : sys$library:stdio.h
+reverse.obj : reverse.c
+reverse.obj : st.h
+reverse.obj : sys$library:math.h
+reverse.obj : sys$library:stddef.h
+reverse.obj : sys$library:stdio.h
+sox.obj : sox.c
+sox.obj : st.h
+sox.obj : sys$library:errno.h
+sox.obj : sys$library:ctype.h
+sox.obj : sys$library:perror.h
+sox.obj : sys$library:stat.h
+sox.obj : sys$library:stddef.h
+sox.obj : sys$library:stdio.h
+sox.obj : sys$library:string.h
+sox.obj : sys$library:varargs.h
+sox.obj : sys:types.h
+handlers.obj : handlers.c
+handlers.obj : st.h
+handlers.obj : sys$library:stddef.h
+handlers.obj : sys$library:stdio.h
+libst.obj : libst.c
+misc.obj : misc.c
+misc.obj : st.h
+misc.obj : sys$library:stddef.h
+misc.obj : sys$library:stdio.h
+getopt.obj : getopt.c
+getopt.obj : st.h
+getopt.obj : sys$library:stddef.h
+getopt.obj : sys$library:stdio.h
+sound2sun.obj : sound2sun.c
+sound2sun.obj : sys$library:stddef.h
+sound2sun.obj : sys$library:stdio.h
--- /dev/null
+++ b/dyn.c
@@ -1,0 +1,111 @@
+#ifdef USE_DYN
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools dynamic compander effect file.
+ *
+ * Compresses or expands dynamic range, i.e. range between
+ * soft and loud sounds. U-law compression basically does this.
+ *
+ * Doesn't work. Giving up for now.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for DYN.C file */
+typedef struct dyn{
+ int rest; /* bytes remaining in current block */
+} *dyn_t;
+
+/*
+ * Process options
+ */
+void dyn_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Copy effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ */
+void dyn_start(effp)
+eff_t effp;
+{
+ /* nothing to do */
+ /* stuff data into delaying effects here */
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void dyn_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ int len, done;
+
+ LONG l;
+ double d, tmp;
+ int sign;
+
+#define NORMIT (65536.0)
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+
+ d = *ibuf++;
+ if (d == 0.0)
+ l = 0;
+ else {
+ if (d < 0.0) {
+ d *= -1.0;
+ sign = -1;
+ } else
+ sign = 1;
+ d /= NORMIT;
+ tmp = log10(d);
+ tmp = pow(8.0, tmp);
+ tmp = tmp * NORMIT;
+ l = tmp * sign;
+ }
+ *obuf++ = l;
+ }
+}
+
+/*
+ * Drain out remaining samples if the effect generates any.
+ */
+
+void dyn_drain(effp, obuf, osamp)
+LONG *obuf;
+int *osamp;
+{
+ *osamp = 0;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * (free allocated memory, etc.)
+ */
+void dyn_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+#endif /* USE_DYN */
--- /dev/null
+++ b/libst.3
@@ -1,0 +1,187 @@
+.de Sh
+.br
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp
+.if t .sp .5v
+.if n .sp
+..
+.TH ST 3 "October 15 1996"
+.SH NAME
+libst \- Sound Tools : sound sample file and effects libraries.
+.SH SYNOPSIS
+.B cc \fIfile.c\fB -o \fIfile \fBlibst.a
+.SH DESCRIPTION
+.I Sound\ Tools
+is a library of sound sample file format readers/writers
+and sound effects processors.
+.P
+Sound Tools includes skeleton C
+files to assist you in writing new formats and effects.
+The full skeleton driver, skel.c, helps you write drivers
+for a new format which has data structures.
+The simple skeleton drivers
+help you write a new driver for raw (headerless) formats, or
+for formats which just have a simple header followed by raw data.
+.P
+Most sound sample formats are fairly simple: they are just a string
+of bytes or words and are presumed to be sampled at a known data rate.
+Most of them have a short data structure at the beginning of the file.
+.SH INTERNALS
+The Sound Tools formats and effects operate on an internal buffer format
+of signed 32-bit longs.
+The data processing routines are called with buffers of these
+samples, and buffer sizes which refer to the number of samples
+processed, not the number of bytes.
+File readers translate the input samples to signed longs
+and return the number of longs read.
+For example, data in linear signed byte format is left-shifted 24 bits.
+.P
+This does cause problems in processing the data.
+For example:
+.br
+ *obuf++ = (*ibuf++ + *ibuf++)/2;
+.br
+would
+.I not
+mix down left and right channels into one monophonic channel,
+because the resulting samples would overflow 32 bits.
+Instead, the ``avg'' effects must use:
+.br
+ *obuf++ = *ibuf++/2 + *ibuf++/2;
+.br
+.P
+Stereo data is stored with the left and right speaker data in
+successive samples.
+Quadraphonic data is stored in this order:
+left front, right front, left rear, right rear.
+.SH FORMATS
+A
+.I format
+is responsible for translating between sound sample files
+and an internal buffer. The internal buffer is store in signed longs
+with a fixed sampling rate. The
+.I format
+operates from two data structures:
+a format structure, and a private structure.
+.P
+The format structure contains a list of control parameters for
+the sample: sampling rate, data size (bytes, words, floats, etc.),
+style (unsigned, signed, logarithmic), number of sound channels.
+It also contains other state information: whether the sample file
+needs to be byte-swapped, whether fseek() will work, its suffix,
+its file stream pointer, its
+.I format
+pointer, and the
+.I private
+structure for the
+.I format .
+.P
+The
+.I private
+area is just a preallocated data array for the
+.I format
+to use however it wishes.
+It should have a defined data structure
+and cast the array to that structure.
+See voc.c for the use of a private data area.
+Voc.c has to track the number of samples it
+writes and when finishing, seek back to the beginning of the file
+and write it out.
+The private area is not very large.
+The ``echo'' effect has to malloc() a much larger area for its
+delay line buffers.
+.P
+A
+.I format
+has 6 routines:
+.TP 20
+startread
+Set up the format parameters, or read in
+a data header, or do what needs to be done.
+.TP 20
+read
+Given a buffer and a length:
+read up to that many samples,
+transform them into signed long integers,
+and copy them into the buffer.
+Return the number of samples actually read.
+.TP 20
+stopread
+Do what needs to be done.
+.TP 20
+startwrite
+Set up the format parameters, or write out
+a data header, or do what needs to be done.
+.TP 20
+write
+Given a buffer and a length:
+copy that many samples out of the buffer,
+convert them from signed longs to the appropriate
+data, and write them to the file.
+If it can't write out all the samples,
+fail.
+.TP 20
+stopwrite
+Fix up any file header, or do what needs to be done.
+.SH EFFECTS
+An effects loop has one input and one output stream.
+It has 5 routines.
+.TP 20
+getopts
+is called with a character string argument list for the effect.
+.TP 20
+start
+is called with the signal parameters for the input and output
+streams.
+.TP 20
+flow
+is called with input and output data buffers,
+and (by reference) the input and output data sizes.
+It processes the input buffer into the output buffer,
+and sets the size variables to the numbers of samples
+actually processed.
+It is under no obligation to fill the output buffer.
+.TP 20
+drain
+is called after there are no more input data samples.
+If the effect wishes to generate more data samples
+it copies the generated data into a given buffer
+and returns the number of samples generated.
+If it fills the buffer, it will be called again, etc.
+The echo effect uses this to fade away.
+.TP 20
+stop
+is called when there are no more input samples to process.
+.I stop
+may generate output samples on its own.
+See echo.c for how to do this,
+and see that what it does is absolutely bogus.
+.SH COMMENTS
+Theoretically, formats can be used to manipulate several files
+inside one program. Multi-sample files, for example the download
+for a sampling keyboard, can be handled cleanly with this feature.
+.SH PORTABILITY PROBLEMS
+Many computers don't supply arithmetic shifting, so do multiplies
+and divides instead of << and >>. The compiler will do the right
+thing if the CPU supplies arithmetic shifting.
+.P
+Do all arithmetic conversions one stage at a time.
+I've had too many problems with "obviously clean" combinations.
+.P
+In general, don't worry about "efficiency".
+The sox.c base translator
+is disk-bound on any machine (other than a 8088 PC with an SMD disk
+controller).
+Just comment your code and make sure it's clean and simple.
+You'll find that DSP code is extremely painful to write as it is.
+.SH BUGS
+The HCOM format is not re-entrant; it can only be used once in a program.
+.P
+The program/library interface is pretty weak.
+There's too much ad-hoc information which a program is supposed to
+gather up.
+Sound Tools wants to be an object-oriented dataflow architecture.
--- /dev/null
+++ b/libst.c
@@ -1,0 +1,4362 @@
+/* libst.c - portable sound tools library
+*/
+
+#include "libst.h"
+
+#ifndef FAST_ULAW_CONVERSION
+
+/*
+** This routine converts from linear to ulaw.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** Joe Campbell: Department of Defense
+** 29 September 1989
+**
+** 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
+*/
+
+#undef ZEROTRAP /* turn off the trap as per the MIL-STD */
+#define uBIAS 0x84 /* define the add-in bias for 16 bit samples */
+#define uCLIP 32635
+#define ACLIP 31744
+
+unsigned char
+st_linear_to_ulaw( 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 > uCLIP ) sample = uCLIP; /* clip the magnitude */
+
+ /* Convert from 16 bit linear to ulaw. */
+ sample = sample + uBIAS;
+ 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;
+ }
+
+/*
+** This routine converts from ulaw to 16 bit linear.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** 29 September 1989
+**
+** 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
+st_ulaw_to_linear( 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;
+ }
+
+#else
+
+unsigned char ulaw_comp_table[16384] = {
+ 0xff,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfb,
+ 0xfb,0xfa,0xfa,0xf9,0xf9,0xf8,0xf8,0xf7,
+ 0xf7,0xf6,0xf6,0xf5,0xf5,0xf4,0xf4,0xf3,
+ 0xf3,0xf2,0xf2,0xf1,0xf1,0xf0,0xf0,0xef,
+ 0xef,0xef,0xef,0xee,0xee,0xee,0xee,0xed,
+ 0xed,0xed,0xed,0xec,0xec,0xec,0xec,0xeb,
+ 0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea,0xe9,
+ 0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe7,
+ 0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe6,0xe5,
+ 0xe5,0xe5,0xe5,0xe4,0xe4,0xe4,0xe4,0xe3,
+ 0xe3,0xe3,0xe3,0xe2,0xe2,0xe2,0xe2,0xe1,
+ 0xe1,0xe1,0xe1,0xe0,0xe0,0xe0,0xe0,0xdf,
+ 0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xde,
+ 0xde,0xde,0xde,0xde,0xde,0xde,0xde,0xdd,
+ 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdc,
+ 0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdb,
+ 0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xda,
+ 0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xd9,
+ 0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd8,
+ 0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd7,
+ 0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd6,
+ 0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd5,
+ 0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd4,
+ 0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd3,
+ 0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd2,
+ 0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd1,
+ 0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd0,
+ 0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xcf,
+ 0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,
+ 0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xce,
+ 0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xce,
+ 0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xcd,
+ 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
+ 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcc,
+ 0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,
+ 0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcb,
+ 0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,
+ 0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xca,
+ 0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,
+ 0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xc9,
+ 0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,
+ 0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc8,
+ 0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,
+ 0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc7,
+ 0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,
+ 0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc6,
+ 0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,
+ 0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc5,
+ 0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,
+ 0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc4,
+ 0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+ 0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc3,
+ 0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,
+ 0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc2,
+ 0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,
+ 0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc1,
+ 0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,
+ 0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc0,
+ 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,
+ 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xbf,
+ 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
+ 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
+ 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
+ 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbe,
+ 0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,
+ 0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,
+ 0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,
+ 0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbd,
+ 0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,
+ 0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,
+ 0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,
+ 0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbc,
+ 0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,
+ 0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,
+ 0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,
+ 0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbb,
+ 0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,
+ 0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,
+ 0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,
+ 0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xba,
+ 0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,
+ 0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,
+ 0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,
+ 0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xb9,
+ 0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,
+ 0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,
+ 0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,
+ 0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb8,
+ 0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,
+ 0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,
+ 0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,
+ 0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb7,
+ 0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,
+ 0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,
+ 0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,
+ 0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb6,
+ 0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,
+ 0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,
+ 0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,
+ 0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb5,
+ 0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,
+ 0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,
+ 0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,
+ 0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb4,
+ 0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
+ 0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
+ 0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
+ 0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb3,
+ 0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,
+ 0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,
+ 0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,
+ 0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb2,
+ 0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
+ 0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
+ 0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
+ 0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb1,
+ 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+ 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+ 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+ 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb0,
+ 0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,
+ 0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,
+ 0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,
+ 0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,
+ 0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+ 0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,
+ 0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,
+ 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+ 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,
+ 0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
+ 0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,
+ 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,
+ 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+ 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,
+ 0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,
+ 0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,
+ 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,
+ 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,
+ 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
+ 0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
+ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
+ 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
+ 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
+ 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,
+ 0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,
+ 0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,
+ 0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+ 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,
+ 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,
+ 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+ 0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,
+ 0x0a,0x0a,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+ 0x0b,0x0b,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,
+ 0x0c,0x0c,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,
+ 0x0d,0x0d,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
+ 0x0e,0x0e,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+ 0x0f,0x0f,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+ 0x1a,0x1a,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+ 0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
+ 0x1c,0x1c,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
+ 0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+ 0x1e,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
+ 0x2a,0x2a,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,
+ 0x2b,0x2b,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
+ 0x2c,0x2c,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+ 0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,
+ 0x2e,0x2e,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,
+ 0x2f,0x2f,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,
+ 0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,
+ 0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,
+ 0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,
+ 0x3a,0x3a,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,
+ 0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,
+ 0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,
+ 0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,
+ 0x3b,0x3b,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+ 0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+ 0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+ 0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+ 0x3c,0x3c,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,
+ 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,
+ 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,
+ 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,
+ 0x3d,0x3d,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,
+ 0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,
+ 0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,
+ 0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,
+ 0x3e,0x3e,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x40,0x40,0x41,0x41,0x41,0x41,0x41,0x41,
+ 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
+ 0x41,0x41,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x43,0x43,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x45,0x45,0x45,0x45,0x45,0x45,
+ 0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,
+ 0x45,0x45,0x46,0x46,0x46,0x46,0x46,0x46,
+ 0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,
+ 0x46,0x46,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x48,0x48,0x48,0x48,0x48,0x48,
+ 0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,
+ 0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,
+ 0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,
+ 0x49,0x49,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,
+ 0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,
+ 0x4a,0x4a,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,
+ 0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,
+ 0x4b,0x4b,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,
+ 0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,
+ 0x4c,0x4c,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+ 0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+ 0x4d,0x4d,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,
+ 0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,
+ 0x4e,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,
+ 0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,
+ 0x4f,0x4f,0x50,0x50,0x50,0x50,0x50,0x50,
+ 0x50,0x50,0x51,0x51,0x51,0x51,0x51,0x51,
+ 0x51,0x51,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x53,0x53,0x53,0x53,0x53,0x53,
+ 0x53,0x53,0x54,0x54,0x54,0x54,0x54,0x54,
+ 0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x56,0x56,0x56,0x56,0x56,0x56,
+ 0x56,0x56,0x57,0x57,0x57,0x57,0x57,0x57,
+ 0x57,0x57,0x58,0x58,0x58,0x58,0x58,0x58,
+ 0x58,0x58,0x59,0x59,0x59,0x59,0x59,0x59,
+ 0x59,0x59,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
+ 0x5a,0x5a,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
+ 0x5b,0x5b,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
+ 0x5c,0x5c,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,
+ 0x5d,0x5d,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e,
+ 0x5e,0x5e,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,
+ 0x5f,0x5f,0x60,0x60,0x60,0x60,0x61,0x61,
+ 0x61,0x61,0x62,0x62,0x62,0x62,0x63,0x63,
+ 0x63,0x63,0x64,0x64,0x64,0x64,0x65,0x65,
+ 0x65,0x65,0x66,0x66,0x66,0x66,0x67,0x67,
+ 0x67,0x67,0x68,0x68,0x68,0x68,0x69,0x69,
+ 0x69,0x69,0x6a,0x6a,0x6a,0x6a,0x6b,0x6b,
+ 0x6b,0x6b,0x6c,0x6c,0x6c,0x6c,0x6d,0x6d,
+ 0x6d,0x6d,0x6e,0x6e,0x6e,0x6e,0x6f,0x6f,
+ 0x6f,0x6f,0x70,0x70,0x71,0x71,0x72,0x72,
+ 0x73,0x73,0x74,0x74,0x75,0x75,0x76,0x76,
+ 0x77,0x77,0x78,0x78,0x79,0x79,0x7a,0x7a,
+ 0x7b,0x7b,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e};
+
+int ulaw_exp_table[256] = {
+ -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
+ -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
+ -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
+ -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
+ -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
+ -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
+ -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
+ -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
+ -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
+ -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
+ -876, -844, -812, -780, -748, -716, -684, -652,
+ -620, -588, -556, -524, -492, -460, -428, -396,
+ -372, -356, -340, -324, -308, -292, -276, -260,
+ -244, -228, -212, -196, -180, -164, -148, -132,
+ -120, -112, -104, -96, -88, -80, -72, -64,
+ -56, -48, -40, -32, -24, -16, -8, 0,
+ 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
+ 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
+ 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
+ 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
+ 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
+ 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
+ 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
+ 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
+ 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
+ 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
+ 876, 844, 812, 780, 748, 716, 684, 652,
+ 620, 588, 556, 524, 492, 460, 428, 396,
+ 372, 356, 340, 324, 308, 292, 276, 260,
+ 244, 228, 212, 196, 180, 164, 148, 132,
+ 120, 112, 104, 96, 88, 80, 72, 64,
+ 56, 48, 40, 32, 24, 16, 8, 0};
+#endif
+
+#ifndef FAST_ALAW_CONVERSION
+
+/*
+ * A-law routines by Graeme W. Gill.
+ * Date: 93/5/7
+ *
+ * References:
+ * 1) CCITT Recommendation G.711
+ *
+ * These routines were used to create the fast
+ * lookup tables.
+ */
+
+#define ACLIP 31744
+
+unsigned char
+st_linear_to_Alaw( sample )
+int sample;
+ {
+ static int exp_lut[128] = {1,1,2,2,3,3,3,3,
+ 4,4,4,4,4,4,4,4,
+ 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,
+ 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 Alawbyte;
+
+ /* Get the sample into sign-magnitude. */
+ sign = ((~sample) >> 8) & 0x80; /* set aside the sign */
+ if ( sign == 0 ) sample = -sample; /* get magnitude */
+ if ( sample > ACLIP ) sample = ACLIP; /* clip the magnitude */
+
+ /* Convert from 16 bit linear to ulaw. */
+ if (sample >= 256)
+ {
+ exponent = exp_lut[( sample >> 8 ) & 0x7F];
+ mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
+ Alawbyte = (( exponent << 4 ) | mantissa);
+ }
+ else
+ Alawbyte = (sample >> 4);
+ Alawbyte ^= (sign ^ 0x55);
+
+ return Alawbyte;
+ }
+
+int
+st_Alaw_to_linear( Alawbyte )
+unsigned char Alawbyte;
+ {
+ static int exp_lut[8] = { 0, 264, 528, 1056, 2112, 4224, 8448, 16896 };
+ int sign, exponent, mantissa, sample;
+
+ Alawbyte ^= 0x55;
+ sign = ( Alawbyte & 0x80 );
+ Alawbyte &= 0x7f; /* get magnitude */
+ if (Alawbyte >= 16)
+ {
+ exponent = (Alawbyte >> 4 ) & 0x07;
+ mantissa = Alawbyte & 0x0F;
+ sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
+ }
+ else
+ sample = (Alawbyte << 4) + 8;
+ if ( sign == 0 ) sample = -sample;
+
+ return sample;
+ }
+
+#else
+
+unsigned char Alaw_comp_table[16384] = {
+ 0xD5,0xD5,0xD5,0xD5,0xD4,0xD4,0xD4,0xD4,
+ 0xD7,0xD7,0xD7,0xD7,0xD6,0xD6,0xD6,0xD6,
+ 0xD1,0xD1,0xD1,0xD1,0xD0,0xD0,0xD0,0xD0,
+ 0xD3,0xD3,0xD3,0xD3,0xD2,0xD2,0xD2,0xD2,
+ 0xDD,0xDD,0xDD,0xDD,0xDC,0xDC,0xDC,0xDC,
+ 0xDF,0xDF,0xDF,0xDF,0xDE,0xDE,0xDE,0xDE,
+ 0xD9,0xD9,0xD9,0xD9,0xD8,0xD8,0xD8,0xD8,
+ 0xDB,0xDB,0xDB,0xDB,0xDA,0xDA,0xDA,0xDA,
+ 0xC5,0xC5,0xC5,0xC5,0xC4,0xC4,0xC4,0xC4,
+ 0xC7,0xC7,0xC7,0xC7,0xC6,0xC6,0xC6,0xC6,
+ 0xC1,0xC1,0xC1,0xC1,0xC0,0xC0,0xC0,0xC0,
+ 0xC3,0xC3,0xC3,0xC3,0xC2,0xC2,0xC2,0xC2,
+ 0xCD,0xCD,0xCD,0xCD,0xCC,0xCC,0xCC,0xCC,
+ 0xCF,0xCF,0xCF,0xCF,0xCE,0xCE,0xCE,0xCE,
+ 0xC9,0xC9,0xC9,0xC9,0xC8,0xC8,0xC8,0xC8,
+ 0xCB,0xCB,0xCB,0xCB,0xCA,0xCA,0xCA,0xCA,
+ 0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,
+ 0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,
+ 0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,
+ 0xF6,0xF6,0xF6,0xF6,0xF6,0xF6,0xF6,0xF6,
+ 0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+ 0xF3,0xF3,0xF3,0xF3,0xF3,0xF3,0xF3,0xF3,
+ 0xF2,0xF2,0xF2,0xF2,0xF2,0xF2,0xF2,0xF2,
+ 0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,
+ 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,
+ 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,
+ 0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,
+ 0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,
+ 0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,
+ 0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,0xE5,
+ 0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,
+ 0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,0xE4,
+ 0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,
+ 0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,
+ 0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,
+ 0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,0xE6,
+ 0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,
+ 0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
+ 0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,
+ 0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,
+ 0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,
+ 0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,0xE2,
+ 0xED,0xED,0xED,0xED,0xED,0xED,0xED,0xED,
+ 0xED,0xED,0xED,0xED,0xED,0xED,0xED,0xED,
+ 0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,
+ 0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,0xEC,
+ 0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,
+ 0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,
+ 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,
+ 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,
+ 0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,
+ 0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,0xE9,
+ 0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,
+ 0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,0xE8,
+ 0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,
+ 0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,0xEB,
+ 0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,
+ 0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
+ 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,
+ 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,
+ 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,
+ 0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,
+ 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,
+ 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,
+ 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,
+ 0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,
+ 0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,
+ 0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,
+ 0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,
+ 0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,0x9F,
+ 0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,
+ 0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,
+ 0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,
+ 0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,0x9E,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
+ 0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,
+ 0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,
+ 0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,
+ 0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,0x9B,
+ 0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,
+ 0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,
+ 0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,
+ 0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,0x9A,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,0x8D,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,0x8F,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,0x8E,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,0x8B,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,0xB5,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,0xB4,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,0xB7,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,0xB6,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,0xB1,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,0xB0,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,0xB3,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,0xB2,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,0xBC,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,0xBE,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,0xB9,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,0xB8,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,0xBA,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,0xA7,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,0xAD,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,0xAF,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,0xAE,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,0xAB,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+ 0x2A,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,0x2B,
+ 0x2B,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
+ 0x29,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
+ 0x2E,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,0x2C,
+ 0x2C,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
+ 0x2D,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+ 0x21,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,
+ 0x26,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+ 0x27,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
+ 0x25,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,
+ 0x3A,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,
+ 0x3B,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+ 0x39,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,
+ 0x3E,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x3F,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,
+ 0x3D,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x30,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,
+ 0x31,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x36,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,
+ 0x37,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
+ 0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+ 0x0A,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x08,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+ 0x09,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+ 0x0E,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+ 0x0C,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+ 0x0D,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+ 0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+ 0x07,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+ 0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+ 0x05,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,
+ 0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,
+ 0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,
+ 0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,
+ 0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x18,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+ 0x19,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,
+ 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,
+ 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,
+ 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,
+ 0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
+ 0x1F,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,
+ 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,
+ 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,
+ 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,
+ 0x1C,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,
+ 0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,
+ 0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,
+ 0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,
+ 0x1D,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+ 0x12,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+ 0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+ 0x14,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,
+ 0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,0x6A,
+ 0x6A,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,
+ 0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,
+ 0x6B,0x68,0x68,0x68,0x68,0x68,0x68,0x68,
+ 0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68,
+ 0x68,0x69,0x69,0x69,0x69,0x69,0x69,0x69,
+ 0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,
+ 0x69,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,
+ 0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,0x6E,
+ 0x6E,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,
+ 0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,0x6F,
+ 0x6F,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,
+ 0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,
+ 0x6C,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,
+ 0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,0x6D,
+ 0x6D,0x62,0x62,0x62,0x62,0x62,0x62,0x62,
+ 0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x62,
+ 0x62,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x63,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x61,0x61,0x61,0x61,0x61,0x61,0x61,
+ 0x61,0x61,0x61,0x61,0x61,0x61,0x61,0x61,
+ 0x61,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
+ 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
+ 0x66,0x67,0x67,0x67,0x67,0x67,0x67,0x67,
+ 0x67,0x67,0x67,0x67,0x67,0x67,0x67,0x67,
+ 0x67,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+ 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+ 0x64,0x65,0x65,0x65,0x65,0x65,0x65,0x65,
+ 0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,
+ 0x65,0x7A,0x7A,0x7A,0x7A,0x7A,0x7A,0x7A,
+ 0x7A,0x7B,0x7B,0x7B,0x7B,0x7B,0x7B,0x7B,
+ 0x7B,0x78,0x78,0x78,0x78,0x78,0x78,0x78,
+ 0x78,0x79,0x79,0x79,0x79,0x79,0x79,0x79,
+ 0x79,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,
+ 0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
+ 0x7F,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,
+ 0x7C,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,
+ 0x7D,0x72,0x72,0x72,0x72,0x72,0x72,0x72,
+ 0x72,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x73,0x70,0x70,0x70,0x70,0x70,0x70,0x70,
+ 0x70,0x71,0x71,0x71,0x71,0x71,0x71,0x71,
+ 0x71,0x76,0x76,0x76,0x76,0x76,0x76,0x76,
+ 0x76,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
+ 0x77,0x74,0x74,0x74,0x74,0x74,0x74,0x74,
+ 0x74,0x75,0x75,0x75,0x75,0x75,0x75,0x75,
+ 0x75,0x4A,0x4A,0x4A,0x4A,0x4B,0x4B,0x4B,
+ 0x4B,0x48,0x48,0x48,0x48,0x49,0x49,0x49,
+ 0x49,0x4E,0x4E,0x4E,0x4E,0x4F,0x4F,0x4F,
+ 0x4F,0x4C,0x4C,0x4C,0x4C,0x4D,0x4D,0x4D,
+ 0x4D,0x42,0x42,0x42,0x42,0x43,0x43,0x43,
+ 0x43,0x40,0x40,0x40,0x40,0x41,0x41,0x41,
+ 0x41,0x46,0x46,0x46,0x46,0x47,0x47,0x47,
+ 0x47,0x44,0x44,0x44,0x44,0x45,0x45,0x45,
+ 0x45,0x5A,0x5A,0x5A,0x5A,0x5B,0x5B,0x5B,
+ 0x5B,0x58,0x58,0x58,0x58,0x59,0x59,0x59,
+ 0x59,0x5E,0x5E,0x5E,0x5E,0x5F,0x5F,0x5F,
+ 0x5F,0x5C,0x5C,0x5C,0x5C,0x5D,0x5D,0x5D,
+ 0x5D,0x52,0x52,0x52,0x52,0x53,0x53,0x53,
+ 0x53,0x50,0x50,0x50,0x50,0x51,0x51,0x51,
+ 0x51,0x56,0x56,0x56,0x56,0x57,0x57,0x57,
+ 0x57,0x54,0x54,0x54,0x54,0x55,0x55,0x55};
+
+int Alaw_exp_table[256] = {
+ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
+ -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
+ -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
+ -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
+ -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,
+ -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,
+ -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,
+ -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,
+ -344, -328, -376, -360, -280, -264, -312, -296,
+ -472, -456, -504, -488, -408, -392, -440, -424,
+ -88, -72, -120, -104, -24, -8, -56, -40,
+ -216, -200, -248, -232, -152, -136, -184, -168,
+ -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
+ -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
+ -688, -656, -752, -720, -560, -528, -624, -592,
+ -944, -912, -1008, -976, -816, -784, -880, -848,
+ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
+ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
+ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
+ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
+ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
+ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
+ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
+ 344, 328, 376, 360, 280, 264, 312, 296,
+ 472, 456, 504, 488, 408, 392, 440, 424,
+ 88, 72, 120, 104, 24, 8, 56, 40,
+ 216, 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
+ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
+ 688, 656, 752, 720, 560, 528, 624, 592,
+ 944, 912, 1008, 976, 816, 784, 880, 848};
+
+#endif
+
--- /dev/null
+++ b/libst.h
@@ -1,0 +1,41 @@
+/* libst.h - include file for portable sound tools library
+**
+** Copyright (C) 1989 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation. This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#define MINLIN -32768
+#define MAXLIN 32767
+#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; else if ( x > MAXLIN ) x = MAXLIN; } while ( 0 )
+
+/* These do not round data. Caller must round appropriately. */
+
+#ifdef FAST_ULAW_CONVERSION
+extern int ulaw_exp_table[256];
+extern unsigned char ulaw_comp_table[16384];
+#define st_ulaw_to_linear(ulawbyte) ulaw_exp_table[ulawbyte]
+#define st_linear_to_ulaw(linearword) ulaw_comp_table[(linearword / 4) & 0x3fff]
+#else
+unsigned char st_linear_to_ulaw( /* int sample */ );
+int st_ulaw_to_linear( /* unsigned char ulawbyte */ );
+#endif
+
+#ifdef FAST_ALAW_CONVERSION
+extern int Alaw_exp_table[256];
+extern unsigned char Alaw_comp_table[16384];
+#define st_Alaw_to_linear(Alawbyte) Alaw_exp_table[Alawbyte]
+#define st_linear_to_Alaw(linearword) Alaw_comp_table[(linearword / 4) & 0x3fff]
+#else
+unsigned char st_linear_to_Alaw( /* int sample */ );
+int st_Alaw_to_linear( /* unsigned char ulawbyte */ );
+#endif
+
+#ifdef USG
+#define setbuffer(x,y,z)
+#endif
--- /dev/null
+++ b/libst.txt
@@ -1,0 +1,264 @@
+
+
+
+ST(3) ST(3)
+
+
+NAME
+ libst - Sound Tools : sound sample file and effects
+ libraries.
+
+SYNOPSIS
+ cc file.c -o file libst.a
+
+DESCRIPTION
+ Sound Tools is a library of sound sample file format read-
+ ers/writers and sound effects processors.
+
+ Sound Tools includes skeleton C files to assist you in
+ writing new formats and effects. The full skeleton
+ driver, skel.c, helps you write drivers for a new format
+ which has data structures. The simple skeleton drivers
+ help you write a new driver for raw (headerless) formats,
+ or for formats which just have a simple header followed by
+ raw data.
+
+ Most sound sample formats are fairly simple: they are just
+ a string of bytes or words and are presumed to be sampled
+ at a known data rate. Most of them have a short data
+ structure at the beginning of the file.
+
+INTERNALS
+ The Sound Tools formats and effects operate on an internal
+ buffer format of signed 32-bit longs. The data processing
+ routines are called with buffers of these samples, and
+ buffer sizes which refer to the number of samples pro-
+ cessed, not the number of bytes. File readers translate
+ the input samples to signed longs and return the number of
+ longs read. For example, data in linear signed byte for-
+ mat is left-shifted 24 bits.
+
+ This does cause problems in processing the data. For
+ example:
+ *obuf++ = (*ibuf++ + *ibuf++)/2;
+ would not mix down left and right channels into one mono-
+ phonic channel, because the resulting samples would over-
+ flow 32 bits. Instead, the ``avg'' effects must use:
+ *obuf++ = *ibuf++/2 + *ibuf++/2;
+
+ Stereo data is stored with the left and right speaker data
+ in successive samples. Quadraphonic data is stored in
+ this order: left front, right front, left rear, right
+ rear.
+
+FORMATS
+ A format is responsible for translating between sound sam-
+ ple files and an internal buffer. The internal buffer is
+ store in signed longs with a fixed sampling rate. The
+ format operates from two data structures: a format struc-
+ ture, and a private structure.
+
+
+
+
+ October 15 1996 1
+
+
+
+
+
+ST(3) ST(3)
+
+
+ The format structure contains a list of control parameters
+ for the sample: sampling rate, data size (bytes, words,
+ floats, etc.), style (unsigned, signed, logarithmic), num-
+ ber of sound channels. It also contains other state
+ information: whether the sample file needs to be byte-
+ swapped, whether fseek() will work, its suffix, its file
+ stream pointer, its format pointer, and the private struc-
+ ture for the format .
+
+ The private area is just a preallocated data array for the
+ format to use however it wishes. It should have a defined
+ data structure and cast the array to that structure. See
+ voc.c for the use of a private data area. Voc.c has to
+ track the number of samples it writes and when finishing,
+ seek back to the beginning of the file and write it out.
+ The private area is not very large. The ``echo'' effect
+ has to malloc() a much larger area for its delay line
+ buffers.
+
+ A format has 6 routines:
+
+ startread Set up the format parameters, or read
+ in a data header, or do what needs to
+ be done.
+
+ read Given a buffer and a length: read up
+ to that many samples, transform them
+ into signed long integers, and copy
+ them into the buffer. Return the num-
+ ber of samples actually read.
+
+ stopread Do what needs to be done.
+
+ startwrite Set up the format parameters, or write
+ out a data header, or do what needs to
+ be done.
+
+ write Given a buffer and a length: copy that
+ many samples out of the buffer, con-
+ vert them from signed longs to the
+ appropriate data, and write them to
+ the file. If it can't write out all
+ the samples, fail.
+
+ stopwrite Fix up any file header, or do what
+ needs to be done.
+
+EFFECTS
+ An effects loop has one input and one output stream. It
+ has 5 routines.
+
+ getopts is called with a character string
+ argument list for the effect.
+
+
+
+
+ October 15 1996 2
+
+
+
+
+
+ST(3) ST(3)
+
+
+ start is called with the signal parameters
+ for the input and output streams.
+
+ flow is called with input and output data
+ buffers, and (by reference) the input
+ and output data sizes. It processes
+ the input buffer into the output
+ buffer, and sets the size variables to
+ the numbers of samples actually pro-
+ cessed. It is under no obligation to
+ fill the output buffer.
+
+ drain is called after there are no more
+ input data samples. If the effect
+ wishes to generate more data samples
+ it copies the generated data into a
+ given buffer and returns the number of
+ samples generated. If it fills the
+ buffer, it will be called again, etc.
+ The echo effect uses this to fade
+ away.
+
+ stop is called when there are no more input
+ samples to process. stop may generate
+ output samples on its own. See echo.c
+ for how to do this, and see that what
+ it does is absolutely bogus.
+
+COMMENTS
+ Theoretically, formats can be used to manipulate several
+ files inside one program. Multi-sample files, for example
+ the download for a sampling keyboard, can be handled
+ cleanly with this feature.
+
+PORTABILITY PROBLEMS
+ Many computers don't supply arithmetic shifting, so do
+ multiplies and divides instead of << and >>. The compiler
+ will do the right thing if the CPU supplies arithmetic
+ shifting.
+
+ Do all arithmetic conversions one stage at a time. I've
+ had too many problems with "obviously clean" combinations.
+
+ In general, don't worry about "efficiency". The sox.c
+ base translator is disk-bound on any machine (other than a
+ 8088 PC with an SMD disk controller). Just comment your
+ code and make sure it's clean and simple. You'll find
+ that DSP code is extremely painful to write as it is.
+
+BUGS
+ The HCOM format is not re-entrant; it can only be used
+ once in a program.
+
+ The program/library interface is pretty weak. There's too
+
+
+
+ October 15 1996 3
+
+
+
+
+
+ST(3) ST(3)
+
+
+ much ad-hoc information which a program is supposed to
+ gather up. Sound Tools wants to be an object-oriented
+ dataflow architecture.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ October 15 1996 4
+
+
binary files /dev/null b/monkey.au differ
binary files /dev/null b/monkey.voc differ
--- /dev/null
+++ b/patchlvl.h
@@ -1,0 +1,1 @@
+#define PATCHLEVEL 16
--- /dev/null
+++ b/pick.c
@@ -1,0 +1,139 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * "pick" effect by Lauren Weinstein (lauren@vortex.com); 2/94
+ * Creates a 1 channel file by selecting a single channel from
+ * a 2 or 4 channel file. Does not currently allow creating a 2 channel
+ * file by selecting 2 channels from a 4 channel file.
+ */
+
+#include "st.h"
+#include "libst.h"
+
+/* Private data for SKEL file */
+typedef struct pickstuff {
+ int chan; /* selected channel */
+} *pick_t;
+
+/* channel names are offset by 1 from actual channel byte array offsets */
+#define CHAN_1 0
+#define CHAN_2 1
+#define CHAN_3 2
+#define CHAN_4 3
+
+/*
+ * Process options
+ */
+void
+pick_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ pick_t pick = (pick_t) effp->priv;
+
+ if (n == 1 && argv[0][0] == '-') { /* must specify channel to pick */
+ switch (argv[0][1]) {
+ case 'l':
+ pick->chan = CHAN_1;
+ return;
+ case 'r':
+ pick->chan = CHAN_2;
+ return;
+ case '1':
+ pick->chan = CHAN_1;
+ return;
+ case '2':
+ pick->chan = CHAN_2;
+ return;
+ case '3':
+ pick->chan = CHAN_3;
+ return;
+ case '4':
+ pick->chan = CHAN_4;
+ return;
+ }
+ }
+ pick->chan = -1; /* invalid option */
+}
+
+
+/*
+ * Start processing. Final option checking is done here since
+ * error/usage messages will vary based on the number of input/output
+ * channels selected, and that info is not available in pick_getopts()
+ * above.
+ */
+void
+pick_start(effp)
+eff_t effp;
+{
+ pick_t pick = (pick_t) effp->priv;
+
+ if (effp->outinfo.channels != 1) /* must be one output channel */
+ fail("Can't pick with other than 1 output channel.");
+ if (effp->ininfo.channels != 2 && effp->ininfo.channels != 4)
+ fail("Can't pick with other than 2 or 4 input channels.");
+ if (effp->ininfo.channels == 2) { /* check for valid option */
+ if (pick->chan == -1 || pick->chan == CHAN_3 || pick->chan == CHAN_4)
+ fail("Must specify channel to pick: '-l', '-r', '-1', or '-2'.");
+ }
+ else /* must be 4 channels; check for valid option */
+ if (pick->chan == -1)
+ fail("Must specify channel to pick: '-1', '-2', '-3', or '-4'.");
+}
+
+/*
+ * Process signed long samples from ibuf to obuf,
+ * isamp or osamp samples, whichever is smaller,
+ * while picking appropriate channels.
+ */
+
+void pick_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ pick_t pick = (pick_t) effp->priv;
+ int len, done;
+
+ switch (effp->ininfo.channels) {
+ case 2:
+ len = ((*isamp/2 > *osamp) ? *osamp : *isamp/2);
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[pick->chan];
+ ibuf += 2;
+ }
+ *isamp = len * 2;
+ *osamp = len;
+ break;
+ case 4:
+ len = ((*isamp/4 > *osamp) ? *osamp : *isamp/4);
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[pick->chan];
+ ibuf += 4;
+ }
+ *isamp = len * 4;
+ *osamp = len;
+ break;
+ }
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void pick_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
--- /dev/null
+++ b/play
@@ -1,0 +1,141 @@
+#!/bin/sh
+# Shell script to play sound files to unix style sound devices.
+# Should auto detect most supported systems and play the file for you.
+#
+# Originally developed by Chris Bagwell (cbagwell@sprynet.com)
+#
+# TODO: Put each set of fopts and filenames on an array and then
+# play each filename back with the given effect.h
+#
+# Change History:
+#
+# June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+#
+# Kjetil Torgrim Homme <kjetilho@ifi.uio.no> sent in a neat patch to
+# attempt an educated guess on how to play sound on sun hardware.
+# There is probably a better way to do it in the actual software though.
+#
+# Use the parsed out volume flag to have sox change the volume. Yes, its
+# better to use the audio devices hardware mixer to adjust volume but some
+# way is better then no way. Its still parsed seperately so people may
+# optionally pass the parameter to a mixer.
+#
+# September 7, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+#
+# Updated usage checking a little more so that only one filename can
+# be given.
+#
+# January 9, 1999 - Chris Bagwell (cbagwell@sprynet.com)
+#
+# Quoted $filename so that files with spaces in their names can
+# be given.
+# Arnim Rupp patch file to work with multiple sound devices via
+# command line option.
+#
+
+# Set up path to sox so that it can find it if user's path doesn't already
+# include it.
+PATH=$PATH:/usr/local/bin
+export PATH
+
+help()
+{
+ echo "play v1.5 - front end to Sox"
+ echo ""
+ echo "Usage: play [ fopts ] infile [effects]"
+ echo
+ echo "fopts: -c channels -d device -h -r rate -t type -v volume -s/-u/-U/-A -b/-w/-l/-f/-d/-D -x"
+ echo
+ echo "effects: avg/band/chorus/copy/cut/deemph/echo/echos/flanger/highp/lowp/map/mask/phaser/pick/polyphase/rate/resample/reverb/reverse/split/stat/vibro"
+ echo ""
+ echo "See sox man page for more info on required effects options."
+}
+
+if [ "$1" = "" ] ; then
+ help; exit 1;
+fi
+
+while [ $# -ne 0 ] # loop over arguments
+do case $1 in
+ avg|band|chorus|copy|cut|echo|echos|flanger|highp|lowp|map|mask|phaser|pick|pred|rate|resample|reverb|reverse|split|stat|vibro)
+ effects="$@"
+ break
+ ;;
+ -c)
+ shift
+ fopts="$fopts -c $1"
+ ;;
+ -d)
+ shift
+ device="$1"
+ ;;
+ -h)
+ help;
+ exit 1;
+ ;;
+ -r)
+ shift
+ fopts="$fopts -r $1"
+ ;;
+ -t)
+ shift
+ fopts="$fopts -t $1"
+ ;;
+ -v)
+ shift
+ volume="-v $1"
+ ;;
+ -)
+ filename="-"
+ ;;
+ -*)
+ fopts="$fopts $1"
+ ;;
+ *)
+ if [ "$filename" = "" ]; then
+ filename="$1"
+ else
+ echo "Filename already give. Ingoring extra name: $1"
+ fi
+ ;;
+ esac
+ shift
+done
+
+arch=`uname -s`
+
+if [ "$arch" = "SunOS" ]; then
+
+ if [ "$device" = "" ]; then
+ device="/dev/audio"
+ fi
+
+ case `arch -k` in
+ sun4|sun4c|sun4d)
+ # Use below for older Sun audio hardware
+ sox $volume $fopts "$filename" -t sunau -U -c 1 $device $effects
+ ;;
+
+ *)
+ # Use below for newer Sun audio hardware that supports stereo linear
+ sox $volume $fopts "$filename" -t sunau -w -s $device $effects
+ ;;
+
+ esac
+
+else
+ if [ "$arch" = "Linux" ]; then
+
+ if [ "$device" = "" ]; then
+ device="/dev/dsp"
+ fi
+
+# Possible way to set volume
+# if [ "$volume" != "" ] ; then
+# mixer $volume
+# fi
+
+ # Best to always use highest quality output for sound.
+ sox $volume $fopts "$filename" -t ossdsp -w -s $device $effects
+ fi
+fi
--- /dev/null
+++ b/play.1
@@ -1,0 +1,49 @@
+.TH NAME SECTION
+.\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection
+.\" other parms are allowed: see man(7), man(1)
+.SH NAME
+play \- play any sound file
+.SH SYNOPSIS
+.B play
+.I "[fopts] infile [effect]"
+.SH "DESCRIPTION"
+This manual page documents briefly the
+.BR play
+command.
+.PP
+.B play
+is a program that allows you to play different types of sound files. It is
+a frontend to the more general sox package. Normally the play command
+will detect the type and other parameters of the soundfile. If it can't do
+so, the parametes can be changed through options.
+.SH OPTIONS
+A summary of common options are included below.
+For a complete description for options and supported formats, see
+the
+.B sox(1)
+man page.
+.TP
+.B \-h
+Show summary of options.
+.TP
+.B \-r rate
+Define the samplerate of the playback.
+.TP
+.B \-v volume
+Change the playback Volume.
+.TP
+.B \-c channels
+Define the number of channels of the file.
+.TP
+.B \-d device
+Specify a different device to play the sound file to.
+.TP
+Other options and a description of effects are described in the sox man page.
+
+.SH "SEE ALSO"
+
+ sox(1)
+
+.SH AUTHOR
+This manual page was written by Guenter Geiger <geiger@iem.mhsg.ac.at>,
+for the Debian GNU/Linux system.
--- /dev/null
+++ b/rec
@@ -1,0 +1,138 @@
+#!/bin/sh
+# Shell script to record sound files from unix style sound devices.
+# Should auto detect most supported systems and record the file for you.
+#
+# Originally developed by Chris Bagwell (cbagwell@sprynet.com)
+#
+# Change History:
+#
+# June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+# Kjetil Torgrim Homme <kjetilho@ifi.uio.no> sent in a neat patch to
+# attempt an educated guess on how to rec sound on sun hardware.
+# There is probably a better way to do it in the actual software though.
+#
+# Use the parsed out volume flag to have sox change the volume. Yes, its
+# better to use the audio devices hardware mixer to adjust volume but some
+# way is better then no way. Its still parsed seperately so people may
+# optionally pass the parameter to a mixer.
+#
+# September 7, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+#
+# Updated usage checking a little more so that only one filename can
+# be given.
+#
+# January 9, 1999 - Chris Bagwell (cbagwell@sprynet.com)
+#
+# Quoted $filename so that files with spaces in their names can
+# be given.
+# Arnim Rupp patch file to work with multiple sound devices via
+# command line option.
+#
+
+# Set up path so that it can find Sox if user's path doesn't already
+# include it.
+PATH=$PATH:/usr/local/bin
+export PATH
+
+help()
+{
+ echo "rec v1.5 - front end to Sox"
+ echo ""
+ echo "Usage: rec [ fopts ] outfile [effects]"
+ echo
+ echo "fopts: -c channels -d device -h -r rate -t type -v volume -s/-u/-U/-A -b/-w/-l/-f/-d/-D -x"
+ echo
+ echo "effects: avg/band/chorus/copy/cut/deemph/echo/echos/flanger/highp/lowp/map/mask/phaser/pick/polyphase/rate/resample/reverb/reverse/split/stat/vibro"
+ echo ""
+ echo "See sox man page for more info on required effects options."
+}
+
+if [ "$1" = "" ] ; then
+ help; exit 1;
+fi
+
+while [ $# -ne 0 ] # loop over arguments
+do case $1 in
+ avg|band|chorus|copy|cut|echo|echos|flanger|highp|lowp|map|mask|phaser|pick|pred|rate|resample|reverb|reverse|split|stat|vibro)
+ effects="$@"
+ break
+ ;;
+ -c)
+ shift
+ fopts="$fopts -c $1"
+ ;;
+ -d)
+ shift
+ device="$1"
+ ;;
+ -h)
+ help;
+ exit 1;
+ ;;
+ -r)
+ shift
+ fopts="$fopts -r $1"
+ ;;
+ -t)
+ shift
+ fopts="$fopts -t $1"
+ ;;
+ -v)
+ shift
+ volume="-v $1"
+ ;;
+ -)
+ filename="-"
+ ;;
+ -*)
+ fopts="$fopts $1"
+ ;;
+ *)
+ if [ "$filename" = "" ]; then
+ filename="$1"
+ else
+ echo "Filename already give. Ingoring extra name: $1"
+ fi
+ ;;
+ esac
+ shift
+done
+
+arch=`uname -s`
+
+echo "Send break (control-c) to end recording"
+
+if [ "$arch" = "SunOS" ]; then
+
+ if [ "$device" = "" ]; then
+ device="/dev/audio"
+ fi
+
+ case `arch -k` in
+ sun4|sun4c|sun4d)
+ # Use below for older Sun audio hardware
+ sox $volume -t sunau -U -c 1 $device $fopts "$filename" $effects
+ ;;
+
+ *)
+ # Use below for newer Sun audio hardware that supports stereo linear
+ sox $volume -t sunau -w -s $device $fopts "$filename" $effects
+ ;;
+
+ esac
+
+else
+ if [ "$arch" = "Linux" ]; then
+
+ if [ "$device" = "" ]; then
+ device="/dev/dsp"
+ fi
+
+# Possible way to set volume
+# if [ "$volume" != "" ] ; then
+# mixer $volume
+# fi
+
+ sox $volume -t ossdsp $device $fopts "$filename" $effects
+ fi
+fi
--- /dev/null
+++ b/resdefs.h
@@ -1,0 +1,39 @@
+
+/*
+ * FILE: stdefs.h
+ * BY: Christopher Lee Fraley
+ * DESC: Defines standard stuff for inclusion in C programs.
+ * DATE: 6-JUN-88
+ * VERS: 1.0 (6-JUN-88, 2:00pm)
+ */
+
+
+#define TRUE 1
+#define FALSE 0
+
+/* Some files include both this file and math.h which will most
+ * likely already have PI defined.
+ */
+#ifndef PI
+#define PI (3.14159265358979232846)
+#endif
+#ifndef PI2
+#define PI2 (6.28318530717958465692)
+#endif
+#define D2R (0.01745329348) /* (2*pi)/360 */
+#define R2D (57.29577951) /* 360/(2*pi) */
+
+#define MAX(x,y) ((x)>(y) ?(x):(y))
+#define MIN(x,y) ((x)<(y) ?(x):(y))
+#define ABS(x) ((x)<0 ?(-(x)):(x))
+#define SGN(x) ((x)<0 ?(-1):((x)==0?(0):(1)))
+
+typedef char BOOL;
+typedef short HWORD;
+typedef unsigned short UHWORD;
+typedef int IWORD;
+#ifndef WORD
+typedef int WORD;
+#endif
+typedef unsigned int UWORD;
+
--- /dev/null
+++ b/sbdsp.c
@@ -1,0 +1,157 @@
+
+char ansi_c_is_very_stupid_and_needs_a_variable_here;
+
+#if defined(BLASTER) || defined(SBLAST)
+/*
+ * Copyright 1992 Rick Richardson
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Rick Richardson, Lance Norskog And Sundry Contributors are not
+ * responsible for the consequences of using this software.
+ */
+
+/*
+ * Direct to Sound Blaster device driver.
+ * SBLAST patches by John T. Kohl.
+ */
+
+#include <sys/types.h>
+#ifdef SBLAST
+#include <i386/isa/sblast.h>
+#else
+#include <sys/sb.h>
+#endif
+#include <signal.h>
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct sbdspstuff {
+ int samples; /* bytes remaining in current block */
+} *sbdsp_t;
+
+static got_int = 0;
+
+static void
+sigint(s)
+int s;
+{
+ if (s) got_int = 1;
+ else signal(SIGINT, sigint);
+}
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+sbdspstartread(ft)
+ft_t ft;
+{
+ sbdsp_t sbdsp = (sbdsp_t) ft->priv;
+#ifdef SBLAST
+ int off = 0;
+#endif
+
+ /* If you need to seek around the input file. */
+ if (0 && ! ft->seekable)
+ fail("SKEL input file must be a file, not a pipe");
+
+ if (!ft->info.rate)
+ ft->info.rate = 11000;
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ ft->info.channels = 1;
+ ioctl(fileno(ft->fp), DSP_IOCTL_RESET, 0);
+#ifdef SBLAST
+ ioctl(fileno(ft->fp), DSP_IOCTL_VOICE, &off);
+ ioctl(fileno(ft->fp), DSP_IOCTL_SPEED, &ft->info.rate);
+#else
+ ioctl(fileno(ft->fp), DSP_IOCTL_VOICE, 0);
+ ioctl(fileno(ft->fp), DSP_IOCTL_SPEED, ft->info.rate);
+#endif
+ sigint(0); /* Prepare to catch SIGINT */
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+sbdspread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ sbdsp_t sbdsp = (sbdsp_t) ft->priv;
+ int rc;
+
+ if (got_int) return (0);
+ rc = rawread(ft, buf, len);
+ if (rc < 0) return 0;
+ return (rc);
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+sbdspstopread(ft)
+ft_t ft;
+{
+#ifdef SBLAST
+ ioctl(fileno(ft->fp), DSP_IOCTL_FLUSH, 0);
+#endif
+}
+
+sbdspstartwrite(ft)
+ft_t ft;
+{
+ sbdsp_t sbdsp = (sbdsp_t) ft->priv;
+#ifdef SBLAST
+ int on = 1;
+#endif
+
+ /* If you have to seek around the output file */
+ if (0 && ! ft->seekable)
+ fail("Output .sbdsp file must be a file, not a pipe");
+
+ if (!ft->info.rate)
+ ft->info.rate = 11000;
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ ft->info.channels = 1;
+ ioctl(fileno(ft->fp), DSP_IOCTL_RESET, 0);
+#ifdef SBLAST
+ ioctl(fileno(ft->fp), DSP_IOCTL_FLUSH, 0);
+ ioctl(fileno(ft->fp), DSP_IOCTL_VOICE, &on);
+ ioctl(fileno(ft->fp), DSP_IOCTL_SPEED, &ft->info.rate);
+#else
+ ioctl(fileno(ft->fp), DSP_IOCTL_VOICE, 1);
+ ioctl(fileno(ft->fp), DSP_IOCTL_SPEED, ft->info.rate);
+#endif
+}
+
+sbdspwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ sbdsp_t sbdsp = (sbdsp_t) ft->priv;
+
+ if (len == 0) return 0;
+ return (rawwrite(ft, buf, len));
+}
+
+sbdspstopwrite(ft)
+ft_t ft;
+{
+ /* All samples are already written out. */
+ /* If file header needs fixing up, for example it needs the */
+ /* the number of samples in a field, seek back and write them here. */
+ fflush(ft->fp);
+ ioctl(fileno(ft->fp), DSP_IOCTL_FLUSH, 0);
+}
+#endif
--- /dev/null
+++ b/sfheader.h
@@ -1,0 +1,120 @@
+# define SIZEOF_BSD_HEADER 1024
+# define SF_MAGIC 107364
+# define SF_LINK 107414
+# define SF_SHORT sizeof(short)
+# define SF_FLOAT sizeof(float)
+# define SF_BUFSIZE (16*1024)
+# define SF_MAXCHAN 4
+# define MAXCOMM 512
+# define MINCOMM 256
+
+/* Codes for sfcode */
+# define SF_END 0
+# define SF_MAXAMP 1
+# define SF_COMMENT 2
+# define SF_LINKCODE 3
+
+typedef struct sfcode {
+ short code;
+ short bsize;
+} SFCODE;
+
+typedef struct sfmaxamp {
+ float value[SF_MAXCHAN];
+ LONG samploc[SF_MAXCHAN];
+ LONG timetag;
+} SFMAXAMP;
+
+typedef struct sfcomment {
+ char comment[MAXCOMM];
+} SFCOMMENT;
+
+typedef struct sflink {
+ char reality[50];
+ LONG startsamp;
+ LONG endsamp;
+} SFLINK;
+
+struct sfinfo {
+ LONG sf_magic;
+ float sf_srate;
+ LONG sf_chans;
+ LONG sf_packmode;
+/* char sf_codes; /* BOGUS! */
+ SFCODE sf_codes;
+} ;
+
+typedef union sfheader {
+ struct sfinfo sfinfo;
+ char filler[SIZEOF_BSD_HEADER];
+} SFHEADER;
+
+static SFCODE ampcode = {
+SF_MAXAMP,
+sizeof(SFMAXAMP) + sizeof(SFCODE)
+};
+
+# define sfchans(x) (x)->sfinfo.sf_chans
+# define sfmagic(x) (x)->sfinfo.sf_magic
+# define sfsrate(x) (x)->sfinfo.sf_srate
+# define sfclass(x) (x)->sfinfo.sf_packmode
+# define sfbsize(x) ((x)->st_size - sizeof(SFHEADER))
+# define sfcodes(x) (x)->sfinfo.sf_codes
+
+# define ismagic(x) ((x)->sfinfo.sf_magic == SF_MAGIC)
+# define islink(x) ((x)->sfinfo.sf_magic == SF_LINK)
+
+# define sfmaxamp(mptr,chan) (mptr)->value[chan]
+# define sfmaxamploc(mptr,chan) (mptr)->samploc[chan]
+# define sfmaxamptime(x) (x)->timetag
+# define ismaxampgood(x,s) (sfmaxamptime(x) + 2 >= (s)->st_mtime)
+
+# define sfcomm(x,n) (x)->comment[n]
+
+# define realname(x) (x)->reality
+# define startsmp(x) (x)->startsamp
+# define endsmp(x) (x)->endsamp
+# define sfoffset(x,h) ((x)->startsamp * sfchans(h) * sfclass(h))
+# define sfendset(x,h) ((x)->endsamp * sfchans(h) * sfclass(h))
+
+# define sflseek(x,y,z) lseek(x,(z != 0) ? y : ((y) + sizeof(SFHEADER)),z)
+# define rheader(x,y) read(x,(char *) y,sizeof(SFHEADER)) != sizeof(SFHEADER)
+
+#define readopensf(name,fd,sfh,sfst,prog,result) \
+if ((fd = open(name, 0)) < 0) { \
+ fprintf(stderr,"%s: cannot access file %s\n",prog,name); \
+ result = -1; \
+} \
+else if (stat(name,&sfst)){ \
+ fprintf(stderr,"%s: cannot get status on %s\n",prog,name); \
+ result = -1; \
+} \
+else if (rheader(fd,&sfh)){ \
+ fprintf(stderr,"%s: cannot read header from %s\n",prog,name); \
+ result = -1; \
+} \
+else if (!ismagic(&sfh)){ \
+ fprintf(stderr,"%s: %s not a bsd soundfile\n",prog,name); \
+ result = -1; \
+} \
+else result = 0;
+
+#define rwopensf(name,fd,sfh,sfst,prog,result,code) \
+if ((fd = open(name, code)) < 0) { \
+ fprintf(stderr,"%s: cannot access file %s\n",prog,name); \
+ result = -1; \
+} \
+else if (rheader(fd,&sfh)){ \
+ fprintf(stderr,"%s: cannot read header from %s\n",prog,name); \
+ result = -1; \
+} \
+else if (!ismagic(&sfh)){ \
+ fprintf(stderr,"%s: %s not a bsd soundfile\n",prog,name); \
+ result = -1; \
+} \
+else if (stat(name,&sfst)){ \
+ fprintf(stderr,"%s: cannot get status on %s\n",prog,name); \
+ result = -1; \
+} \
+else result = 0;
+
--- /dev/null
+++ b/sound2au.com
@@ -1,0 +1,52 @@
+$ FVER = 'F$Verify(0)'
+$ !
+$ ! Sound2Au.Com
+$ ! translate a variety of sound formats into Sun .au format (compatible with
+$ ! DECsound) via SOX and SOUND2SUN.
+$ !
+$ ! sound2sun was written by Rich Gopstein and Harris Corporation.
+$ !
+$ ! SOX is part of the Sound Tools package written and distributed by
+$ ! Lance Norskog, et. al.
+$ !
+$ ! Usage
+$ ! @sound2au file_name [frequency]
+$ !
+$ ! where:
+$ ! file_name = filename template (may contain wildcards)
+$ ! frequency = sampling frequency (default 11000 Hz)
+$ !
+$ ! Modification History
+$ ! 14 Dec 1992, K. S. Kubo, Created
+$ !
+$ If P1 .Eqs. "" THEN GOTO USAGE_EXIT
+$ !
+$ FTMPL = F$Parse(P1,"*.SND;")
+$ If F$TrnLnm("SOX_DIR") .Nes. "" Then Goto MORE_DEFS
+$ SDIR = F$Element(0, "]", F$Environment("PROCEDURE")) + "]"
+$ Define/NoLog SOX_DIR 'SDIR'
+$ MORE_DEFS:
+$ SOX = "$ SOX_DIR:SOX"
+$ SOUND2SUN = "$ SOX_DIR:SOUND2SUN"
+$ ONAME = ""
+$ If P2 .Nes. "" Then SOUND2SUN = SOUND2SUN + " -f ''P2'"
+$ LOOP:
+$ FNAME = F$Search(FTMPL)
+$ If FNAME .Eqs. "" Then Goto REAL_EXIT
+$ If FNAME .Eqs. ONAME Then Goto REAL_EXIT
+$ ONAME = FNAME
+$ VER = F$Parse(FNAME,,,"VERSION")
+$ FTYPE = F$Parse(FNAME,,,"TYPE")
+$ FNAME = FNAME - VER - ";" ! strip version number off
+$ BNAME = FNAME - FTYPE ! get the base name
+$ SOX 'FNAME' -t .raw -u -b 'BNAME'.raw
+$ SOUND2SUN 'BNAME'.raw 'BNAME'.au
+$ Delete/NoLog 'BNAME'.raw;
+$ Goto LOOP
+$ !
+$ USAGE_EXIT:
+$ Write Sys$Output "Usage: @SOUND2AU file_name"
+$ !
+$ REAL_EXIT:
+$ FVER = F$Verify('FVER')
+$ EXIT
--- /dev/null
+++ b/sound2sun.c
@@ -1,0 +1,201 @@
+/************************************************************************/
+/* Copyright 1989 by Rich Gopstein and Harris Corporation */
+/* */
+/* Permission to use, copy, modify, and distribute this software */
+/* and its documentation for any purpose and without fee is */
+/* hereby granted, provided that the above copyright notice */
+/* appears in all copies and that both that copyright notice and */
+/* this permission notice appear in supporting documentation, and */
+/* that the name of Rich Gopstein and Harris Corporation not be */
+/* used in advertising or publicity pertaining to distribution */
+/* of the software without specific, written prior permission. */
+/* Rich Gopstein and Harris Corporation make no representations */
+/* about the suitability of this software for any purpose. It */
+/* provided "as is" without express or implied warranty. */
+/************************************************************************/
+
+/************************************************************************/
+/* sound2sun.c - Convert sampled audio files into uLAW format for the */
+/* Sparcstation 1. */
+/* Send comments to ..!rutgers!soleil!gopstein */
+/************************************************************************/
+/* */
+/* Modified November 27, 1989 to convert to 8000 samples/sec */
+/* (contrary to man page) */
+/* Modified December 13, 1992 to write standard Sun .au header with */
+/* unspecified length. Also made miscellaneous changes for */
+/* VMS port. (K. S. Kubo, ken@hmcvax.claremont.edu) */
+/* Fixed Bug with converting slow sample speeds */
+/* */
+/************************************************************************/
+
+
+#include <stdio.h>
+
+#define DEFAULT_FREQUENCY 11000
+
+#ifdef VAXC
+#define READ_OPEN "r", "mbf=16", "shr=get"
+#define WR_OPEN "w", "mbf=16"
+#else
+#define READ_OPEN "r"
+#define WR_OPEN "w"
+#endif
+
+FILE *infile, *outfile;
+
+/* convert two's complement ch into uLAW format */
+
+unsigned int cvt(ch)
+int ch;
+{
+
+ int mask;
+
+ if (ch < 0) {
+ ch = -ch;
+ mask = 0x7f;
+ } else {
+ mask = 0xff;
+ }
+
+ if (ch < 32) {
+ ch = 0xF0 | 15 - (ch / 2);
+ } else if (ch < 96) {
+ ch = 0xE0 | 15 - (ch - 32) / 4;
+ } else if (ch < 224) {
+ ch = 0xD0 | 15 - (ch - 96) / 8;
+ } else if (ch < 480) {
+ ch = 0xC0 | 15 - (ch - 224) / 16;
+ } else if (ch < 992) {
+ ch = 0xB0 | 15 - (ch - 480) / 32;
+ } else if (ch < 2016) {
+ ch = 0xA0 | 15 - (ch - 992) / 64;
+ } else if (ch < 4064) {
+ ch = 0x90 | 15 - (ch - 2016) / 128;
+ } else if (ch < 8160) {
+ ch = 0x80 | 15 - (ch - 4064) / 256;
+ } else {
+ ch = 0x80;
+ }
+return (mask & ch);
+}
+
+/* write a "standard" sun header with an unspecified length */
+#define wrulong(fp, ul) putc((ul >> 24) & 0xff, fp); \
+ putc((ul >> 16) & 0xff, fp); putc((ul >> 8) & 0xff, fp); \
+ putc(ul & 0xff, fp);
+
+static void
+wr_header(optr)
+FILE *optr;
+{
+ wrulong(optr, 0x2e736e64); /* Sun magic */
+ wrulong(optr, 24); /* header size in bytes */
+ wrulong(optr, ((unsigned)(~0))); /* unspecified data size */
+ wrulong(optr, 1); /* Sun uLaw format */
+ wrulong(optr, 8000); /* sample rate by definition :-) */
+ wrulong(optr, 1); /* single channel */
+}
+
+/*******************************************************
+/* */
+/* Usage is "sound2sun [-f frequency] infile outfile" */
+/* */
+/* "frequency" is the samples per second of the infile */
+/* the outfile is always 8000 samples per second. */
+/* */
+/*******************************************************/
+
+/***********************************************************************/
+/* */
+/* The input file is expected to be a stream of one-byte excess-128 */
+/* samples. Each sample is converted to 2's complement by subtracting */
+/* 128, then converted to uLAW and output. We calculate the proper */
+/* number of input bytes to skip in order to make the sample frequency */
+/* convert to 8000/sec properly. Interpolation could be added, but it */
+/* doesn't appear to be necessary. */
+/* */
+/***********************************************************************/
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+
+ float sum = 0;
+ float frequency, increment;
+
+ unsigned char ch;
+ unsigned char ulaw;
+
+ int chr;
+
+ if ((argc != 3) && (argc != 5)) {
+ fprintf(stderr,"Usage: sound2sun [-f frequency] infile outfile\n");
+ exit(1);
+ }
+
+ if (argc == 5) {
+ if (strcmp(argv[1], "-f") != 0) {
+ fprintf(stderr, "Usage: sound2sun [-f frequency] infile outfile\n");
+ exit(1);
+ } else {
+ frequency = atoi(argv[2]);
+ }
+ } else {
+ frequency = DEFAULT_FREQUENCY;
+ }
+
+ if ((infile = fopen(argv[argc-2], READ_OPEN)) == NULL) {
+ perror("Error opening infile");
+ exit(0);
+ }
+
+ if ((outfile = fopen(argv[argc-1], WR_OPEN)) == NULL) {
+ perror("Error opening outfile");
+ exit(0);
+ }
+
+ wr_header(outfile);
+
+ /* increment is the number of bytes to read each time */
+
+ increment = frequency / 8000;
+
+ ch = fgetc(infile);
+
+ while (!feof(infile)) {
+
+ /* convert the excess 128 to two's complement */
+
+ chr = 0x80 - ch;
+
+ /* increase the volume */
+ /* convert to uLAW */
+
+ ulaw = cvt(chr * 16);
+
+ /* output it */
+
+ fputc((char) ulaw, outfile);
+
+ /* skip enough input bytes to compensate for sampling frequency diff */
+
+ sum += increment;
+
+ while(sum > 0) {
+ if (!feof(infile)) ch = fgetc(infile);
+ sum--;
+ }
+
+ }
+
+ fclose(infile);
+ fclose(outfile);
+}
+
+/* DEC/CMS REPLACEMENT HISTORY, Element SOUND2SUN.C */
+/* *1 14-DEC-1992 17:46:37 CENYDD "main program" */
+/* DEC/CMS REPLACEMENT HISTORY, Element SOUND2SUN.C */
--- /dev/null
+++ b/sound2sun.opt
@@ -1,0 +1,5 @@
+identification="V1.0"
+!
+! Basic C library stuff
+!
+sys$share:vaxcrtl/shareable
--- /dev/null
+++ b/sox.1
@@ -1,0 +1,723 @@
+.de Sh
+.br
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp
+.if t .sp .5v
+.if n .sp
+..
+.TH SOX 1 "September 6, 1998"
+.SH NAME
+sox \- SOund eXchange : universal sound sample translator
+.SH SYNOPSIS
+.B sox \fIinfile outfile \fB
+.br
+.B sox \fIinfile outfile \fB[ \fIeffect\fR
+.B [ \fIeffect options ...\fB ] ]
+.br
+.B sox \fIinfile \fB-e \fIeffect\fR
+.B [ \fIeffect options ...\fB ]
+.br
+.B sox
+[\fI general options \fB ]
+[ \fIformat options \fB ]
+\fIifile\fB
+[ \fIformat options \fB ]
+\fIofile\fB
+[ \fIeffect\fR [ \fIeffect options ...\fB ] ]
+.P
+\fIGeneral options:\fB
+[ -e ]
+[ -h ]
+[ -p ]
+[ -v \fIvolume\fB ]
+[ -V ]
+.P
+\fIFormat options:\fB
+[ \fB-t \fIfiletype\fB ]
+[ -r \fIrate\fB ]
+[ -s/-u/-U/-A/-a/-g ]
+[ -b/-w/-l/-f/-d/-D ]
+[ -c \fIchannels\fB ]
+[ -x ]
+.P
+\fIEffects:\fB
+.br
+ avg [ \fI-l\fB | \fI-r\fB ]
+.br
+ band \fB[ \fI-n \fB] \fIcenter \fB[ \fIwidth\fB ]
+.br
+ check
+.br
+ chorus \fIgain-in gain out delay decay speed depth
+ -s\fB | \fI-t\fB [ \fIdelay decay speed depth -s\fB | -fI-t\fB ]
+.br
+ copy
+.br
+ cut
+.br
+ deemph
+.br
+ echo \fIgain-in gain-out delay decay\fB [ \fIdelay decay ...\fB]
+.br
+ echos \fIgain-in gain-out delay decay\fB [ \fIdelay decay ...\fB]
+.br
+ flanger \fIgain-in gain-out delay decay speed -s\fB | -fI-t\fB
+.br
+ highp \fIcenter\fB
+.br
+ lowp \fIcenter\fB
+.br
+ map
+.br
+ mask
+.br
+ phaser \fIgain-in gain-out delay decay speed -s\fB | \fI-t\fB
+.br
+ pick
+.br
+ polyphase [ \fI-w \fR< \fInum\fR / \fIham\fR > ]
+ [ \fI -width \fR< \fI long \fR / \fIshort \fR / \fI# \fR> ]
+ [ \fI-cutoff # \fR ]
+.br
+ \fBrate
+.br
+ resample
+.br
+ reverb \fIgain-out reverb-time delay\fB [ \fIdelay ... \fB]
+.br
+ reverse
+.br
+ split
+.br
+ stat [ \fIdebug\fB | \fI-v\fB ]
+.br
+ vibro \fIspeed \fB[ \fIdepth\fB ]
+.SH DESCRIPTION
+.I Sox
+translates sound files from one format to another,
+possibly doing a sound effect.
+.SH OPTIONS
+The option syntax is a little grotty, but in essence:
+.br
+ sox file.au file.voc
+.br
+translates a sound sample in SUN Sparc .AU format
+into a SoundBlaster .VOC file, while
+.br
+ sox -v 0.5 file.au -r 12000 file.voc rate
+.br
+does the same format translation but also
+lowers the amplitude by 1/2 and changes
+the sampling rate from 8000 hertz to 12000 hertz via
+the
+.B rate
+\fIsound effect\fR loop.
+.PP
+File type options:
+.TP 10
+\fB-t\fI filetype
+gives the type of the sound sample file.
+.TP 10
+\fB-r \fIrate\fR
+Give sample rate in Hertz of file.
+.TP 10
+\fB-s/-u/-U/-A/-a/-g\fR
+The sample data is signed linear (2's complement),
+unsigned linear, U-law (logarithmic), A-law (logarithmic),
+ADPCM, or GSM.
+U-law and A-law are the U.S. and international
+standards for logarithmic telephone sound compression.
+ADPCM is form of sound compression that has a good
+compromise between good sound quality and fast encoding/decoding
+time.
+GSM is a standard used for telephone sound compression in
+European countries and its gaining popularity because of its
+quality.
+.TP 10
+\fB-b/-w/-l/-f/-d/-D\fR
+The sample data is in bytes, 16-bit words, 32-bit longwords,
+32-bit floats, 64-bit double floats, or 80-bit IEEE floats.
+Floats and double floats are in native machine format.
+.TP 10
+\fB-x\fR
+The sample data is in XINU format; that is,
+it comes from a machine with the opposite word order
+than yours and must
+be swapped according to the word-size given above.
+Only 16-bit and 32-bit integer data may be swapped.
+Machine-format floating-point data is not portable.
+IEEE floats are a fixed, portable format. ???
+.TP 10
+\fB-c \fIchannels\fR
+The number of sound channels in the data file.
+This may be 1, 2, or 4; for mono, stereo, or quad sound data.
+.PP
+General options:
+.TP 10
+\fB-e\fR
+after the input file allows you to avoid giving
+an output file and just name an effect.
+This is mainly useful with the
+.B stat
+effect but can be used with others.
+.TP 10
+\fB-h\fR
+Print version number and usage information.
+.TP 10
+\fB-p\fR
+Run in preview mode and run fast. This will somewhat speed up
+sox when the output format has a different number of channels and
+a different rate then the input file. The order that the effects
+are run in will be arranged for maximum speed and not quality.
+.TP 10
+\fB-v \fIvolume\fR
+Change amplitude (floating point);
+less than 1.0 decreases, greater than 1.0 increases.
+Note: we perceive volume logarithmically, not linearly.
+Note: see the
+.B stat
+effect.
+.TP 10
+\fB-V\fR
+Print a description of processing phases.
+Useful for figuring out exactly how
+.I sox
+is mangling your sound samples.
+.PP
+The input and output files may be standard input and output.
+This is specified by '-'.
+The
+.B -t\ \fItype
+option must be given in this case,
+else
+.I sox
+will not know the format of the given file.
+The
+.B -t,
+.B -r,
+.B -s/-u/-U/-A,
+.B -b/-w/-l/-f/-d/-D
+and
+.B -x
+options refer to the input data when given before the
+input file name. After, they refer to the output data.
+.PP
+If you don't give an output file name,
+.I sox
+will just read the input file.
+This is useful for validating structured file formats;
+the
+.B stat
+effect may also be used
+via the
+.B -e
+option.
+.SH FILE TYPES
+.I Sox
+needs to know the formats of the input and output files.
+File formats which have headers are checked,
+if that header doesn't seem right,
+the program exits with an appropriate message.
+Currently, raw (no header) binary and textual data,
+Amiga 8SVX, Apple/SGI AIFF, SPARC .AU (w/header), NeXT .SND,
+CD-R, CVSD, GSM 06.10, Mac HCOM, Sound Tools MAUD, OSS device drivers,
+Turtle Beach .SMP, Sound Blaster, Sndtool, and Sounder,
+Sun Audio device driver,
+Yamaha TX-16W Sampler, IRCAM Sound Files, Creative Labs VOC,
+Psion .WVE, and Microsoft RIFF/WAV are supported.
+.PP
+.TP 10
+.B .8svx
+Amiga 8SVX musical instrument description format.
+.TP 10
+.B .aiff
+AIFF files used on Apple IIc/IIgs and SGI.
+Note: the AIFF format supports only one SSND chunk.
+It does not support multiple sound chunks,
+or the 8SVX musical instrument description format.
+AIFF files are multimedia archives and
+and can have multiple audio and picture chunks.
+You may need a separate archiver to work with them.
+.TP 10
+.B .au
+SUN Microsystems AU files.
+There are apparently many types of .au files;
+DEC has invented its own with a different magic number
+and word order.
+The .au handler can read these files but will not write them.
+Some .au files have valid AU headers and some do not.
+The latter are probably original SUN u-law 8000 hz samples.
+These can be dealt with using the
+.B .ul
+format (see below).
+.TP 10
+.B .cdr
+CD-R
+.br
+CD-R files are used in mastering music Compact Disks.
+The file format is, as you might expect, raw stereo
+raw unsigned samples at 44khz. But, there's
+some blocking/padding oddity in the format, so it
+needs its own handler.
+.TP 10
+.B .cvs
+Continuously Variable Slope Delta modulation
+.br
+Used to compress speech audio for applications such as voice mail.
+.TP 10
+.B .dat
+Text Data files
+.br
+These files contain a textual representation of the
+sample data. There is one line at the beginning
+that contains the sample rate. Subsequent lines
+contain two numeric data items: the time since
+the beginning of the sample and the sample value.
+Values are normalized so that the maximum and minimum
+are 1.00 and -1.00. This file format can be used to
+create data files for external programs such as
+FFT analyzers or graph routines. SOX can also convert
+a file in this format back into one of the other file
+formats.
+.TP 10
+.B .gsm
+GSM 06.10 Lossy Speech Compression
+.br
+A standard for compressing speech which is used in the
+Global Standard for Mobil telecommunications (GSM). Its good
+for its purpose, shrinking audio data size, but it will introduce
+lots of noise when a given sound sample is encoded and decoded
+multiple times. This format is used by some voice mail applications.
+It is rather CPU intensive.
+GSM in
+.B sox
+is optional and requires access to an external GSM library. To see
+if there is support for gsm run
+.I sox -h
+and look for it under the list of supported file formats.
+.TP 10
+.B .hcom
+Macintosh HCOM files.
+These are (apparently) Mac FSSD files with some variant
+of Huffman compression.
+The Macintosh has wacky file formats and this format
+handler apparently doesn't handle all the ones it should.
+Mac users will need your usual arsenal of file converters
+to deal with an HCOM file under Unix or DOS.
+.TP 10
+.B .maud
+An Amiga format
+.br
+An IFF-conform sound file type, registered by
+MS MacroSystem Computer GmbH, published along
+with the "Toccata" sound-card on the Amiga.
+Allows 8bit linear, 16bit linear, A-Law, u-law
+in mono and stereo.
+.TP 10
+.B ossdsp
+OSS /dev/dsp device driver
+.br
+This is a psuedo-file type and can be optionally compiled into Sox. Run
+.B sox -h
+to see if you have support for this file type. When this driver is used
+it allows you to open up the OSS /dev/dsp file and configure it to
+use the same data type as passed in to
+.B Sox.
+It works for both playing and recording sound samples. When playing sound
+files it attempts to set up the OSS driver to use the same format as the
+input file. It is suggested to always override the output values to use
+the highest quality samples your sound card can handle. Example:
+.I -t ossdsp -w -s /dev/dsp
+.TP 10
+.B .sf
+IRCAM Sound Files.
+.br
+SoundFiles are used by academic music software
+such as the CSound package, and the MixView sound sample editor.
+.TP 10
+.B .smp
+Turtle Beach SampleVision files.
+.br
+SMP files are for use with the PC-DOS package SampleVision by Turtle Beach
+Softworks. This package is for communication to several MIDI samplers. All
+sample rates are supported by the package, although not all are supported by
+the samplers themselves. Currently loop points are ignored.
+.TP 10
+.B sunau
+Sun /dev/audio device driver
+.br
+This is a psuedo-file type and can be optionally compiled into Sox. Run
+.B sox -h
+to see if you have support for this file type. When this driver is used
+it allows you to open up a Sun /dev/audio file and configure it to
+use the same data type as passed in to
+.B Sox.
+It works for both playing and recording sound samples. When playing sound
+files it attempts to set up the audio driver to use the same format as the
+input file. It is suggested to always override the output values to use
+the highest quality samples your hardware can handle. Example:
+.I -t sunau -w -s /dev/audio
+or
+.I -t sunau -U -c 1 /dev/audio
+for older sun equipment.
+.TP 10
+.B .txw
+Yamaha TX-16W sampler.
+.br
+A file format from a Yamaha sampling keyboard which wrote IBM-PC
+format 3.5" floppies. Handles reading of files which do not have
+the sample rate field set to one of the expected by looking at some
+other bytes in the attack/loop length fields, and defaulting to
+33kHz if the sample rate is still unknown.
+.TP 10
+.B .vms
+More info to come.
+.br
+Used to compress speech audio for applications such as voice mail.
+.TP 10
+.B .voc
+Sound Blaster VOC files.
+.br
+VOC files are multi-part and contain silence parts, looping, and
+different sample rates for different chunks.
+On input, the silence parts are filled out, loops are rejected,
+and sample data with a new sample rate is rejected.
+Silence with a different sample rate is generated appropriately.
+On output, silence is not detected, nor are impossible sample rates.
+.TP 10
+.B .wav
+Microsoft .WAV RIFF files.
+.br
+These appear to be very similar to IFF files,
+but not the same.
+They are the native sound file format of Windows.
+(Obviously, Windows was of such incredible importance
+to the computer industry that it just had to have its own
+sound file format.)
+Normally \fB.wav\fR files have all formatting information
+in their headers, and so do not need any format options
+specified for an input file. If any are, they will
+override the file header, and you will be warned to this effect.
+You had better know what you are doing! Output format
+options will cause a format conversion, and the \fB.wav\fR
+will written appropriately. Note that it is possible to
+write data of a type that cannot be specified by
+the \fB.wav\fR header, and you will be warned that
+you a writing a bad file !
+Sox currently can read PCM, ULAW, ALAW, MS ADPCM, and IMA (or DVI) ADPCM.
+It can output all of these formats except the ADPCM styles.
+.TP 10
+.B .wve
+Psion 8-bit alaw
+.br
+These are 8-bit a-law 8khz sound files used on the
+Psion palmtop portable computer.
+.TP 10
+.B .raw
+Raw files (no header).
+.br
+The sample rate, size (byte, word, etc),
+and style (signed, unsigned, etc.)
+of the sample file must be given.
+The number of channels defaults to 1.
+.TP 10
+.B ".ub, .sb, .uw, .sw, .ul"
+These are several suffices which serve as
+a shorthand for raw files with a given size and style.
+Thus, \fBub, sb, uw, sw,\fR and \fBul\fR
+correspond to "unsigned byte", "signed byte",
+"unsigned word", "signed word", and "ulaw" (byte).
+The sample rate defaults to 8000 hz if not explicitly set,
+and the number of channels (as always) defaults to 1.
+There are lots of Sparc samples floating around in u-law format
+with no header and fixed at a sample rate of 8000 hz.
+(Certain sound management software cheerfully ignores the headers.)
+Similarly, most Mac sound files are in unsigned byte format with
+a sample rate of 11025 or 22050 hz.
+.TP 10
+.B .auto
+This is a ``meta-type'': specifying this type for an input file
+triggers some code that tries to guess the real type by looking for
+magic words in the header. If the type can't be guessed, the program
+exits with an error message. The input must be a plain file, not a
+pipe. This type can't be used for output files.
+.SH EFFECTS
+Only one effect from the palette may be applied to a sound sample.
+To do multiple effects you'll need to run
+.I sox
+in a pipeline.
+.TP 10
+avg [ \fI-l\fR | \fI-r\fR ]
+Reduce the number of channels by averaging the samples,
+or duplicate channels to increase the number of channels.
+Valid combinations are 1 - 2, 1 - 4, 2 - 4, 4 - 2, 4 - 1,
+2 - 1. The \fI-l\fR or \fI-r\fR option averages from
+just left or right channels/duplicates to just the left
+or right channels.
+.TP 10
+band \fB[ \fI-n \fB] \fIcenter \fB[ \fIwidth\fB ]
+Apply a band-pass filter.
+The frequency response drops logarithmically
+around the
+.I center
+frequency.
+The
+.I width
+gives the slope of the drop.
+The frequencies at
+.I "center + width"
+and
+.I "center - width"
+will be half of their original amplitudes.
+.B Band
+defaults to a mode oriented to pitched signals,
+i.e. voice, singing, or instrumental music.
+The
+.I -n
+(for noise) option uses the alternate mode
+for un-pitched signals.
+.B Band
+introduces noise in the shape of the filter,
+i.e. peaking at the
+.I center
+frequency and settling around it.
+.TP
+chorus \fIgain-in gain-out delay decay speed deptch
+.TP 10
+ -s \fR| \fI-t [ \fIdelay decay speed depth -s \fR| \fI-t ... \fR]
+Add a chorus to a sound sample. Each quadtuple
+delay/decay/speed/depth gives the delay in milliseconds
+and the decay (relative to gain-in) with a modulation
+speed in Hz using depth in milliseconds.
+The modulation is either sinodial (-s) or triangular
+(-t). Gain-out is the volume of the output.
+.TP 10
+copy
+Copy the input file to the output file.
+This is the default effect if both files have the same
+sampling rate, or the rates are "close".
+.TP 10
+cut \fIloopnumber
+Extract loop #N from a sample.
+.TP 10
+deemph
+Apply a treble attenuation shelving filter to samples in
+audio cd format. The frequency response of pre-emphasized
+recordings is rectified. The filtering is defined in the
+standard document ISO 908.
+.TP 10
+echo \fIgain-in gain-out delay decay \fR[ \fIdelay decay ... \fR]
+Add echoing to a sound sample.
+Each delay/decay part gives the delay in milliseconds
+and the decay (relative to gain-in) of that echo.
+Gain-out is the volume of the output.
+.TP 10
+echos \fIgain-in gain-out delay decay \fR[ \fIdelay decay ... \fR]
+Add a sequence of echos to a sound sample.
+Each delay/decay part gives the delay in milliseconds
+and the decay (relative to gain-in) of that echo.
+Gain-out is the volume of the output.
+.TP 10
+flanger \fIgain-in gain-out delay decay speed -s \fR| \fI-t
+Add a flanger to a sound sample. Each triple
+delay/decay/speed gives the delay in milliseconds
+and the decay (relative to gain-in) with a modulation
+speed in Hz.
+The modulation is either sinodial (-s) or triangular
+(-t). Gain-out is the volume of the output.
+.TP 10
+highp \fIcenter
+Apply a high-pass filter.
+The frequency response drops logarithmically with
+.I center
+frequency in the middle of the drop.
+The slope of the filter is quite gentle.
+.TP 10
+lowp \fIcenter
+Apply a low-pass filter.
+The frequency response drops logarithmically with
+.I center
+frequency in the middle of the drop.
+The slope of the filter is quite gentle.
+.TP 10
+map
+Display a list of loops in a sample,
+and miscellaneous loop info.
+.TP 10
+mask
+Add "masking noise" to signal.
+This effect deliberately adds white noise to a sound
+in order to mask quantization effects,
+created by the process of playing a sound digitally.
+It tends to mask buzzing voices, for example.
+It adds 1/2 bit of noise to the sound file at the
+output bit depth.
+.TP 10
+phaser \fIgain-in gain-out delay decay speed -s \fR| \fI-t
+Add a phaser to a sound sample. Each triple
+delay/decay/speed gives the delay in milliseconds
+and the decay (relative to gain-in) with a modulation
+speed in Hz.
+The modulation is either sinodial (-s) or triangular
+(-t). The decay should be less than 0.5 to avoid
+feedback. Gain-out is the volume of the output.
+.TP 10
+pick
+Select the left or right channel of a stereo sample,
+or one of four channels in a quadrophonic sample.
+.TP
+polyphase [ \fI-w \fR< \fInum\fR / \fIham\fR > ]
+.TP
+ [ \fI -width \fR< \fI long \fR / \fIshort \fR / \fI# \fR> ]
+.TP 10
+ [ \fI-cutoff # \fR ]
+Translate input sampling rate to output sampling rate via polyphase
+interpolation, a DSP algorithm. This method is slow and uses lots
+of RAM, but gives much better results then
+.B rate.
+.br
+-w < nut / ham > : select either a Nuttal (~90 dB stopband) or Hamming
+(~43 dB stopband) window.
+.B Warning:
+Nuttall windows require 2x length than Hamming windows. Default is
+.I nut.
+.br
+-width long / short / # : specify the width of the filter.
+.I long
+is 1024 samples;
+.I short
+is 128 samples. Alternatively, an exact number can be used. Default is
+.I long.
+.br
+-cutoff # : specify the filter cutoff frequency in terms of fraction of
+bandwidth. If upsampling, then this is the fraction of the orignal signal
+that should go through. If downsampling, this is the fraction of the
+signal left after downsampling. Default is 0.95. Remember that
+this is a float.
+
+.TP 10
+rate
+Translate input sampling rate to output sampling rate
+via linear interpolation to the Least Common Multiple
+of the two sampling rates.
+This is the default effect
+if the two files have different sampling rates.
+This is fast but noisy:
+the spectrum of the original sound will be shifted upwards
+and duplicated faintly when up-translating by a multiple.
+Lerp-ing is acceptable for cheap 8-bit sound hardware,
+but for CD-quality sound you should instead use either
+.B resample
+or
+.B polyphase.
+If you are wondering which of
+.B Sox's
+rate changing effects to ues, you will want to read a
+detailed analysis of all of them at http://usa.ece.cmu.edu/Sox/
+.TP 10
+resample [ \fIrolloff\fR [ \fIbeta\fR ] ]
+Translate input sampling rate to output sampling rate
+via simulated analog filtration.
+This method is slow and uses lots of RAM,
+but gives much better results then
+.B rate
+(This has empirically been shown to be false. The
+resample algorthym needs to be updated from its original source).
+.TP 10
+reverb \fIgain-out delay \fR[ \fIdelay ... \fR]
+Add reverbation to a sound sample. Each delay is given
+in milliseconds and its feedback is depending on the
+reverb-time in milliseconds. Each delay should be in
+the range of half to quarter of reverb-time to get
+a realistic reverbation. Gain-out is the volume of the
+output.
+.TP 10
+reverse
+Reverse the sound sample completely.
+Included for finding Satanic subliminals.
+.TP 10
+split
+Turn a mono sample into a stereo sample by copying
+the input channel to the left and right channels.
+.TP 10
+stat [ debug | -v ]
+Do a statistical check on the input file,
+and print results on the standard error file.
+.B stat
+may copy the file untouched from input to output,
+if you select an output file.
+The "Volume Adjustment:" field in the statistics
+gives you the argument to the
+.B -v
+.I number
+which will make the sample as loud as possible without clipping.
+There is an optional parameter
+.B -v
+that will print out the "Volume Adjustment:" field's value and
+return. This could be of use in scripts to auto convert the
+volume. There is an also an optional parameter
+.B debug
+that will place sox into debug mode and print out a hex dump of the
+sound file from the internal buffer that is in 32-bit signed PCM data.
+This is mainly only of use in tracking down endian problems that
+creep in to sox on cross-platform versions.
+.TP 10
+vibro \fIspeed \fB [ \fIdepth\fB ]
+Add the world-famous Fender Vibro-Champ sound
+effect to a sound sample by using
+a sine wave as the volume knob.
+.B Speed
+gives the Hertz value of the wave.
+This must be under 30.
+.B Depth
+gives the amount the volume is cut into
+by the sine wave,
+ranging 0.0 to 1.0 and defaulting to 0.5.
+.P
+.I Sox
+enforces certain effects.
+If the two files have different sampling
+rates, the requested effect must be one of
+.B copy,
+or
+.B rate,
+." or
+." .B resample.
+If the two files have different numbers of channels,
+the
+.B avg
+." or other channel mixing
+effect must be requested.
+.SH BUGS
+The syntax is horrific.
+It's very tempting to include a default system that allows
+an effect name as the program name
+and just pipes a sound sample from standard input
+to standard output, but the problem of inputting the
+sample rates makes this unworkable.
+.P
+Please report any bugs found in this version of sox to Chris Bagwell (cbagwell@sprynet.com)
+.SH FILES
+.SH SEE ALSO
+.BR play (1) ,
+.BR rec (1)
+.SH NOTICES
+The echoplex effect is:
+Copyright (C) 1989 by Jef Poskanzer.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation. This software is provided "as is" without express or
+implied warranty.
+
+The version of Sox that accompanies this manual page is support by
+Chris Bagwell (cbagwell@sprynet.com). Please refer any questions
+regarding it to this address. You may obtain the latest version at the
+the web site http://home.sprynet.com/sprynet/cbagwell/projects.html
+
--- /dev/null
+++ b/sox.opt
@@ -1,0 +1,9 @@
+identification="V5.7"
+!
+! SoundTools library
+!
+soundtools.olb/library
+!
+! Basic C library stuff
+!
+sys$share:vaxcrtl/shareable
--- /dev/null
+++ b/sox.txt
@@ -1,0 +1,726 @@
+
+
+
+SOX(1) SOX(1)
+
+
+NAME
+ sox - SOund eXchange : universal sound sample translator
+
+SYNOPSIS
+ sox infile outfile
+ sox infile outfile [ effect [ effect options ... ] ]
+ sox infile -e effect [ effect options ... ]
+ sox [ general options ] [ format options ] ifile [ for-
+ mat options ] ofile [ effect [ effect options ... ] ]
+
+ General options: [ -e ] [ -h ] [ -p ] [ -v volume ] [ -V ]
+
+ Format options: [ -t filetype ] [ -r rate ] [
+ -s/-u/-U/-A/-a/-g ] [ -b/-w/-l/-f/-d/-D ] [ -c channels ]
+ [ -x ]
+
+ Effects:
+ avg [ -l | -r ]
+ band [ -n ] center [ width ]
+ check
+ chorus gain-in gain out delay decay speed depth
+ -s | -t [ delay decay speed depth -s | -fI-t ]
+ copy
+ cut
+ deemph
+ echo gain-in gain-out delay decay [ delay decay ...]
+ echos gain-in gain-out delay decay [ delay decay ...]
+ flanger gain-in gain-out delay decay speed -s | -fI-t
+ highp center
+ lowp center
+ map
+ mask
+ phaser gain-in gain-out delay decay speed -s | -t
+ pick
+ polyphase [ -w < num / ham > ]
+ [ -width < long / short / # > ]
+ [ -cutoff # ]
+ rate
+ resample
+ reverb gain-out reverb-time delay [ delay ... ]
+ reverse
+ split
+ stat [ debug | -v ]
+ vibro speed [ depth ]
+
+DESCRIPTION
+ Sox translates sound files from one format to another,
+ possibly doing a sound effect.
+
+OPTIONS
+ The option syntax is a little grotty, but in essence:
+ sox file.au file.voc
+ translates a sound sample in SUN Sparc .AU format into a
+ SoundBlaster .VOC file, while
+
+
+
+ September 6, 1998 1
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ sox -v 0.5 file.au -r 12000 file.voc rate
+ does the same format translation but also lowers the
+ amplitude by 1/2 and changes the sampling rate from 8000
+ hertz to 12000 hertz via the rate sound effect loop.
+
+ File type options:
+
+ -t filetype
+ gives the type of the sound sample file.
+
+ -r rate Give sample rate in Hertz of file.
+
+ -s/-u/-U/-A/-a/-g
+ The sample data is signed linear (2's comple-
+ ment), unsigned linear, U-law (logarithmic), A-
+ law (logarithmic), ADPCM, or GSM. U-law and A-
+ law are the U.S. and international standards for
+ logarithmic telephone sound compression. ADPCM
+ is form of sound compression that has a good
+ compromise between good sound quality and fast
+ encoding/decoding time. GSM is a standard used
+ for telephone sound compression in European
+ countries and its gaining popularity because of
+ its quality.
+
+ -b/-w/-l/-f/-d/-D
+ The sample data is in bytes, 16-bit words,
+ 32-bit longwords, 32-bit floats, 64-bit double
+ floats, or 80-bit IEEE floats. Floats and dou-
+ ble floats are in native machine format.
+
+ -x The sample data is in XINU format; that is, it
+ comes from a machine with the opposite word
+ order than yours and must be swapped according
+ to the word-size given above. Only 16-bit and
+ 32-bit integer data may be swapped. Machine-
+ format floating-point data is not portable.
+ IEEE floats are a fixed, portable format. ???
+
+ -c channels
+ The number of sound channels in the data file.
+ This may be 1, 2, or 4; for mono, stereo, or
+ quad sound data.
+
+ General options:
+
+ -e after the input file allows you to avoid giving
+ an output file and just name an effect. This is
+ mainly useful with the stat effect but can be
+ used with others.
+
+ -h Print version number and usage information.
+
+ -p Run in preview mode and run fast. This will
+
+
+
+ September 6, 1998 2
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ somewhat speed up sox when the output format has
+ a different number of channels and a different
+ rate then the input file. The order that the
+ effects are run in will be arranged for maximum
+ speed and not quality.
+
+ -v volume Change amplitude (floating point); less than 1.0
+ decreases, greater than 1.0 increases. Note: we
+ perceive volume logarithmically, not linearly.
+ Note: see the stat effect.
+
+ -V Print a description of processing phases. Use-
+ ful for figuring out exactly how sox is mangling
+ your sound samples.
+
+ The input and output files may be standard input and out-
+ put. This is specified by '-'. The -t type option must
+ be given in this case, else sox will not know the format
+ of the given file. The -t, -r, -s/-u/-U/-A,
+ -b/-w/-l/-f/-d/-D and -x options refer to the input data
+ when given before the input file name. After, they refer
+ to the output data.
+
+ If you don't give an output file name, sox will just read
+ the input file. This is useful for validating structured
+ file formats; the stat effect may also be used via the -e
+ option.
+
+FILE TYPES
+ Sox needs to know the formats of the input and output
+ files. File formats which have headers are checked, if
+ that header doesn't seem right, the program exits with an
+ appropriate message. Currently, raw (no header) binary
+ and textual data, Amiga 8SVX, Apple/SGI AIFF, SPARC .AU
+ (w/header), NeXT .SND, CD-R, CVSD, GSM 06.10, Mac HCOM,
+ Sound Tools MAUD, OSS device drivers, Turtle Beach .SMP,
+ Sound Blaster, Sndtool, and Sounder, Sun Audio device
+ driver, Yamaha TX-16W Sampler, IRCAM Sound Files, Cre-
+ ative Labs VOC, Psion .WVE, and Microsoft RIFF/WAV are
+ supported.
+
+
+ .8svx Amiga 8SVX musical instrument description for-
+ mat.
+
+ .aiff AIFF files used on Apple IIc/IIgs and SGI.
+ Note: the AIFF format supports only one SSND
+ chunk. It does not support multiple sound
+ chunks, or the 8SVX musical instrument descrip-
+ tion format. AIFF files are multimedia archives
+ and and can have multiple audio and picture
+ chunks. You may need a separate archiver to
+ work with them.
+
+
+
+
+ September 6, 1998 3
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ .au SUN Microsystems AU files. There are apparently
+ many types of .au files; DEC has invented its
+ own with a different magic number and word
+ order. The .au handler can read these files but
+ will not write them. Some .au files have valid
+ AU headers and some do not. The latter are
+ probably original SUN u-law 8000 hz samples.
+ These can be dealt with using the .ul format
+ (see below).
+
+ .cdr CD-R
+ CD-R files are used in mastering music Compact
+ Disks. The file format is, as you might expect,
+ raw stereo raw unsigned samples at 44khz. But,
+ there's some blocking/padding oddity in the for-
+ mat, so it needs its own handler.
+
+ .cvs Continuously Variable Slope Delta modulation
+ Used to compress speech audio for applications
+ such as voice mail.
+
+ .dat Text Data files
+ These files contain a textual representation of
+ the sample data. There is one line at the
+ beginning that contains the sample rate. Subse-
+ quent lines contain two numeric data items: the
+ time since the beginning of the sample and the
+ sample value. Values are normalized so that the
+ maximum and minimum are 1.00 and -1.00. This
+ file format can be used to create data files for
+ external programs such as FFT analyzers or graph
+ routines. SOX can also convert a file in this
+ format back into one of the other file formats.
+
+ .gsm GSM 06.10 Lossy Speech Compression
+ A standard for compressing speech which is used
+ in the Global Standard for Mobil telecommunica-
+ tions (GSM). Its good for its purpose, shrink-
+ ing audio data size, but it will introduce lots
+ of noise when a given sound sample is encoded
+ and decoded multiple times. This format is used
+ by some voice mail applications. It is rather
+ CPU intensive. GSM in sox is optional and
+ requires access to an external GSM library. To
+ see if there is support for gsm run sox -h and
+ look for it under the list of supported file
+ formats.
+
+ .hcom Macintosh HCOM files. These are (apparently)
+ Mac FSSD files with some variant of Huffman com-
+ pression. The Macintosh has wacky file formats
+ and this format handler apparently doesn't han-
+ dle all the ones it should. Mac users will need
+ your usual arsenal of file converters to deal
+
+
+
+ September 6, 1998 4
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ with an HCOM file under Unix or DOS.
+
+ .maud An Amiga format
+ An IFF-conform sound file type, registered by MS
+ MacroSystem Computer GmbH, published along with
+ the "Toccata" sound-card on the Amiga. Allows
+ 8bit linear, 16bit linear, A-Law, u-law in mono
+ and stereo.
+
+ ossdsp OSS /dev/dsp device driver
+ This is a psuedo-file type and can be optionally
+ compiled into Sox. Run sox -h to see if you
+ have support for this file type. When this
+ driver is used it allows you to open up the OSS
+ /dev/dsp file and configure it to use the same
+ data type as passed in to Sox. It works for
+ both playing and recording sound samples. When
+ playing sound files it attempts to set up the
+ OSS driver to use the same format as the input
+ file. It is suggested to always override the
+ output values to use the highest quality samples
+ your sound card can handle. Example: -t ossdsp
+ -w -s /dev/dsp
+
+ .sf IRCAM Sound Files.
+ SoundFiles are used by academic music software
+ such as the CSound package, and the MixView
+ sound sample editor.
+
+ .smp Turtle Beach SampleVision files.
+ SMP files are for use with the PC-DOS package
+ SampleVision by Turtle Beach Softworks. This
+ package is for communication to several MIDI
+ samplers. All sample rates are supported by the
+ package, although not all are supported by the
+ samplers themselves. Currently loop points are
+ ignored.
+
+ sunau Sun /dev/audio device driver
+ This is a psuedo-file type and can be optionally
+ compiled into Sox. Run sox -h to see if you
+ have support for this file type. When this
+ driver is used it allows you to open up a Sun
+ /dev/audio file and configure it to use the same
+ data type as passed in to Sox. It works for
+ both playing and recording sound samples. When
+ playing sound files it attempts to set up the
+ audio driver to use the same format as the input
+ file. It is suggested to always override the
+ output values to use the highest quality samples
+ your hardware can handle. Example: -t sunau -w
+ -s /dev/audio or -t sunau -U -c 1 /dev/audio for
+ older sun equipment.
+
+
+
+
+ September 6, 1998 5
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ .txw Yamaha TX-16W sampler.
+ A file format from a Yamaha sampling keyboard
+ which wrote IBM-PC format 3.5" floppies. Han-
+ dles reading of files which do not have the sam-
+ ple rate field set to one of the expected by
+ looking at some other bytes in the attack/loop
+ length fields, and defaulting to 33kHz if the
+ sample rate is still unknown.
+
+ .vms More info to come.
+ Used to compress speech audio for applications
+ such as voice mail.
+
+ .voc Sound Blaster VOC files.
+ VOC files are multi-part and contain silence
+ parts, looping, and different sample rates for
+ different chunks. On input, the silence parts
+ are filled out, loops are rejected, and sample
+ data with a new sample rate is rejected.
+ Silence with a different sample rate is gener-
+ ated appropriately. On output, silence is not
+ detected, nor are impossible sample rates.
+
+ .wav Microsoft .WAV RIFF files.
+ These appear to be very similar to IFF files,
+ but not the same. They are the native sound
+ file format of Windows. (Obviously, Windows was
+ of such incredible importance to the computer
+ industry that it just had to have its own sound
+ file format.) Normally .wav files have all for-
+ matting information in their headers, and so do
+ not need any format options specified for an
+ input file. If any are, they will override the
+ file header, and you will be warned to this
+ effect. You had better know what you are doing!
+ Output format options will cause a format con-
+ version, and the .wav will written appropri-
+ ately. Note that it is possible to write data
+ of a type that cannot be specified by the .wav
+ header, and you will be warned that you a writ-
+ ing a bad file ! Sox currently can read PCM,
+ ULAW, ALAW, MS ADPCM, and IMA (or DVI) ADPCM.
+ It can output all of these formats except the
+ ADPCM styles.
+
+ .wve Psion 8-bit alaw
+ These are 8-bit a-law 8khz sound files used on
+ the Psion palmtop portable computer.
+
+ .raw Raw files (no header).
+ The sample rate, size (byte, word, etc), and
+ style (signed, unsigned, etc.) of the sample
+ file must be given. The number of channels
+ defaults to 1.
+
+
+
+ September 6, 1998 6
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ .ub, .sb, .uw, .sw, .ul
+ These are several suffices which serve as a
+ shorthand for raw files with a given size and
+ style. Thus, ub, sb, uw, sw, and ul correspond
+ to "unsigned byte", "signed byte", "unsigned
+ word", "signed word", and "ulaw" (byte). The
+ sample rate defaults to 8000 hz if not explic-
+ itly set, and the number of channels (as always)
+ defaults to 1. There are lots of Sparc samples
+ floating around in u-law format with no header
+ and fixed at a sample rate of 8000 hz. (Certain
+ sound management software cheerfully ignores the
+ headers.) Similarly, most Mac sound files are
+ in unsigned byte format with a sample rate of
+ 11025 or 22050 hz.
+
+ .auto This is a ``meta-type'': specifying this type
+ for an input file triggers some code that tries
+ to guess the real type by looking for magic
+ words in the header. If the type can't be
+ guessed, the program exits with an error mes-
+ sage. The input must be a plain file, not a
+ pipe. This type can't be used for output files.
+
+EFFECTS
+ Only one effect from the palette may be applied to a sound
+ sample. To do multiple effects you'll need to run sox in
+ a pipeline.
+
+ avg [ -l | -r ]
+ Reduce the number of channels by averaging the
+ samples, or duplicate channels to increase the
+ number of channels. Valid combinations are 1 -
+ 2, 1 - 4, 2 - 4, 4 - 2, 4 - 1, 2 - 1. The -l or
+ -r option averages from just left or right chan-
+ nels/duplicates to just the left or right chan-
+ nels.
+
+ band [ -n ] center [ width ]
+ Apply a band-pass filter. The frequency
+ response drops logarithmically around the center
+ frequency. The width gives the slope of the
+ drop. The frequencies at center + width and
+ center - width will be half of their original
+ amplitudes. Band defaults to a mode oriented to
+ pitched signals, i.e. voice, singing, or instru-
+ mental music. The -n (for noise) option uses
+ the alternate mode for un-pitched signals. Band
+ introduces noise in the shape of the filter,
+ i.e. peaking at the center frequency and set-
+ tling around it.
+
+ chorus gain-in gain-out delay decay speed deptch
+
+
+
+
+ September 6, 1998 7
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ -s | -t [ delay decay speed depth -s | -t ... ]
+ Add a chorus to a sound sample. Each quadtuple
+ delay/decay/speed/depth gives the delay in mil-
+ liseconds and the decay (relative to gain-in)
+ with a modulation speed in Hz using depth in
+ milliseconds. The modulation is either sinodial
+ (-s) or triangular (-t). Gain-out is the volume
+ of the output.
+
+ copy Copy the input file to the output file. This is
+ the default effect if both files have the same
+ sampling rate, or the rates are "close".
+
+ cut loopnumber
+ Extract loop #N from a sample.
+
+ deemph Apply a treble attenuation shelving filter to
+ samples in audio cd format. The frequency
+ response of pre-emphasized recordings is recti-
+ fied. The filtering is defined in the standard
+ document ISO 908.
+
+ echo gain-in gain-out delay decay [ delay decay ... ]
+ Add echoing to a sound sample. Each delay/decay
+ part gives the delay in milliseconds and the
+ decay (relative to gain-in) of that echo. Gain-
+ out is the volume of the output.
+
+ echos gain-in gain-out delay decay [ delay decay ... ]
+ Add a sequence of echos to a sound sample. Each
+ delay/decay part gives the delay in milliseconds
+ and the decay (relative to gain-in) of that
+ echo. Gain-out is the volume of the output.
+
+ flanger gain-in gain-out delay decay speed -s | -t
+ Add a flanger to a sound sample. Each triple
+ delay/decay/speed gives the delay in millisec-
+ onds and the decay (relative to gain-in) with a
+ modulation speed in Hz. The modulation is
+ either sinodial (-s) or triangular (-t). Gain-
+ out is the volume of the output.
+
+ highp center
+ Apply a high-pass filter. The frequency
+ response drops logarithmically with center fre-
+ quency in the middle of the drop. The slope of
+ the filter is quite gentle.
+
+ lowp center
+ Apply a low-pass filter. The frequency response
+ drops logarithmically with center frequency in
+ the middle of the drop. The slope of the filter
+ is quite gentle.
+
+
+
+
+ September 6, 1998 8
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ map Display a list of loops in a sample, and miscel-
+ laneous loop info.
+
+ mask Add "masking noise" to signal. This effect
+ deliberately adds white noise to a sound in
+ order to mask quantization effects, created by
+ the process of playing a sound digitally. It
+ tends to mask buzzing voices, for example. It
+ adds 1/2 bit of noise to the sound file at the
+ output bit depth.
+
+ phaser gain-in gain-out delay decay speed -s | -t
+ Add a phaser to a sound sample. Each triple
+ delay/decay/speed gives the delay in millisec-
+ onds and the decay (relative to gain-in) with a
+ modulation speed in Hz. The modulation is
+ either sinodial (-s) or triangular (-t). The
+ decay should be less than 0.5 to avoid feedback.
+ Gain-out is the volume of the output.
+
+ pick Select the left or right channel of a stereo
+ sample, or one of four channels in a quadro-
+ phonic sample.
+
+ polyphase [ -w < num / ham > ]
+
+ [ -width < long / short / # > ]
+
+ [ -cutoff # ]
+ Translate input sampling rate to output sampling
+ rate via polyphase interpolation, a DSP algo-
+ rithm. This method is slow and uses lots of
+ RAM, but gives much better results then rate.
+ -w < nut / ham > : select either a Nuttal (~90
+ dB stopband) or Hamming (~43 dB stopband) win-
+ dow. Warning: Nuttall windows require 2x length
+ than Hamming windows. Default is nut.
+ -width long / short / # : specify the width of
+ the filter. long is 1024 samples; short is 128
+ samples. Alternatively, an exact number can be
+ used. Default is long.
+ -cutoff # : specify the filter cutoff frequency
+ in terms of fraction of bandwidth. If upsam-
+ pling, then this is the fraction of the orignal
+ signal that should go through. If downsampling,
+ this is the fraction of the signal left after
+ downsampling. Default is 0.95. Remember that
+ this is a float.
+
+
+ rate Translate input sampling rate to output sampling
+ rate via linear interpolation to the Least Com-
+ mon Multiple of the two sampling rates. This is
+ the default effect if the two files have
+
+
+
+ September 6, 1998 9
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ different sampling rates. This is fast but
+ noisy: the spectrum of the original sound will
+ be shifted upwards and duplicated faintly when
+ up-translating by a multiple. Lerp-ing is
+ acceptable for cheap 8-bit sound hardware, but
+ for CD-quality sound you should instead use
+ either resample or polyphase. If you are won-
+ dering which of Sox's rate changing effects to
+ ues, you will want to read a detailed analysis
+ of all of them at http://usa.ece.cmu.edu/Sox/
+
+ resample [ rolloff [ beta ] ]
+ Translate input sampling rate to output sampling
+ rate via simulated analog filtration. This
+ method is slow and uses lots of RAM, but gives
+ much better results then rate (This has empiri-
+ cally been shown to be false. The resample
+ algorthym needs to be updated from its original
+ source).
+
+ reverb gain-out delay [ delay ... ]
+ Add reverbation to a sound sample. Each delay
+ is given in milliseconds and its feedback is
+ depending on the reverb-time in milliseconds.
+ Each delay should be in the range of half to
+ quarter of reverb-time to get a realistic rever-
+ bation. Gain-out is the volume of the output.
+
+ reverse Reverse the sound sample completely. Included
+ for finding Satanic subliminals.
+
+ split Turn a mono sample into a stereo sample by copy-
+ ing the input channel to the left and right
+ channels.
+
+ stat [ debug | -v ]
+ Do a statistical check on the input file, and
+ print results on the standard error file. stat
+ may copy the file untouched from input to out-
+ put, if you select an output file. The "Volume
+ Adjustment:" field in the statistics gives you
+ the argument to the -v number which will make
+ the sample as loud as possible without clipping.
+ There is an optional parameter -v that will
+ print out the "Volume Adjustment:" field's value
+ and return. This could be of use in scripts to
+ auto convert the volume. There is an also an
+ optional parameter debug that will place sox
+ into debug mode and print out a hex dump of the
+ sound file from the internal buffer that is in
+ 32-bit signed PCM data. This is mainly only of
+ use in tracking down endian problems that creep
+ in to sox on cross-platform versions.
+
+
+
+
+ September 6, 1998 10
+
+
+
+
+
+SOX(1) SOX(1)
+
+
+ vibro speed [ depth ]
+ Add the world-famous Fender Vibro-Champ sound
+ effect to a sound sample by using a sine wave as
+ the volume knob. Speed gives the Hertz value of
+ the wave. This must be under 30. Depth gives
+ the amount the volume is cut into by the sine
+ wave, ranging 0.0 to 1.0 and defaulting to 0.5.
+
+ Sox enforces certain effects. If the two files have dif-
+ ferent sampling rates, the requested effect must be one of
+ copy, or rate, If the two files have different numbers of
+ channels, the avg effect must be requested.
+
+BUGS
+ The syntax is horrific. It's very tempting to include a
+ default system that allows an effect name as the program
+ name and just pipes a sound sample from standard input to
+ standard output, but the problem of inputting the sample
+ rates makes this unworkable.
+
+ Please report any bugs found in this version of sox to
+ Chris Bagwell (cbagwell@sprynet.com)
+
+FILES
+SEE ALSO
+ play(1), rec(1)
+
+NOTICES
+ The echoplex effect is: Copyright (C) 1989 by Jef
+ Poskanzer.
+
+ Permission to use, copy, modify, and distribute this soft-
+ ware and its documentation for any purpose and without fee
+ is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation. This software is provided "as is" without
+ express or implied warranty.
+
+ The version of Sox that accompanies this manual page is
+ support by Chris Bagwell (cbagwell@sprynet.com). Please
+ refer any questions regarding it to this address. You may
+ obtain the latest version at the the web site
+ http://home.sprynet.com/sprynet/cbagwell/projects.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+ September 6, 1998 11
+
+
--- /dev/null
+++ b/soxeffect
@@ -1,0 +1,82 @@
+#!/bin/sh
+#
+# soxeffect - When this script is ran using a different name then soxeffect
+# it will run sox using that name as the effect. It uses stdin/stdout
+# to grab data and output data.
+#
+# TODO: It would be nice to specify different output parameters then
+# the input format.
+#
+
+# Some people prefer to rename sox to something like sox.bin, then use this
+# script to always run sox, using "ln -s soxeffect sox".
+
+SOX=/usr/local/bin/sox
+# SOX=/usr/local/bin/sox.bin
+
+help()
+{
+ echo "soxeffect v1.0 - effects front end to Sox"
+ echo ""
+ echo "Usage: [effectname] [ fopts ] [effectopts]"
+ echo
+ echo "When ran as the name of an effect that Sox supports, it will take"
+ echo "audio data from stdin, apply the effect, and write the output back"
+ echo "to stdout. This means that [ fopts ] need to be given so that"
+ echo "sox will know what format the audio data is in."
+ echo
+ echo "effectname: avg/band/chorus/copy/cut/deemph/echo/echos/flanger/highp/lowp/map/mask/phaser/pick/polyphase/rate/resample/reverb/reverse/split/stat/vibro"
+ echo
+ echo "fopts: -c channels -h -r rate -t type -v volume -s/-u/-U/-A -b/-w/-l/-f/-d/-D -x"
+ echo ""
+ echo "See sox man page for more info on required effects options."
+}
+
+NAME=$0
+case $NAME in
+ */*)
+ NAME=`echo $NAME | sed "s'^.*/''"`
+ ;;
+esac
+
+while [ $# -ne 0 ] # loop over arguments
+do case $1 in
+ -c)
+ shift
+ fopts="$fopts -c $1"
+ ;;
+ -h)
+ help;
+ exit 1;
+ ;;
+ -r)
+ shift
+ fopts="$fopts -r $1"
+ ;;
+ -t)
+ shift
+ fopts="$fopts -t $1"
+ ;;
+ -v)
+ shift
+ volume="-v $1"
+ ;;
+ -*)
+ fopts="$fopts $1"
+ ;;
+ *)
+ effectopts="$@"
+ break;
+ ;;
+ esac
+ shift
+done
+
+case $NAME in
+ *sox)
+ exec $SOX $*
+ ;;
+ *avg|*band|*chorus|*copy|*cut|*deemph|*echo|*echos|*flanger|*Highp|*lowp|*map|*mask|*Phaser|*pick|*polyphase|*rate|*resample|*reverb|*reverse|*split|*stat|*vibro)
+ $SOX $volume $fopts - $fopts - $NAME $effectopts
+ ;;
+esac
--- /dev/null
+++ b/split.c
@@ -1,0 +1,130 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * "split" effect by Lauren Weinstein (lauren@vortex.com); 2/94
+ * Splits 1 channel file to 2 channels (stereo), or 4 channels (quad);
+ * or splits a 2 channel file to 4 channels.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for split */
+typedef struct splitstuff {
+ int rest; /* bytes remaining in current block */
+} *split_t;
+
+/*
+ * Process options
+ */
+void
+split_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Split effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ */
+void
+split_start(effp)
+eff_t effp;
+{
+ switch (effp->ininfo.channels) {
+ case 1: /* 1 channel must split to 2 or 4 */
+ switch(effp->outinfo.channels) {
+ case 2:
+ case 4:
+ return;
+ }
+ break;
+ case 2: /* 2 channels must split to 4 */
+ switch(effp->outinfo.channels) {
+ case 4:
+ return;
+ }
+ break;
+ }
+ fail("Can't split %d channels into %d channels",
+ effp->ininfo.channels, effp->outinfo.channels);
+}
+
+/*
+ * Process signed long samples from ibuf to obuf,
+ * isamp or osamp samples, whichever is smaller,
+ * while splitting into appropriate channels.
+ */
+
+void split_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ int len, done;
+
+ switch(effp->ininfo.channels) {
+ case 1: /* 1 input channel */
+ switch(effp->outinfo.channels) {
+ case 2: /* split to 2 channels */
+ len = ((*isamp > *osamp/2)
+ ? *osamp/2 : *isamp);
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[1] = *ibuf++;
+ obuf += 2;
+ }
+ *isamp = len;
+ *osamp = len * 2;
+ break;
+ case 4: /* split to 4 channels */
+ len = ((*isamp > *osamp/4)
+ ? *osamp/4 : *isamp);
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[1] = obuf[2]
+ = obuf[3] = *ibuf++;
+ obuf += 4;
+ }
+ *isamp = len;
+ *osamp = len * 4;
+ break;
+ }
+ break;
+ case 2: /* 2 input channels; split to 4 channels */
+ /* We're using the same channel ordering */
+ /* as in "avg.c"--sure hope it's correct! */
+ len = ((*isamp/2 > *osamp/4)
+ ? *osamp/4 : *isamp/2);
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[2] = ibuf[0];
+ obuf[1] = obuf[3] = ibuf[1];
+ ibuf += 2;
+ obuf += 4;
+ }
+ *isamp = len;
+ *osamp = len * 2;
+ break;
+ }
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void split_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+
--- /dev/null
+++ b/src/8svx.c
@@ -1,0 +1,336 @@
+/*
+ * Amiga 8SVX format handler: W V Neisius, February 1992
+ */
+
+#include <math.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef VMS
+#include <perror.h>
+#endif
+#include "st.h"
+
+/* Private data used by writer */
+struct svxpriv {
+ ULONG nsamples;
+ FILE *ch[4];
+};
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+void svxwriteheader(P2(ft_t, LONG));
+
+/*======================================================================*/
+/* 8SVXSTARTREAD */
+/*======================================================================*/
+
+void svxstartread(ft)
+ft_t ft;
+{
+ struct svxpriv *p = (struct svxpriv *) ft->priv;
+
+ char buf[12];
+ char *endptr;
+ char *chunk_buf;
+
+ ULONG totalsize;
+ ULONG chunksize;
+
+ int channels;
+ LONG rate;
+ int littlendian = 0;
+ int i;
+
+ ULONG chan1_pos;
+
+ rate = 0;
+ channels = 1;
+
+ /* read FORM chunk */
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "FORM", 4) != 0)
+ fail("8SVX: header does not begin with magic word 'FORM'");
+ totalsize = rblong(ft);
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "8SVX", 4) != 0)
+ fail("8SVX: 'FORM' chunk does not specify '8SVX' as type");
+
+ /* read chunks until 'BODY' (or end) */
+ while (fread(buf,1,4,ft->fp) == 4 && strncmp(buf,"BODY",4) != 0) {
+ if (strncmp(buf,"VHDR",4) == 0) {
+ chunksize = rblong(ft);
+ if (chunksize != 20)
+ fail ("8SVX: VHDR chunk has bad size");
+ fseek(ft->fp,12,SEEK_CUR);
+ rate = rbshort(ft);
+ fseek(ft->fp,1,SEEK_CUR);
+ fread(buf,1,1,ft->fp);
+ if (buf[0] != 0)
+ fail ("8SVX: unsupported data compression");
+ fseek(ft->fp,4,SEEK_CUR);
+ continue;
+ }
+
+ if (strncmp(buf,"ANNO",4) == 0) {
+ chunksize = rblong(ft);
+ if (chunksize & 1)
+ chunksize++;
+ chunk_buf = (char *) malloc(chunksize + 1);
+ if (fread(chunk_buf,1,(size_t)chunksize,ft->fp)
+ != chunksize)
+ fail("8SVX: Unexpected EOF in ANNO header");
+ chunk_buf[chunksize] = '\0';
+ report ("%s",chunk_buf);
+ free(chunk_buf);
+
+ continue;
+ }
+
+ if (strncmp(buf,"NAME",4) == 0) {
+ chunksize = rblong(ft);
+ if (chunksize & 1)
+ chunksize++;
+ chunk_buf = (char *) malloc(chunksize + 1);
+ if (fread (chunk_buf,1,(size_t)chunksize,ft->fp)
+ != chunksize)
+ fail("8SVX: Unexpected EOF in NAME header");
+ chunk_buf[chunksize] = '\0';
+ report ("%s",chunk_buf);
+ free(chunk_buf);
+
+ continue;
+ }
+
+ if (strncmp(buf,"CHAN",4) == 0) {
+ chunksize = rblong(ft);
+ if (chunksize != 4)
+ fail("8SVX: Short channel chunk");
+ channels = rblong(ft);
+ channels = (channels & 0x01) +
+ ((channels & 0x02) >> 1) +
+ ((channels & 0x04) >> 2) +
+ ((channels & 0x08) >> 3);
+
+ continue;
+ }
+
+ /* some other kind of chunk */
+ chunksize = rblong(ft);
+ if (chunksize & 1)
+ chunksize++;
+ fseek(ft->fp,chunksize,SEEK_CUR);
+ continue;
+
+ }
+
+ if (rate == 0)
+ fail ("8SVX: invalid rate");
+ if (strncmp(buf,"BODY",4) != 0)
+ fail ("8SVX: BODY chunk not found");
+ p->nsamples = rblong(ft);
+
+ ft->info.channels = channels;
+ ft->info.rate = rate;
+ ft->info.style = SIGN2;
+ ft->info.size = BYTE;
+
+ /* open files to channels */
+ p->ch[0] = ft->fp;
+ chan1_pos = ftell(p->ch[0]);
+
+ for (i = 1; i < channels; i++) {
+ if ((p->ch[i] = fopen(ft->filename, READBINARY)) == NULL)
+ fail("Can't open channel file '%s': %s",
+ ft->filename, strerror(errno));
+
+ /* position channel files */
+ if (fseek(p->ch[i],chan1_pos,SEEK_SET))
+ fail ("Can't position channel %d: %s",i,strerror(errno));
+ if (fseek(p->ch[i],p->nsamples/channels*i,SEEK_CUR))
+ fail ("Can't seek channel %d: %s",i,strerror(errno));
+ }
+
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1)
+ ft->swap = 1;
+}
+
+/*======================================================================*/
+/* 8SVXREAD */
+/*======================================================================*/
+LONG svxread(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ ULONG datum;
+ int done = 0;
+ int i;
+
+ struct svxpriv *p = (struct svxpriv *) ft->priv;
+
+ while (done < nsamp) {
+ for (i = 0; i < ft->info.channels; i++) {
+ datum = getc(p->ch[i]);
+ if (feof(p->ch[i]))
+ return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ }
+ done += ft->info.channels;
+ }
+ return done;
+}
+
+/*======================================================================*/
+/* 8SVXSTOPREAD */
+/*======================================================================*/
+void svxstopread(ft)
+ft_t ft;
+{
+ int i;
+
+ struct svxpriv *p = (struct svxpriv *) ft->priv;
+
+ /* close channel files */
+ for (i = 1; i < ft->info.channels; i++) {
+ fclose (p->ch[i]);
+ }
+}
+
+/*======================================================================*/
+/* 8SVXSTARTWRITE */
+/*======================================================================*/
+void svxstartwrite(ft)
+ft_t ft;
+{
+ struct svxpriv *p = (struct svxpriv *) ft->priv;
+ int littlendian = 0;
+ int i;
+ char *endptr;
+
+ /* open channel output files */
+ p->ch[0] = ft->fp;
+ for (i = 1; i < ft->info.channels; i++) {
+ if ((p->ch[i] = tmpfile()) == NULL)
+ fail("Can't open channel output file: %s",
+ strerror(errno));
+ }
+
+ /* write header (channel 0) */
+ ft->info.style = SIGN2;
+ ft->info.size = BYTE;
+
+ p->nsamples = 0;
+ svxwriteheader(ft, p->nsamples);
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1)
+ ft->swap = 1;
+}
+
+/*======================================================================*/
+/* 8SVXWRITE */
+/*======================================================================*/
+
+void svxwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ struct svxpriv *p = (struct svxpriv *) ft->priv;
+
+ LONG datum;
+ int done = 0;
+ int i;
+
+ p->nsamples += len;
+
+ while(done < len) {
+ for (i = 0; i < ft->info.channels; i++) {
+ datum = RIGHT(*buf++, 24);
+ putc((int)datum, p->ch[i]);
+ }
+ done += ft->info.channels;
+ }
+}
+
+/*======================================================================*/
+/* 8SVXSTOPWRITE */
+/*======================================================================*/
+
+void svxstopwrite(ft)
+ft_t ft;
+{
+ struct svxpriv *p = (struct svxpriv *) ft->priv;
+
+ int i;
+ int len;
+ char svxbuf[512];
+
+ /* append all channel pieces to channel 0 */
+ /* close temp files */
+ for (i = 1; i < ft->info.channels; i++) {
+ if (fseek (p->ch[i], 0L, 0))
+ fail ("Can't rewind channel output file %d",i);
+ while (!feof(p->ch[i])) {
+ len = fread (svxbuf, 1, 512, p->ch[i]);
+ fwrite (svxbuf, 1, len, p->ch[0]);
+ }
+ fclose (p->ch[i]);
+ }
+
+ /* add a pad byte if BODY size is odd */
+ if(p->nsamples % 2 != 0)
+ fputc('\0', ft->fp);
+
+ /* fixup file sizes in header */
+ if (fseek(ft->fp, 0L, 0) != 0)
+ fail("can't rewind output file to rewrite 8SVX header");
+ svxwriteheader(ft, p->nsamples);
+}
+
+/*======================================================================*/
+/* 8SVXWRITEHEADER */
+/*======================================================================*/
+#define SVXHEADERSIZE 100
+void svxwriteheader(ft,nsamples)
+ft_t ft;
+LONG nsamples;
+{
+ LONG formsize = nsamples + SVXHEADERSIZE - 8;
+
+ /* FORM size must be even */
+ if(formsize % 2 != 0) formsize++;
+
+ fputs ("FORM", ft->fp);
+ wblong(ft, formsize); /* size of file */
+ fputs("8SVX", ft->fp); /* File type */
+
+ fputs ("VHDR", ft->fp);
+ wblong(ft, (LONG) 20); /* number of bytes to follow */
+ wblong(ft, nsamples); /* samples, 1-shot */
+ wblong(ft, (LONG) 0); /* samples, repeat */
+ wblong(ft, (LONG) 0); /* samples per repeat cycle */
+ wbshort(ft, (int) ft->info.rate); /* samples per second */
+ fputc(1,ft->fp); /* number of octaves */
+ fputc(0,ft->fp); /* data compression (none) */
+ wbshort(ft,1); wbshort(ft,0); /* volume */
+
+ fputs ("ANNO", ft->fp);
+ wblong(ft, (LONG) 32); /* length of block */
+ fputs ("File created by Sound Exchange ", ft->fp);
+
+ fputs ("CHAN", ft->fp);
+ wblong(ft, (LONG) 4);
+ wblong(ft, (ft->info.channels == 2) ? (LONG) 6 :
+ (ft->info.channels == 4) ? (LONG) 15 : (LONG) 2);
+
+ fputs ("BODY", ft->fp);
+ wblong(ft, nsamples); /* samples in file */
+}
--- /dev/null
+++ b/src/aiff.c
@@ -1,0 +1,776 @@
+/*
+ * September 25, 1991
+ * Copyright 1991 Guido van Rossum And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools SGI/Amiga AIFF format.
+ * Used by SGI on 4D/35 and Indigo.
+ * This is a subformat of the EA-IFF-85 format.
+ * This is related to the IFF format used by the Amiga.
+ * But, apparently, not the same.
+ *
+ * Jan 93: new version from Guido Van Rossum that
+ * correctly skips unwanted sections.
+ *
+ * Jan 94: add loop & marker support
+ * Jul 97: added comments I/O by Leigh Smith
+ * Nov 97: added verbose chunk comments
+ *
+ * June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Fixed compile warnings reported by Kjetil Torgrim Homme
+ * <kjetilho@ifi.uio.no>
+ *
+ * Sept 9, 1998 - fixed loop markers.
+ *
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "st.h"
+
+#ifndef SEEK_SET
+#define SEEK_SET 0 /* nasty nasty */
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1 /* nasty nasty */
+#endif /* SEEK_CUR */
+
+/* Private data used by writer */
+struct aiffpriv {
+ ULONG nsamples; /* number of 1-channel samples read or written */
+};
+
+double read_ieee_extended();
+LONG rawread(P3(ft_t, LONG *, LONG));
+void aiffwriteheader(P2(ft_t, LONG));
+void rawwrite(P3(ft_t, LONG *, LONG));
+void write_ieee_extended(P2(ft_t, double));
+double ConvertFromIeeeExtended();
+void ConvertToIeeeExtended(P2(double, char *));
+void textChunk(P3(char **text, char *chunkDescription, ft_t ft));
+void reportInstrument(P1(ft_t ft));
+
+void aiffstartread(ft)
+ft_t ft;
+{
+ struct aiffpriv *p = (struct aiffpriv *) ft->priv;
+ char buf[5];
+ ULONG totalsize;
+ LONG chunksize;
+ int channels = 0;
+ ULONG frames;
+ int bits = 0;
+ double rate = 0.0;
+ ULONG offset = 0;
+ ULONG blocksize = 0;
+ int littlendian = 0;
+ char *endptr;
+ int foundcomm = 0, foundmark = 0, foundinstr = 0;
+ struct mark {
+ int id, position;
+ char name[40];
+ } marks[32];
+ int i, j;
+ LONG nmarks = 0;
+ LONG sustainLoopBegin = 0, sustainLoopEnd = 0,
+ releaseLoopBegin = 0, releaseLoopEnd = 0;
+ LONG seekto = 0L, ssndsize = 0L;
+ char *author;
+ char *copyright;
+ char *nametext;
+
+
+ /* FORM chunk */
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "FORM", 4) != 0)
+ fail("AIFF header does not begin with magic word 'FORM'");
+ totalsize = rblong(ft);
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "AIFF", 4) != 0)
+ fail("AIFF 'FORM' chunk does not specify 'AIFF' as type");
+
+
+ /* Skip everything but the COMM chunk and the SSND chunk */
+ /* The SSND chunk must be the last in the file */
+ while (1) {
+ if (fread(buf, 1, 4, ft->fp) != 4)
+ if (ssndsize > 0)
+ break;
+ else
+ fail("Missing SSND chunk in AIFF file");
+
+ if (strncmp(buf, "COMM", 4) == 0) {
+ /* COMM chunk */
+ chunksize = rblong(ft);
+ if (chunksize != 18)
+ fail("AIFF COMM chunk has bad size");
+ channels = rbshort(ft);
+ frames = rblong(ft);
+ bits = rbshort(ft);
+ rate = read_ieee_extended(ft);
+ foundcomm = 1;
+ }
+ else if (strncmp(buf, "SSND", 4) == 0) {
+ /* SSND chunk */
+ chunksize = rblong(ft);
+ offset = rblong(ft);
+ blocksize = rblong(ft);
+ chunksize -= 8;
+ ssndsize = chunksize;
+ /* if can't seek, just do sound now */
+ if (!ft->seekable)
+ break;
+ /* else, seek to end of sound and hunt for more */
+ seekto = ftell(ft->fp);
+ fseek(ft->fp, chunksize, SEEK_CUR);
+ }
+ else if (strncmp(buf, "MARK", 4) == 0) {
+ /* MARK chunk */
+ chunksize = rblong(ft);
+ nmarks = rbshort(ft);
+ chunksize -= 2;
+ for(i = 0; i < nmarks; i++) {
+ int len;
+
+ marks[i].id = rbshort(ft);
+ marks[i].position = rblong(ft);
+ chunksize -= 6;
+ len = getc(ft->fp);
+ chunksize -= len + 1;
+ for(j = 0; j < len ; j++)
+ marks[i].name[j] = getc(ft->fp);
+ marks[i].name[j] = 0;
+ if ((len & 1) == 0) {
+ chunksize--;
+ getc(ft->fp);
+ }
+ }
+ /* HA HA! Sound Designer (and others) makes */
+ /* bogus files. It spits out bogus chunksize */
+ /* for MARK field */
+ while(chunksize-- > 0)
+ getc(ft->fp);
+ foundmark = 1;
+ }
+ else if (strncmp(buf, "INST", 4) == 0) {
+ /* INST chunk */
+ chunksize = rblong(ft);
+ ft->instr.MIDInote = getc(ft->fp);
+ getc(ft->fp); /* detune */
+ ft->instr.MIDIlow = getc(ft->fp);
+ ft->instr.MIDIhi = getc(ft->fp);
+ getc(ft->fp); /* low velocity */
+ getc(ft->fp); /* hi velocity */
+ rbshort(ft); /* gain */
+ ft->loops[0].type = rbshort(ft); /* sustain loop */
+ sustainLoopBegin = rbshort(ft); /* begin marker */
+ sustainLoopEnd = rbshort(ft); /* end marker */
+ ft->loops[1].type = rbshort(ft); /* release loop */
+ releaseLoopBegin = rbshort(ft); /* begin marker */
+ releaseLoopEnd = rbshort(ft); /* end marker */
+ foundinstr = 1;
+ }
+ else if (strncmp(buf, "APPL", 4) == 0) {
+ chunksize = rblong(ft);
+ while(chunksize-- > 0)
+ getc(ft->fp);
+ }
+ else if (strncmp(buf, "ALCH", 4) == 0) {
+ /* I think this is bogus and gets grabbed by APPL */
+ /* INST chunk */
+ rblong(ft); /* ENVS - jeez! */
+ chunksize = rblong(ft);
+ while(chunksize-- > 0)
+ getc(ft->fp);
+ }
+ else if (strncmp(buf, "ANNO", 4) == 0) {
+ /* Old form of comment chunk */
+ chunksize = rblong(ft);
+ /* allocate enough memory to hold the comment */
+ ft->comment = (char *) malloc((size_t) chunksize);
+ if (ft->comment == NULL)
+ fail("AIFF: Couldn't allocate ANNO header");
+ if (fread(ft->comment, 1, chunksize, ft->fp) != chunksize)
+ fail("AIFF: Unexpected EOF in ANNO header");
+ }
+ else if (strncmp(buf, "AUTH", 4) == 0) {
+ /* Author chunk */
+ textChunk(&author, "Author:", ft);
+ free(author);
+ }
+ else if (strncmp(buf, "NAME", 4) == 0) {
+ /* Name chunk */
+ textChunk(&nametext, "Name:", ft);
+ free(nametext);
+ }
+ else if (strncmp(buf, "(c) ", 4) == 0) {
+ /* Copyright chunk */
+ textChunk(©right, "Copyright:", ft);
+ free(copyright);
+ }
+ else {
+ buf[4] = 0;
+ /* bogus file, probably from the Mac */
+ if ((buf[0] < 'A' || buf[0] > 'Z') ||
+ (buf[1] < 'A' || buf[1] > 'Z') ||
+ (buf[2] < 'A' || buf[2] > 'Z') ||
+ (buf[3] < 'A' || buf[3] > 'Z'))
+ break;
+ if (feof(ft->fp))
+ break;
+ report("AIFFstartread: ignoring '%s' chunk\n", buf);
+ chunksize = rblong(ft);
+ if (feof(ft->fp))
+ break;
+ /* Skip the chunk using getc() so we may read
+ from a pipe */
+ while (chunksize-- > 0) {
+ if (getc(ft->fp) == EOF)
+ break;
+ }
+ }
+ if (feof(ft->fp))
+ break;
+ }
+
+ /*
+ * if a pipe, we lose all chunks after sound.
+ * Like, say, instrument loops.
+ */
+ if (ft->seekable)
+ if (seekto > 0)
+ fseek(ft->fp, seekto, SEEK_SET);
+ else
+ fail("AIFF: no sound data on input file");
+
+ /* SSND chunk just read */
+ if (blocksize != 0)
+ fail("AIFF header specifies nonzero blocksize?!?!");
+ while ((LONG) (--offset) >= 0) {
+ if (getc(ft->fp) == EOF)
+ fail("unexpected EOF while skipping AIFF offset");
+ }
+
+ if (foundcomm) {
+ ft->info.channels = channels;
+ ft->info.rate = rate;
+ ft->info.style = SIGN2;
+ switch (bits) {
+ case 8:
+ ft->info.size = BYTE;
+ break;
+ case 16:
+ ft->info.size = WORD;
+ break;
+ default:
+ fail("unsupported sample size in AIFF header: %d", bits);
+ /*NOTREACHED*/
+ }
+ } else {
+ if ((ft->info.channels == -1)
+ || (ft->info.rate == -1)
+ || (ft->info.style == -1)
+ || (ft->info.size == -1)) {
+ report("You must specify # channels, sample rate, signed/unsigned,\n");
+ report("and 8/16 on the command line.");
+ fail("Bogus AIFF file: no COMM section.");
+ }
+
+ }
+
+ p->nsamples = ssndsize / ft->info.size; /* leave out channels */
+
+ /* process instrument and marker notations. */
+ if (foundmark && !foundinstr)
+ fail("Bogus AIFF file: MARKers but no INSTrument.");
+ if (!foundmark && foundinstr)
+ fail("Bogus AIFF file: INSTrument but no MARKers.");
+ if (foundmark && foundinstr) {
+ int i;
+ int slbIndex = 0, sleIndex = 0;
+ int rlbIndex = 0, rleIndex = 0;
+
+ /* find our loop markers and save their marker indexes */
+ for(i = 0; i < nmarks; i++) {
+ if(marks[i].id == sustainLoopBegin)
+ slbIndex = i;
+ if(marks[i].id == sustainLoopEnd)
+ sleIndex = i;
+ if(marks[i].id == releaseLoopBegin)
+ rlbIndex = i;
+ if(marks[i].id == releaseLoopEnd)
+ rleIndex = i;
+ }
+
+ ft->instr.nloops = 0;
+ if (ft->loops[0].type != 0) {
+ ft->loops[0].start = marks[slbIndex].position;
+ ft->loops[0].length =
+ marks[sleIndex].position - marks[slbIndex].position;
+ /* really the loop count should be infinite */
+ ft->loops[0].count = 1;
+ ft->instr.loopmode = LOOP_SUSTAIN_DECAY | ft->loops[0].type;
+ ft->instr.nloops++;
+ }
+ if (ft->loops[1].type != 0) {
+ ft->loops[1].start = marks[rlbIndex].position;
+ ft->loops[1].length =
+ marks[rleIndex].position - marks[rlbIndex].position;
+ /* really the loop count should be infinite */
+ ft->loops[1].count = 1;
+ ft->instr.loopmode = LOOP_SUSTAIN_DECAY | ft->loops[1].type;
+ ft->instr.nloops++;
+ }
+ }
+ if (verbose)
+ reportInstrument(ft);
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1)
+ ft->swap = 1;
+}
+
+/* print out the MIDI key allocations, loop points, directions etc */
+void reportInstrument(ft)
+ft_t ft;
+{
+ int loopNum;
+
+ if(ft->instr.nloops > 0)
+ fprintf(stderr, "AIFF Loop markers:\n");
+ for(loopNum = 0; loopNum < ft->instr.nloops; loopNum++) {
+ if (ft->loops[loopNum].count) {
+ fprintf(stderr, "Loop %d: start: %6d", loopNum, ft->loops[loopNum].start);
+ fprintf(stderr, " end: %6d",
+ ft->loops[loopNum].start + ft->loops[loopNum].length);
+ fprintf(stderr, " count: %6d", ft->loops[loopNum].count);
+ fprintf(stderr, " type: ");
+ switch(ft->loops[loopNum].type & ~LOOP_SUSTAIN_DECAY) {
+ case 0: fprintf(stderr, "off\n"); break;
+ case 1: fprintf(stderr, "forward\n"); break;
+ case 2: fprintf(stderr, "forward/backward\n"); break;
+ }
+ }
+ }
+ fprintf(stderr, "Unity MIDI Note: %d\n", ft->instr.MIDInote);
+ fprintf(stderr, "Low MIDI Note: %d\n", ft->instr.MIDIlow);
+ fprintf(stderr, "High MIDI Note: %d\n", ft->instr.MIDIhi);
+}
+
+/* Process a text chunk, allocate memory, display it if verbose and return */
+void textChunk(text, chunkDescription, ft)
+char **text;
+char *chunkDescription;
+ft_t ft;
+{
+ LONG chunksize = rblong(ft);
+ /* allocate enough memory to hold the text including a terminating \0 */
+ *text = (char *) malloc((size_t) chunksize + 1);
+ if (*text == NULL)
+ fail("AIFF: Couldn't allocate %s header", chunkDescription);
+ if (fread(*text, 1, chunksize, ft->fp) != chunksize)
+ fail("AIFF: Unexpected EOF in %s header", chunkDescription);
+ *(*text + chunksize) = '\0';
+ if(verbose) {
+ printf("%-10s \"%s\"\n", chunkDescription, *text);
+ }
+}
+
+LONG aiffread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ struct aiffpriv *p = (struct aiffpriv *) ft->priv;
+
+ /* just read what's left of SSND chunk */
+ if (len > p->nsamples)
+ len = p->nsamples;
+ rawread(ft, buf, len);
+ p->nsamples -= len;
+ return len;
+}
+
+void aiffstopread(ft)
+ft_t ft;
+{
+ char buf[5];
+ ULONG chunksize;
+
+ if (!ft->seekable)
+ while (! feof(ft->fp)) {
+ if (fread(buf, 1, 4, ft->fp) != 4)
+ return;
+
+ chunksize = rblong(ft);
+ if (feof(ft->fp))
+ return;
+ buf[4] = '\0';
+ warn("Ignoring AIFF tail chunk: '%s', %d bytes long\n",
+ buf, chunksize);
+ if (! strcmp(buf, "MARK") || ! strcmp(buf, "INST"))
+ warn(" You're stripping MIDI/loop info!\n");
+ while ((LONG) (--chunksize) >= 0)
+ if (getc(ft->fp) == EOF)
+ return;
+ }
+ return;
+}
+
+/* When writing, the header is supposed to contain the number of
+ samples and data bytes written.
+ Since we don't know how many samples there are until we're done,
+ we first write the header with an very large number,
+ and at the end we rewind the file and write the header again
+ with the right number. This only works if the file is seekable;
+ if it is not, the very large size remains in the header.
+ Strictly spoken this is not legal, but the playaiff utility
+ will still be able to play the resulting file. */
+
+void aiffstartwrite(ft)
+ft_t ft;
+{
+ struct aiffpriv *p = (struct aiffpriv *) ft->priv;
+ int littlendian = 0;
+ char *endptr;
+
+ p->nsamples = 0;
+ if (ft->info.style == ULAW && ft->info.size == BYTE) {
+ report("expanding 8-bit u-law to 16 bits");
+ ft->info.size = WORD;
+ }
+ ft->info.style = SIGN2; /* We have a fixed style */
+ /* Compute the "very large number" so that a maximum number
+ of samples can be transmitted through a pipe without the
+ risk of causing overflow when calculating the number of bytes.
+ At 48 kHz, 16 bits stereo, this gives ~3 hours of music.
+ Sorry, the AIFF format does not provide for an "infinite"
+ number of samples. */
+ aiffwriteheader(ft, 0x7f000000L / (ft->info.size*ft->info.channels));
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1)
+ ft->swap = 1;
+}
+
+void aiffwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ struct aiffpriv *p = (struct aiffpriv *) ft->priv;
+ p->nsamples += len;
+ rawwrite(ft, buf, len);
+}
+
+void
+aiffstopwrite(ft)
+ft_t ft;
+{
+ struct aiffpriv *p = (struct aiffpriv *) ft->priv;
+ if (!ft->seekable)
+ return;
+ if (fseek(ft->fp, 0L, SEEK_SET) != 0)
+ fail("can't rewind output file to rewrite AIFF header");
+ aiffwriteheader(ft, p->nsamples / ft->info.channels);
+}
+
+void aiffwriteheader(ft, nframes)
+ft_t ft;
+LONG nframes;
+{
+ int hsize =
+ 8 /*COMM hdr*/ + 18 /*COMM chunk*/ +
+ 8 /*SSND hdr*/ + 12 /*SSND chunk*/;
+ int bits = 0;
+ int i;
+
+ hsize += 8 + 2 + 16*ft->instr.nloops; /* MARK chunk */
+ hsize += 20; /* INST chunk */
+
+ if (ft->info.style == SIGN2 && ft->info.size == BYTE)
+ bits = 8;
+ else if (ft->info.style == SIGN2 && ft->info.size == WORD)
+ bits = 16;
+ else
+ fail("unsupported output style/size for AIFF header");
+
+ fputs("FORM", ft->fp); /* IFF header */
+ wblong(ft, hsize + nframes * ft->info.size * ft->info.channels); /* file size */
+ fputs("AIFF", ft->fp); /* File type */
+
+ /* ANNO chunk -- holds comments text, however this is */
+ /* discouraged by Apple in preference to a COMT comments */
+ /* chunk, which holds a timestamp and marker id */
+ fputs("ANNO", ft->fp);
+ wblong(ft, (LONG) strlen(ft->comment)); /* ANNO chunk size, the No of chars */
+ fputs(ft->comment, ft->fp);
+
+ /* COMM chunk -- describes encoding (and #frames) */
+ fputs("COMM", ft->fp);
+ wblong(ft, (LONG) 18); /* COMM chunk size */
+ wbshort(ft, ft->info.channels); /* nchannels */
+ wblong(ft, nframes); /* number of frames */
+ wbshort(ft, bits); /* sample width, in bits */
+ write_ieee_extended(ft, (double)ft->info.rate);
+
+ /* MARK chunk -- set markers */
+ if (ft->instr.nloops) {
+ fputs("MARK", ft->fp);
+ if (ft->instr.nloops > 2)
+ ft->instr.nloops = 2;
+ wblong(ft, 2 + 16*ft->instr.nloops);
+ wbshort(ft, ft->instr.nloops);
+
+ for(i = 0; i < ft->instr.nloops; i++) {
+ wbshort(ft, i + 1);
+ wblong(ft, ft->loops[i].start);
+ fputc(0, ft->fp);
+ fputc(0, ft->fp);
+ wbshort(ft, i*2 + 1);
+ wblong(ft, ft->loops[i].start + ft->loops[i].length);
+ fputc(0, ft->fp);
+ fputc(0, ft->fp);
+ }
+
+ fputs("INST", ft->fp);
+ wblong(ft, 20);
+ /* random MIDI shit that we default on */
+ fputc(ft->instr.MIDInote, ft->fp);
+ fputc(0, ft->fp); /* detune */
+ fputc(ft->instr.MIDIlow, ft->fp);
+ fputc(ft->instr.MIDIhi, ft->fp);
+ fputc(1, ft->fp); /* low velocity */
+ fputc(127, ft->fp); /* hi velocity */
+ wbshort(ft, 0); /* gain */
+
+ /* sustain loop */
+ wbshort(ft, ft->loops[0].type);
+ wbshort(ft, 1); /* marker 1 */
+ wbshort(ft, 3); /* marker 3 */
+ /* release loop, if there */
+ if (ft->instr.nloops == 2) {
+ wbshort(ft, ft->loops[1].type);
+ wbshort(ft, 2); /* marker 2 */
+ wbshort(ft, 4); /* marker 4 */
+ } else {
+ wbshort(ft, 0); /* no release loop */
+ wbshort(ft, 0);
+ wbshort(ft, 0);
+ }
+ }
+
+ /* SSND chunk -- describes data */
+ fputs("SSND", ft->fp);
+ /* chunk size */
+ wblong(ft, 8 + nframes * ft->info.channels * ft->info.size);
+ wblong(ft, (LONG) 0); /* offset */
+ wblong(ft, (LONG) 0); /* block size */
+}
+
+double read_ieee_extended(ft)
+ft_t ft;
+{
+ char buf[10];
+ if (fread(buf, 1, 10, ft->fp) != 10)
+ fail("EOF while reading IEEE extended number");
+ return ConvertFromIeeeExtended(buf);
+}
+
+void write_ieee_extended(ft, x)
+ft_t ft;
+double x;
+{
+ char buf[10];
+ ConvertToIeeeExtended(x, buf);
+ /*
+ report("converted %g to %o %o %o %o %o %o %o %o %o %o",
+ x,
+ buf[0], buf[1], buf[2], buf[3], buf[4],
+ buf[5], buf[6], buf[7], buf[8], buf[9]);
+ */
+ (void) fwrite(buf, 1, 10, ft->fp);
+}
+
+
+/*
+ * C O N V E R T T O I E E E E X T E N D E D
+ */
+
+/* Copyright (C) 1988-1991 Apple Computer, Inc.
+ * All rights reserved.
+ *
+ * Machine-independent I/O routines for IEEE floating-point numbers.
+ *
+ * NaN's and infinities are converted to HUGE_VAL or HUGE, which
+ * happens to be infinity on IEEE machines. Unfortunately, it is
+ * impossible to preserve NaN's in a machine-independent way.
+ * Infinities are, however, preserved on IEEE machines.
+ *
+ * These routines have been tested on the following machines:
+ * Apple Macintosh, MPW 3.1 C compiler
+ * Apple Macintosh, THINK C compiler
+ * Silicon Graphics IRIS, MIPS compiler
+ * Cray X/MP and Y/MP
+ * Digital Equipment VAX
+ *
+ *
+ * Implemented by Malcolm Slaney and Ken Turkowski.
+ *
+ * Malcolm Slaney contributions during 1988-1990 include big- and little-
+ * endian file I/O, conversion to and from Motorola's extended 80-bit
+ * floating-point format, and conversions to and from IEEE single-
+ * precision floating-point format.
+ *
+ * In 1991, Ken Turkowski implemented the conversions to and from
+ * IEEE double-precision format, added more precision to the extended
+ * conversions, and accommodated conversions involving +/- infinity,
+ * NaN's, and denormalized numbers.
+ */
+
+#ifndef HUGE_VAL
+# define HUGE_VAL HUGE
+#endif /*HUGE_VAL*/
+
+# define FloatToUnsigned(f) ((ULONG)(((LONG)(f - 2147483648.0)) + 2147483647L) + 1)
+
+void ConvertToIeeeExtended(num, bytes)
+double num;
+char *bytes;
+{
+ int sign;
+ int expon;
+ double fMant, fsMant;
+ ULONG hiMant, loMant;
+
+ if (num < 0) {
+ sign = 0x8000;
+ num *= -1;
+ } else {
+ sign = 0;
+ }
+
+ if (num == 0) {
+ expon = 0; hiMant = 0; loMant = 0;
+ }
+ else {
+ fMant = frexp(num, &expon);
+ if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
+ expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
+ }
+ else { /* Finite */
+ expon += 16382;
+ if (expon < 0) { /* denormalized */
+ fMant = ldexp(fMant, expon);
+ expon = 0;
+ }
+ expon |= sign;
+ fMant = ldexp(fMant, 32);
+ fsMant = floor(fMant);
+ hiMant = FloatToUnsigned(fsMant);
+ fMant = ldexp(fMant - fsMant, 32);
+ fsMant = floor(fMant);
+ loMant = FloatToUnsigned(fsMant);
+ }
+ }
+
+ bytes[0] = expon >> 8;
+ bytes[1] = expon;
+ bytes[2] = hiMant >> 24;
+ bytes[3] = hiMant >> 16;
+ bytes[4] = hiMant >> 8;
+ bytes[5] = hiMant;
+ bytes[6] = loMant >> 24;
+ bytes[7] = loMant >> 16;
+ bytes[8] = loMant >> 8;
+ bytes[9] = loMant;
+}
+
+
+/*
+ * C O N V E R T F R O M I E E E E X T E N D E D
+ */
+
+/*
+ * Copyright (C) 1988-1991 Apple Computer, Inc.
+ * All rights reserved.
+ *
+ * Machine-independent I/O routines for IEEE floating-point numbers.
+ *
+ * NaN's and infinities are converted to HUGE_VAL or HUGE, which
+ * happens to be infinity on IEEE machines. Unfortunately, it is
+ * impossible to preserve NaN's in a machine-independent way.
+ * Infinities are, however, preserved on IEEE machines.
+ *
+ * These routines have been tested on the following machines:
+ * Apple Macintosh, MPW 3.1 C compiler
+ * Apple Macintosh, THINK C compiler
+ * Silicon Graphics IRIS, MIPS compiler
+ * Cray X/MP and Y/MP
+ * Digital Equipment VAX
+ *
+ *
+ * Implemented by Malcolm Slaney and Ken Turkowski.
+ *
+ * Malcolm Slaney contributions during 1988-1990 include big- and little-
+ * endian file I/O, conversion to and from Motorola's extended 80-bit
+ * floating-point format, and conversions to and from IEEE single-
+ * precision floating-point format.
+ *
+ * In 1991, Ken Turkowski implemented the conversions to and from
+ * IEEE double-precision format, added more precision to the extended
+ * conversions, and accommodated conversions involving +/- infinity,
+ * NaN's, and denormalized numbers.
+ */
+
+#ifndef HUGE_VAL
+# define HUGE_VAL HUGE
+#endif /*HUGE_VAL*/
+
+# define UnsignedToFloat(u) (((double)((LONG)(u - 2147483647L - 1))) + 2147483648.0)
+
+/****************************************************************
+ * Extended precision IEEE floating-point conversion routine.
+ ****************************************************************/
+
+double ConvertFromIeeeExtended(bytes)
+unsigned char *bytes; /* LCN */
+{
+ double f;
+ int expon;
+ ULONG hiMant, loMant;
+
+ expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
+ hiMant = ((ULONG)(bytes[2] & 0xFF) << 24)
+ | ((ULONG)(bytes[3] & 0xFF) << 16)
+ | ((ULONG)(bytes[4] & 0xFF) << 8)
+ | ((ULONG)(bytes[5] & 0xFF));
+ loMant = ((ULONG)(bytes[6] & 0xFF) << 24)
+ | ((ULONG)(bytes[7] & 0xFF) << 16)
+ | ((ULONG)(bytes[8] & 0xFF) << 8)
+ | ((ULONG)(bytes[9] & 0xFF));
+
+ if (expon == 0 && hiMant == 0 && loMant == 0) {
+ f = 0;
+ }
+ else {
+ if (expon == 0x7FFF) { /* Infinity or NaN */
+ f = HUGE_VAL;
+ }
+ else {
+ expon -= 16383;
+ f = ldexp(UnsignedToFloat(hiMant), expon-=31);
+ f += ldexp(UnsignedToFloat(loMant), expon-=32);
+ }
+ }
+
+ if (bytes[0] & 0x80)
+ return -f;
+ else
+ return f;
+}
+
--- /dev/null
+++ b/src/au.c
@@ -1,0 +1,324 @@
+/*
+ * Copyright 1991, 1992, 1993 Guido van Rossum And Sundry Contributors.
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * October 7, 1998 - cbagwell@sprynet.com
+ * G.723 was using incorrect # of bits. Corrected to 3 and 5 bits.
+ */
+
+/*
+ * Sound Tools Sun format with header (SunOS 4.1; see /usr/demo/SOUND).
+ * NeXT uses this format also, but has more format codes defined.
+ * DEC uses a slight variation and swaps bytes.
+ * We only support the common formats.
+ * CCITT G.721 (32 kbit/s) and G.723 (24/40 kbit/s) are also supported,
+ * courtesy Sun's public domain implementation.
+ * Output is always in big-endian (Sun/NeXT) order.
+ */
+
+#include "st.h"
+#include "g72x.h"
+#include <stdlib.h>
+
+/* Magic numbers used in Sun and NeXT audio files */
+#define SUN_MAGIC 0x2e736e64 /* Really '.snd' */
+#define SUN_INV_MAGIC 0x646e732e /* '.snd' upside-down */
+#define DEC_MAGIC 0x2e736400 /* Really '\0ds.' (for DEC) */
+#define DEC_INV_MAGIC 0x0064732e /* '\0ds.' upside-down */
+#define SUN_HDRSIZE 24 /* Size of minimal header */
+#define SUN_UNSPEC ((unsigned)(~0)) /* Unspecified data size */
+#define SUN_ULAW 1 /* u-law encoding */
+#define SUN_LIN_8 2 /* Linear 8 bits */
+#define SUN_LIN_16 3 /* Linear 16 bits */
+#define SUN_LIN_24 4 /* Linear 24 bits */
+#define SUN_LIN_32 5 /* Linear 32 bits */
+#define SUN_FLOAT 6 /* IEEE FP 32 bits */
+#define SUN_DOUBLE 7 /* IEEE FP 64 bits */
+#define SUN_G721 23 /* CCITT G.721 4-bits ADPCM */
+#define SUN_G723_3 25 /* CCITT G.723 3-bits ADPCM */
+#define SUN_G723_5 26 /* CCITT G.723 5-bits ADPCM */
+/* The other formats are not supported by sox at the moment */
+
+/* Private data */
+struct aupriv {
+ /* For writer: */
+ ULONG data_size;
+ /* For G72x decoding: */
+ struct g72x_state state;
+ int (*dec_routine)();
+ int dec_bits;
+ unsigned int in_buffer;
+ int in_bits;
+};
+
+void auwriteheader(P2(ft_t ft, ULONG data_size));
+LONG rawread(P3(ft_t, LONG *, LONG));
+void rawwrite(P3(ft_t,LONG *, LONG));
+
+void austartread(ft)
+ft_t ft;
+{
+ /* The following 6 variables represent a Sun sound header on disk.
+ The numbers are written as big-endians.
+ Any extra bytes (totalling hdr_size - 24) are an
+ "info" field of unspecified nature, usually a string.
+ By convention the header size is a multiple of 4. */
+ ULONG magic;
+ ULONG hdr_size;
+ ULONG data_size;
+ ULONG encoding;
+ ULONG sample_rate;
+ ULONG channels;
+
+ register int i;
+ char *buf;
+ struct aupriv *p = (struct aupriv *) ft->priv;
+
+ /* Sanity check */
+ if (sizeof(struct aupriv) > PRIVSIZE)
+ fail(
+"struct aupriv is too big (%d); change PRIVSIZE in st.h and recompile sox",
+ sizeof(struct aupriv));
+
+ /* Check the magic word */
+ magic = rlong(ft);
+ if (magic == DEC_INV_MAGIC) {
+ ft->swap = 1;
+ report("Found inverted DEC magic word");
+ }
+ else if (magic == SUN_INV_MAGIC) {
+ ft->swap = 1;
+ report("Found inverted Sun/NeXT magic word");
+ }
+ else if (magic == SUN_MAGIC) {
+ ft->swap = 0;
+ report("Found Sun/NeXT magic word");
+ }
+ else if (magic == DEC_MAGIC) {
+ ft->swap = 0;
+ report("Found DEC magic word");
+ }
+ else
+ fail("Sun/NeXT/DEC header doesn't start with magic word\nTry the '.ul' file type with '-t ul -r 8000 filename'");
+
+ /* Read the header size */
+ hdr_size = rlong(ft);
+ if (hdr_size < SUN_HDRSIZE)
+ fail("Sun/NeXT header size too small.");
+
+ /* Read the data size; may be ~0 meaning unspecified */
+ data_size = rlong(ft);
+
+ /* Read the encoding; there are some more possibilities */
+ encoding = rlong(ft);
+
+
+ /* Translate the encoding into style and size parameters */
+ /* (Or, for G.72x, set the decoding routine and parameters) */
+ p->dec_routine = NULL;
+ p->in_buffer = 0;
+ p->in_bits = 0;
+ switch (encoding) {
+ case SUN_ULAW:
+ ft->info.style = ULAW;
+ ft->info.size = BYTE;
+ break;
+ case SUN_LIN_8:
+ ft->info.style = SIGN2;
+ ft->info.size = BYTE;
+ break;
+ case SUN_LIN_16:
+ ft->info.style = SIGN2;
+ ft->info.size = WORD;
+ break;
+ case SUN_G721:
+ ft->info.style = SIGN2;
+ ft->info.size = WORD;
+ g72x_init_state(&p->state);
+ p->dec_routine = g721_decoder;
+ p->dec_bits = 4;
+ break;
+ case SUN_G723_3:
+ ft->info.style = SIGN2;
+ ft->info.size = WORD;
+ g72x_init_state(&p->state);
+ p->dec_routine = g723_24_decoder;
+ p->dec_bits = 3;
+ break;
+ case SUN_G723_5:
+ ft->info.style = SIGN2;
+ ft->info.size = WORD;
+ g72x_init_state(&p->state);
+ p->dec_routine = g723_40_decoder;
+ p->dec_bits = 5;
+ break;
+ default:
+ report("encoding: 0x%lx", encoding);
+ fail("Unsupported encoding in Sun/NeXT header.\nOnly U-law, signed bytes, signed words, and ADPCM are supported.");
+ /*NOTREACHED*/
+ }
+
+ /* Read the sampling rate */
+ sample_rate = rlong(ft);
+ ft->info.rate = sample_rate;
+
+ /* Read the number of channels */
+ channels = rlong(ft);
+ ft->info.channels = (int) channels;
+
+ /* Skip the info string in header; print it if verbose */
+ hdr_size -= SUN_HDRSIZE; /* #bytes already read */
+ if (hdr_size > 0) {
+ buf = (char *) malloc(hdr_size + 1);
+ for(i = 0; i < hdr_size; i++) {
+ buf[i] = (char) getc(ft->fp);
+ if (feof(ft->fp))
+ fail("Unexpected EOF in Sun/NeXT header info.");
+ }
+ buf[i] = '\0';
+ ft->comment = buf;
+ report("Input file %s: Sun header info: %s", ft->filename, buf);
+ }
+}
+
+/* When writing, the header is supposed to contain the number of
+ data bytes written, unless it is written to a pipe.
+ Since we don't know how many bytes will follow until we're done,
+ we first write the header with an unspecified number of bytes,
+ and at the end we rewind the file and write the header again
+ with the right size. This only works if the file is seekable;
+ if it is not, the unspecified size remains in the header
+ (this is legal). */
+
+void austartwrite(ft)
+ft_t ft;
+{
+ struct aupriv *p = (struct aupriv *) ft->priv;
+ int littlendian = 0;
+ char *endptr;
+
+ p->data_size = 0;
+ auwriteheader(ft, SUN_UNSPEC);
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1)
+ ft->swap = 1;
+}
+
+/*
+ * Unpack input codes and pass them back as bytes.
+ * Returns 1 if there is residual input, returns -1 if eof, else returns 0.
+ * (Adapted from Sun's decode.c.)
+ */
+int
+unpack_input(ft, code)
+ft_t ft;
+unsigned char *code;
+{
+ struct aupriv *p = (struct aupriv *) ft->priv;
+ unsigned char in_byte;
+
+ if (p->in_bits < p->dec_bits) {
+ if (fread(&in_byte, sizeof (char), 1, ft->fp) != 1) {
+ *code = 0;
+ return (-1);
+ }
+ p->in_buffer |= (in_byte << p->in_bits);
+ p->in_bits += 8;
+ }
+ *code = p->in_buffer & ((1 << p->dec_bits) - 1);
+ p->in_buffer >>= p->dec_bits;
+ p->in_bits -= p->dec_bits;
+ return (p->in_bits > 0);
+}
+
+LONG auread(ft, buf, samp)
+ft_t ft;
+LONG *buf, samp;
+{
+ struct aupriv *p = (struct aupriv *) ft->priv;
+ unsigned char code;
+ int done;
+ if (p->dec_routine == NULL)
+ return rawread(ft, buf, samp);
+ done = 0;
+ while (samp > 0 && unpack_input(ft, &code) >= 0) {
+ *buf++ = LEFT((*p->dec_routine)(code, AUDIO_ENCODING_LINEAR,
+ &p->state),
+ 16);
+ samp--;
+ done++;
+ }
+ return done;
+}
+
+void auwrite(ft, buf, samp)
+ft_t ft;
+LONG *buf, samp;
+{
+ struct aupriv *p = (struct aupriv *) ft->priv;
+ p->data_size += samp * ft->info.size;
+ rawwrite(ft, buf, samp);
+}
+
+void austopwrite(ft)
+ft_t ft;
+{
+ struct aupriv *p = (struct aupriv *) ft->priv;
+ if (!ft->seekable)
+ return;
+ if (fseek(ft->fp, 0L, 0) != 0)
+ fail("Can't rewind output file to rewrite Sun header.");
+ auwriteheader(ft, p->data_size);
+}
+
+void auwriteheader(ft, data_size)
+ft_t ft;
+ULONG data_size;
+{
+ ULONG magic;
+ ULONG hdr_size;
+ ULONG encoding;
+ ULONG sample_rate;
+ ULONG channels;
+
+ if (ft->info.style == ULAW && ft->info.size == BYTE)
+ encoding = SUN_ULAW;
+ else if (ft->info.style == SIGN2 && ft->info.size == BYTE)
+ encoding = SUN_LIN_8;
+ else if (ft->info.style == SIGN2 && ft->info.size == WORD)
+ encoding = SUN_LIN_16;
+ else {
+ report("Unsupported output style/size for Sun/NeXT header or .AU format not specified.");
+ report("Only U-law, signed bytes, and signed words are supported.");
+ report("Defaulting to 8khz u-law\n");
+ encoding = SUN_ULAW;
+ ft->info.style = ULAW;
+ ft->info.size = BYTE;
+ ft->info.rate = 8000; /* strange but true */
+ }
+
+ magic = SUN_MAGIC;
+ wblong(ft, magic);
+
+ if (ft->comment == NULL)
+ ft->comment = "";
+ hdr_size = SUN_HDRSIZE + strlen(ft->comment);
+ wblong(ft, hdr_size);
+
+ wblong(ft, data_size);
+
+ wblong(ft, encoding);
+
+ sample_rate = ft->info.rate;
+ wblong(ft, sample_rate);
+
+ channels = ft->info.channels;
+ wblong(ft, channels);
+
+ fputs(ft->comment, ft->fp);
+}
+
--- /dev/null
+++ b/src/auto.c
@@ -1,0 +1,83 @@
+/*
+ * May 19, 1992
+ * Copyright 1992 Guido van Rossum And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * A meta-handler that recognizes most file types by looking in the
+ * first part of the file. The file must be seekable!
+ * (IRCAM sound files are not recognized -- these don't seem to be
+ * used any more -- but this is just laziness on my part.)
+ */
+
+#include "st.h"
+#include <string.h>
+
+IMPORT void gettype();
+
+void autostartread(ft)
+ft_t ft;
+{
+ char *type;
+ char header[132];
+ if (!ft->seekable)
+ fail("Type AUTO input must be a file, not a pipe");
+ if (fread(header, 1, sizeof header, ft->fp) != sizeof header)
+ fail("Type AUTO detects short file");
+ fseek(ft->fp, 0L - sizeof header, 1); /* Seek back */
+ type = 0;
+ if ((strncmp(header, ".snd", 4) == 0) ||
+ (strncmp(header, "dns.", 4) == 0) ||
+ ((header[0] == '\0') && (strncmp(header+1, "ds.", 3) == 0))) {
+ type = "au";
+ }
+ else if (strncmp(header, "FORM", 4) == 0) {
+ if (strncmp(header + 8, "AIFF", 4) == 0)
+ type = "aiff";
+ else if (strncmp(header + 8, "8SVX", 4) == 0)
+ type = "8svx";
+ else if (strncmp(header + 8, "MAUD", 4) == 0)
+ type = "maud";
+ }
+ else if (strncmp(header, "RIFF", 4) == 0 &&
+ strncmp(header + 8, "WAVE", 4) == 0) {
+ type = "wav";
+ }
+ else if (strncmp(header, "Creative Voice File", 19) == 0) {
+ type = "voc";
+ }
+ else if (strncmp(header+65, "FSSD", 4) == 0 &&
+ strncmp(header+128, "HCOM", 4) == 0) {
+ type = "hcom";
+ }
+ else if (strncmp(header, "SOUND", 5) == 0) {
+ type = "sndt";
+ }
+ else if (header[0] == 0 && header[1] == 0) {
+ int rate = (header[2] & 0xff) + ((header[3] & 0xff) << 8);
+ if (rate >= 4000 && rate <= 25000)
+ type = "sndr";
+ }
+ if (type == 0) {
+ printf("Type AUTO doesn't recognize this header\n");
+ printf("Trying: -t raw -r 11000 -b -u\n\n");
+ type = "raw";
+ ft->info.rate = 11000;
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ }
+ report("Type AUTO changed to %s", type);
+ ft->filetype = type;
+ gettype(ft); /* Change ft->h to the new format */
+ (* ft->h->startread)(ft);
+}
+
+void autostartwrite(ft)
+ft_t ft;
+{
+ fail("Type AUTO can only be used for input!");
+}
--- /dev/null
+++ b/src/avg.c
@@ -1,0 +1,266 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Channel duplication code by Graeme W. Gill - 93/5/18
+ */
+
+/*
+ * Sound Tools stereo/quad -> mono mixdown effect file.
+ * and mono/stereo -> stereo/quad channel duplication.
+ *
+ * What's in a center channel?
+ */
+
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct avgstuff {
+ int mix; /* How are we mixing it? */
+} *avg_t;
+
+#define MIX_CENTER 0
+#define MIX_LEFT 1
+#define MIX_RIGHT 2
+
+/*
+ * Process options
+ */
+void avg_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ avg_t avg = (avg_t) effp->priv;
+
+ /* NOTE :- should probably have a pan option for both */
+ /* 2 -> 1 and 1 -> 2 etc. conversion, rather than just */
+ /* left and right. If 4 channels is to be fully supported, */
+ /* front and back pan is also needed. (GWG) */
+ /* (should at least have MIX_FRONT and MIX_BACK) */
+ avg->mix = MIX_CENTER;
+ if (n) {
+ if(!strcmp(argv[0], "-l"))
+ avg->mix = MIX_LEFT;
+ else if (!strcmp(argv[0], "-r"))
+ avg->mix = MIX_RIGHT;
+ else
+ fail("Usage: avg [ -l | -r ]");
+ }
+}
+
+/*
+ * Start processing
+ */
+void
+avg_start(effp)
+eff_t effp;
+{
+ switch (effp->outinfo.channels) {
+ case 1: switch (effp->ininfo.channels) {
+ case 2:
+ case 4:
+ return;
+ }
+ case 2: switch (effp->ininfo.channels) {
+ case 1:
+ case 4:
+ return;
+ }
+ case 4: switch (effp->ininfo.channels) {
+ case 1:
+ case 2:
+ return;
+ }
+ }
+ fail("Can't average %d channels into %d channels",
+ effp->ininfo.channels, effp->outinfo.channels);
+}
+
+/*
+ * Process either isamp or osamp samples, whichever is smaller.
+ */
+
+void avg_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ avg_t avg = (avg_t) effp->priv;
+ int len, done;
+
+ switch (effp->outinfo.channels) {
+ case 1: switch (effp->ininfo.channels) {
+ case 2:
+ /* average 2 channels into 1 */
+ len = ((*isamp/2 > *osamp) ? *osamp : *isamp/2);
+ switch(avg->mix) {
+ case MIX_CENTER:
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[0]/2 + ibuf[1]/2;
+ ibuf += 2;
+ }
+ break;
+ case MIX_LEFT:
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[0];
+ ibuf += 2;
+ }
+ break;
+ case MIX_RIGHT:
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[1];
+ ibuf += 2;
+ }
+ break;
+ }
+ *isamp = len * 2;
+ *osamp = len;
+ break;
+ case 4:
+ /* average 4 channels into 1 */
+ len = ((*isamp/4 > *osamp) ? *osamp : *isamp/4);
+ switch(avg->mix) {
+ case MIX_CENTER:
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[0]/4 + ibuf[1]/4 +
+ ibuf[2]/4 + ibuf[3]/4;
+ ibuf += 4;
+ }
+ break;
+ case MIX_LEFT:
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[0]/2 + ibuf[2]/2;
+ ibuf += 4;
+ }
+ break;
+ case MIX_RIGHT:
+ for(done = 0; done < len; done++) {
+ *obuf++ = ibuf[1]/2 + ibuf[3]/2;
+ ibuf += 4;
+ }
+ break;
+ }
+ *isamp = len * 4;
+ *osamp = len;
+ break;
+ }
+ break;
+ case 2: switch (effp->ininfo.channels) {
+ case 1:
+ /* duplicate 1 channel into 2 */
+ len = ((*isamp > *osamp/2) ? *osamp/2 : *isamp);
+ switch(avg->mix) {
+ case MIX_CENTER:
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[1] = ibuf[0];
+ ibuf += 1;
+ obuf += 2;
+ }
+ break;
+ case MIX_LEFT:
+ for(done = 0; done < len; done++) {
+ obuf[0] = ibuf[0];
+ obuf[1] = 0;
+ ibuf += 1;
+ obuf += 2;
+ }
+ break;
+ case MIX_RIGHT:
+ for(done = 0; done < len; done++) {
+ obuf[0] = 0;
+ obuf[1] = ibuf[0];
+ ibuf += 1;
+ obuf += 2;
+ }
+ break;
+ }
+ *isamp = len;
+ *osamp = len * 2;
+ break;
+ /*
+ * After careful inspection of CSOUND source code,
+ * I'm mildly sure the order is:
+ * front-left, front-right, rear-left, rear-right
+ */
+ case 4:
+ /* average 4 channels into 2 */
+ len = ((*isamp/4 > *osamp/2) ? *osamp/2 : *isamp/4);
+ for(done = 0; done < len; done++) {
+ obuf[0] = ibuf[0]/2 + ibuf[2]/2;
+ obuf[1] = ibuf[1]/2 + ibuf[3]/2;
+ ibuf += 4;
+ obuf += 2;
+ }
+ *isamp = len * 4;
+ *osamp = len * 2;
+ break;
+ }
+ break;
+ case 4: switch (effp->ininfo.channels) {
+ case 1:
+ /* duplicate 1 channel into 4 */
+ len = ((*isamp > *osamp/4) ? *osamp/4 : *isamp);
+ switch(avg->mix) {
+ case MIX_CENTER:
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[1] =
+ obuf[2] = obuf[3] = ibuf[0];
+ ibuf += 1;
+ obuf += 4;
+ }
+ break;
+ case MIX_LEFT:
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[2] = ibuf[0];
+ obuf[1] = obuf[3] = 0;
+ ibuf += 1;
+ obuf += 4;
+ }
+ break;
+ case MIX_RIGHT:
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[2] = 0;
+ obuf[1] = obuf[3] = ibuf[0];
+ ibuf += 1;
+ obuf += 4;
+ }
+ break;
+ }
+ *isamp = len;
+ *osamp = len * 4;
+ break;
+ case 2:
+ /* duplicate 2 channels into 4 */
+ len = ((*isamp/2 > *osamp/4) ? *osamp/4 : *isamp/2);
+ for(done = 0; done < len; done++) {
+ obuf[0] = obuf[2] = ibuf[0];
+ obuf[1] = obuf[3] = ibuf[1];
+ ibuf += 2;
+ obuf += 4;
+ }
+ *isamp = len * 2;
+ *osamp = len * 4;
+ break;
+ }
+ break;
+ } /* end switch out channels */
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ *
+ * Should have statistics on right, left, and output amplitudes.
+ */
+void avg_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
--- /dev/null
+++ b/src/band.c
@@ -1,0 +1,128 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools Bandpass effect file.
+ *
+ * Algorithm: 2nd order recursive filter.
+ * Formula stolen from MUSIC56K, a toolkit of 56000 assembler stuff.
+ * Quote:
+ * This is a 2nd order recursive band pass filter of the form.
+ * y(n)= a * x(n) - b * y(n-1) - c * y(n-2)
+ * where :
+ * x(n) = "IN"
+ * "OUT" = y(n)
+ * c = EXP(-2*pi*cBW/S_RATE)
+ * b = -4*c/(1+c)*COS(2*pi*cCF/S_RATE)
+ * if cSCL=2 (i.e. noise input)
+ * a = SQT(((1+c)*(1+c)-b*b)*(1-c)/(1+c))
+ * else
+ * a = SQT(1-b*b/(4*c))*(1-c)
+ * endif
+ * note : cCF is the center frequency in Hertz
+ * cBW is the band width in Hertz
+ * cSCL is a scale factor, use 1 for pitched sounds
+ * use 2 for noise.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for Bandpass effect */
+typedef struct bandstuff {
+ float center;
+ float width;
+ double A, B, C;
+ double out1, out2;
+ short noise;
+ /* 50 bytes of data, 52 bytes long for allocation purposes. */
+} *band_t;
+
+/*
+ * Process options
+ */
+void band_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ band_t band = (band_t) effp->priv;
+
+ band->noise = 0;
+ if (n > 0 && !strcmp(argv[0], "-n")) {
+ band->noise = 1;
+ n--;
+ argv++;
+ }
+ if ((n < 1) || !sscanf(argv[0], "%f", &band->center))
+ fail("Usage: band [ -n ] center [ width ]");
+ band->width = band->center / 2;
+ if ((n >= 2) && !sscanf(argv[1], "%f", &band->width))
+ fail("Usage: band [ -n ] center [ width ]");
+}
+
+/*
+ * Prepare processing.
+ */
+void band_start(effp)
+eff_t effp;
+{
+ band_t band = (band_t) effp->priv;
+ if (band->center > effp->ininfo.rate/2)
+ fail("Band: center must be < minimum data rate/2\n");
+
+ band->C = exp(-2*M_PI*band->width/effp->ininfo.rate);
+ band->B = -4*band->C/(1+band->C)*
+ cos(2*M_PI*band->center/effp->ininfo.rate);
+ if (band->noise)
+ band->A = sqrt(((1+band->C)*(1+band->C)-band->B *
+ band->B)*(1-band->C)/(1+band->C));
+ else
+ band->A = sqrt(1-band->B*band->B/(4*band->C))*(1-band->C);
+ band->out1 = band->out2 = 0.0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void band_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ band_t band = (band_t) effp->priv;
+ int len, done;
+ double d;
+ LONG l;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+
+ /* yeah yeah yeah registers & integer arithmetic yeah yeah yeah */
+ for(done = 0; done < len; done++) {
+ l = *ibuf++;
+ d = (band->A * l - band->B * band->out1) - band->C * band->out2;
+ band->out2 = band->out1;
+ band->out1 = d;
+ *obuf++ = d;
+ }
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void band_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
--- /dev/null
+++ b/src/cdr.c
@@ -1,0 +1,149 @@
+/*
+ * CD-R format handler
+ *
+ * David Elliott, Sony Microsystems - July 5, 1991
+ *
+ * Copyright 1991 David Elliott And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * This code automatically handles endianness differences
+ *
+ * cbagwell (cbagwell@sprynet.com) - 20 April 1998
+ *
+ * Changed endianness handling. Seemed to be reversed (since format
+ * is in big endian) and made it so that user could always override
+ * swapping no matter what endian machine they are one.
+ *
+ * Fixed bug were trash could be appended to end of file for certain
+ * endian machines.
+ *
+ */
+
+#include "st.h"
+
+#define SECTORSIZE (2352 / 2)
+
+/* Private data for SKEL file */
+typedef struct cdrstuff {
+ LONG samples; /* number of samples written */
+} *cdr_t;
+
+LONG rawread(P3(ft_t, LONG *, LONG));
+void rawwrite(P3(ft_t, LONG *, LONG));
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+
+void cdrstartread(ft)
+ft_t ft;
+{
+
+ int littlendian = 1;
+ char *endptr;
+
+ endptr = (char *) &littlendian;
+ /* CDR is in Big Endian format. Swap whats read in on */
+ /* Little Endian machines. */
+ if (*endptr)
+ {
+ ft->swap = ft->swap ? 0 : 1;
+ }
+
+ ft->info.rate = 44100L;
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ ft->info.channels = 2;
+ ft->comment = NULL;
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG cdrread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+
+ return rawread(ft, buf, len);
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void cdrstopread(ft)
+ft_t ft;
+{
+}
+
+void cdrstartwrite(ft)
+ft_t ft;
+{
+ cdr_t cdr = (cdr_t) ft->priv;
+
+ int littlendian = 1;
+ char *endptr;
+
+ endptr = (char *) &littlendian;
+ /* CDR is in Big Endian format. Swap whats written out on */
+ /* Little Endian Machines. */
+ if (*endptr)
+ {
+ ft->swap = ft->swap ? 0 : 1;
+ }
+
+ cdr->samples = 0;
+
+ ft->info.rate = 44100L;
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ ft->info.channels = 2;
+}
+
+void cdrwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ cdr_t cdr = (cdr_t) ft->priv;
+
+ cdr->samples += len;
+
+ rawwrite(ft, buf, len);
+}
+
+/*
+ * A CD-R file needs to be padded to SECTORSIZE, which is in terms of
+ * samples. We write -32768 for each sample to pad it out.
+ */
+
+void cdrstopwrite(ft)
+ft_t ft;
+{
+ cdr_t cdr = (cdr_t) ft->priv;
+ int padsamps = SECTORSIZE - (cdr->samples % SECTORSIZE);
+ short zero;
+
+ zero = 0;
+
+ if (padsamps == SECTORSIZE) {
+ return;
+ }
+
+ while (padsamps > 0) {
+ wshort(ft, zero);
+ padsamps--;
+ }
+}
+
--- /dev/null
+++ b/src/chorus.c
@@ -1,0 +1,356 @@
+/*
+ * August 24, 1998
+ * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Juergen Mueller And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Chorus effect.
+ *
+ * Flow diagram scheme for n delays ( 1 <= n <= MAX_CHORUS ):
+ *
+ * * gain-in ___
+ * ibuff -----+--------------------------------------------->| |
+ * | _________ | |
+ * | | | * decay 1 | |
+ * +---->| delay 1 |----------------------------->| |
+ * | |_________| | |
+ * | /|\ | |
+ * : | | |
+ * : +-----------------+ +--------------+ | + |
+ * : | Delay control 1 |<--| mod. speed 1 | | |
+ * : +-----------------+ +--------------+ | |
+ * | _________ | |
+ * | | | * decay n | |
+ * +---->| delay n |----------------------------->| |
+ * |_________| | |
+ * /|\ |___|
+ * | |
+ * +-----------------+ +--------------+ | * gain-out
+ * | Delay control n |<--| mod. speed n | |
+ * +-----------------+ +--------------+ +----->obuff
+ *
+ *
+ * The delay i is controled by a sine or triangle modulation i ( 1 <= i <= n).
+ *
+ * Usage:
+ * chorus gain-in gain-out delay-1 decay-1 speed-1 depth-1 -s1|t1 [
+ * delay-2 decay-2 speed-2 depth-2 -s2|-t2 ... ]
+ *
+ * Where:
+ * gain-in, decay-1 ... decay-n : 0.0 ... 1.0 volume
+ * gain-out : 0.0 ... volume
+ * delay-1 ... delay-n : 20.0 ... 100.0 msec
+ * speed-1 ... speed-n : 0.1 ... 5.0 Hz modulation 1 ... n
+ * depth-1 ... depth-n : 0.0 ... 10.0 msec modulated delay 1 ... n
+ * -s1 ... -sn : modulation by sine 1 ... n
+ * -t1 ... -tn : modulation by triangle 1 ... n
+ *
+ * Note:
+ * when decay is close to 1.0, the samples can begin clipping and the output
+ * can saturate!
+ *
+ * Hint:
+ * 1 / out-gain < gain-in ( 1 + decay-1 + ... + decay-n )
+ *
+*/
+
+/*
+ * Sound Tools chorus effect file.
+ */
+
+#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
+#include <math.h>
+#include <string.h>
+#include "st.h"
+
+#define MOD_SINE 0
+#define MOD_TRIANGLE 1
+#define MAX_CHORUS 7
+
+/* Private data for SKEL file */
+typedef struct chorusstuff {
+ int num_chorus;
+ int modulation[MAX_CHORUS];
+ int counter;
+ long phase[MAX_CHORUS];
+ float *chorusbuf;
+ float in_gain, out_gain;
+ float delay[MAX_CHORUS], decay[MAX_CHORUS];
+ float speed[MAX_CHORUS], depth[MAX_CHORUS];
+ long length[MAX_CHORUS];
+ int *lookup_tab[MAX_CHORUS];
+ int depth_samples[MAX_CHORUS], samples[MAX_CHORUS];
+ int maxsamples, fade_out;
+} *chorus_t;
+
+/* Private data for SKEL file */
+
+LONG chorus_clip24(l)
+LONG l;
+{
+ if (l >= ((LONG)1 << 24))
+ return ((LONG)1 << 24) - 1;
+ else if (l <= -((LONG)1 << 24))
+ return -((LONG)1 << 24) + 1;
+ else
+ return l;
+}
+
+/* This was very painful. We need a sine library. */
+
+void chorus_sine(buf, len, max, depth)
+int *buf;
+long len;
+int max;
+int depth;
+{
+ long i;
+ int offset;
+ double val;
+
+ offset = max - depth;
+ for (i = 0; i < len; i++) {
+ val = sin((double)i/(double)len * 2.0 * M_PI);
+ buf[i] = offset + (int) (val * (double)depth);
+ }
+}
+
+void chorus_triangle(buf, len, max, depth)
+int *buf;
+long len;
+int max;
+int depth;
+{
+ long i;
+ int offset;
+ double val;
+
+ offset = max - 2 * depth;
+ for (i = 0; i < len / 2; i++) {
+ val = i * 2.0 / len;
+ buf[i] = offset + (int) (val * 2.0 * (double)depth);
+ }
+ for (i = len / 2; i < len ; i++) {
+ val = (len - i) * 2.0 / len;
+ buf[i] = offset + (int) (val * 2.0 * (double)depth);
+ }
+}
+
+/*
+ * Process options
+ */
+void chorus_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ chorus_t chorus = (chorus_t) effp->priv;
+ int i;
+
+ chorus->num_chorus = 0;
+ i = 0;
+
+ if ( ( n < 7 ) || (( n - 2 ) % 5 ) )
+ fail("Usage: chorus gain-in gain-out delay decay speed depth [ -s | -t ]");
+
+ sscanf(argv[i++], "%f", &chorus->in_gain);
+ sscanf(argv[i++], "%f", &chorus->out_gain);
+ while ( i < n ) {
+ if ( chorus->num_chorus > MAX_CHORUS )
+ fail("chorus: to many delays, use less than %i delays", MAX_CHORUS);
+ sscanf(argv[i++], "%f", &chorus->delay[chorus->num_chorus]);
+ sscanf(argv[i++], "%f", &chorus->decay[chorus->num_chorus]);
+ sscanf(argv[i++], "%f", &chorus->speed[chorus->num_chorus]);
+ sscanf(argv[i++], "%f", &chorus->depth[chorus->num_chorus]);
+ if ( !strcmp(argv[i], "-s"))
+ chorus->modulation[chorus->num_chorus] = MOD_SINE;
+ else if ( ! strcmp(argv[i], "-t"))
+ chorus->modulation[chorus->num_chorus] = MOD_TRIANGLE;
+ else
+ fail("Usage: chorus gain-in gain-out delay decay speed [ -s | -t ]");
+ i++;
+ chorus->num_chorus++;
+ }
+}
+
+/*
+ * Prepare for processing.
+ */
+void chorus_start(effp)
+eff_t effp;
+{
+ chorus_t chorus = (chorus_t) effp->priv;
+ int i;
+ float sum_in_volume;
+
+ chorus->maxsamples = 0;
+
+ if ( chorus->in_gain < 0.0 )
+ fail("chorus: gain-in must be positive!\n");
+ if ( chorus->in_gain > 1.0 )
+ fail("chorus: gain-in must be less than 1.0!\n");
+ if ( chorus->out_gain < 0.0 )
+ fail("chorus: gain-out must be positive!\n");
+ for ( i = 0; i < chorus->num_chorus; i++ ) {
+ chorus->samples[i] = (int) ( ( chorus->delay[i] +
+ chorus->depth[i] ) * effp->ininfo.rate / 1000.0);
+ chorus->depth_samples[i] = (int) (chorus->depth[i] *
+ effp->ininfo.rate / 1000.0);
+
+ if ( chorus->delay[i] < 20.0 )
+ fail("chorus: delay must be more than 20.0 msec!\n");
+ if ( chorus->delay[i] > 100.0 )
+ fail("chorus: delay must be less than 100.0 msec!\n");
+ if ( chorus->speed[i] < 0.1 )
+ fail("chorus: speed must be more than 0.1 Hz!\n");
+ if ( chorus->speed[i] > 5.0 )
+ fail("chorus: speed must be less than 5.0 Hz!\n");
+ if ( chorus->depth[i] < 0.0 )
+ fail("chorus: delay must be more positive!\n");
+ if ( chorus->depth[i] > 10.0 )
+ fail("chorus: delay must be less than 10.0 msec!\n");
+ if ( chorus->decay[i] < 0.0 )
+ fail("chorus: decay must be positive!\n" );
+ if ( chorus->decay[i] > 1.0 )
+ fail("chorus: decay must be less that 1.0!\n" );
+ chorus->length[i] = effp->ininfo.rate / chorus->speed[i];
+ if (! (chorus->lookup_tab[i] =
+ (int *) malloc(sizeof (int) * chorus->length[i])))
+ fail("chorus: Cannot malloc %d bytes!\n",
+ sizeof(int) * chorus->length[i]);
+ if ( chorus->modulation[i] == MOD_SINE )
+ chorus_sine(chorus->lookup_tab[i], chorus->length[i],
+ chorus->samples[i] - 1, chorus->depth_samples[i]);
+ else
+ chorus_triangle(chorus->lookup_tab[i], chorus->length[i],
+ chorus->samples[i] - 1, chorus->depth_samples[i]);
+ chorus->phase[i] = 0;
+
+ if ( chorus->samples[i] > chorus->maxsamples )
+ chorus->maxsamples = chorus->samples[i];
+ }
+
+ /* Be nice and check the hint with warning, if... */
+ sum_in_volume = 1.0;
+ for ( i = 0; i < chorus->num_chorus; i++ )
+ sum_in_volume += chorus->decay[i];
+ if ( chorus->in_gain * ( sum_in_volume ) > 1.0 / chorus->out_gain )
+ warn("chorus: warning >>> gain-out can cause saturation or clipping of output <<<");
+
+
+ if (! (chorus->chorusbuf =
+ (float *) malloc(sizeof (float) * chorus->maxsamples)))
+ fail("chorus: Cannot malloc %d bytes!\n",
+ sizeof(float) * chorus->maxsamples);
+ for ( i = 0; i < chorus->maxsamples; i++ )
+ chorus->chorusbuf[i] = 0.0;
+
+ chorus->counter = 0;
+ chorus->fade_out = chorus->maxsamples;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void chorus_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ chorus_t chorus = (chorus_t) effp->priv;
+ int len, done;
+ int i;
+
+ float d_in, d_out;
+ LONG out;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* Store delays as 24-bit signed longs */
+ d_in = (float) *ibuf++ / 256;
+ /* Compute output first */
+ d_out = d_in * chorus->in_gain;
+ for ( i = 0; i < chorus->num_chorus; i++ )
+ d_out += chorus->chorusbuf[(chorus->maxsamples +
+ chorus->counter - chorus->lookup_tab[i][chorus->phase[i]]) %
+ chorus->maxsamples] * chorus->decay[i];
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * chorus->out_gain;
+ out = chorus_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delay and input */
+ chorus->chorusbuf[chorus->counter] = d_in;
+ chorus->counter =
+ ( chorus->counter + 1 ) % chorus->maxsamples;
+ for ( i = 0; i < chorus->num_chorus; i++ )
+ chorus->phase[i] =
+ ( chorus->phase[i] + 1 ) % chorus->length[i];
+ }
+ /* processed all samples */
+}
+
+/*
+ * Drain out reverb lines.
+ */
+void chorus_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ chorus_t chorus = (chorus_t) effp->priv;
+ int done;
+ int i;
+
+ float d_in, d_out;
+ LONG out;
+
+ done = 0;
+ while ( ( done < *osamp ) && ( done < chorus->fade_out ) ) {
+ d_in = 0;
+ d_out = 0;
+ /* Compute output first */
+ for ( i = 0; i < chorus->num_chorus; i++ )
+ d_out += chorus->chorusbuf[(chorus->maxsamples +
+ chorus->counter - chorus->lookup_tab[i][chorus->phase[i]]) %
+ chorus->maxsamples] * chorus->decay[i];
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * chorus->out_gain;
+ out = chorus_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delay and input */
+ chorus->chorusbuf[chorus->counter] = d_in;
+ chorus->counter =
+ ( chorus->counter + 1 ) % chorus->maxsamples;
+ for ( i = 0; i < chorus->num_chorus; i++ )
+ chorus->phase[i] =
+ ( chorus->phase[i] + 1 ) % chorus->length[i];
+ done++;
+ chorus->fade_out--;
+ }
+ /* samples played, it remains */
+ *osamp = done;
+}
+
+/*
+ * Clean up chorus effect.
+ */
+void chorus_stop(effp)
+eff_t effp;
+{
+ chorus_t chorus = (chorus_t) effp->priv;
+ int i;
+
+ free((char *) chorus->chorusbuf);
+ chorus->chorusbuf = (float *) -1; /* guaranteed core dump */
+ for ( i = 0; i < chorus->num_chorus; i++ ) {
+ free((char *) chorus->lookup_tab[i]);
+ chorus->lookup_tab[i] = (int *) -1; /* guaranteed core dump */
+ }
+}
+
--- /dev/null
+++ b/src/copy.c
@@ -1,0 +1,70 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools skeleton effect file.
+ */
+
+#include "st.h"
+
+/*
+ * Process options
+ */
+void copy_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Copy effect takes no options.");
+}
+
+/*
+ * Start processing
+ */
+void copy_start(effp)
+eff_t effp;
+{
+ /* nothing to do */
+ /* stuff data into delaying effects here */
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+void copy_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ int done;
+
+ done = ((*isamp < *osamp) ? *isamp : *osamp);
+ memcpy(obuf, ibuf, done * sizeof(LONG));
+ *isamp = *osamp = done;
+ return;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void copy_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+
+
+
--- /dev/null
+++ b/src/cvsd.c
@@ -1,0 +1,636 @@
+/*
+ * CVSD (Continuously Variable Slope Delta modulation)
+ * conversion routines
+ *
+ * The CVSD format is described in the MIL Std 188 113, which is
+ * available from http://bbs.itsi.disa.mil:5580/T3564
+ *
+ * Copyright (C) 1996
+ * Thomas Sailer (sailer@ife.ee.ethz.ch) (HB9JNX/AE4WA)
+ * Swiss Federal Institute of Technology, Electronics Lab
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Change History:
+ *
+ * June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Fixed compile warnings reported by Kjetil Torgrim Homme
+ * <kjetilho@ifi.uio.no>
+ *
+ *
+ */
+
+/* ---------------------------------------------------------------------- */
+
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef SEEK_SET
+#define SEEK_SET 0 /* nasty nasty */
+#endif /* SEEK_SET */
+
+#include "cvsdfilt.h"
+#include "st.h"
+#include "libst.h"
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef NEED_MEMMOVE
+#define memmove(dest,src,len) (bcopy((src),(dest),(len)))
+#endif
+
+/* ---------------------------------------------------------------------- */
+/*
+ * private data structures
+ */
+
+struct cvsd_common_state {
+ unsigned overload;
+ float mla_int;
+ float mla_tc0;
+ float mla_tc1;
+ unsigned phase;
+ unsigned phase_inc;
+ float v_min, v_max;
+};
+
+struct cvsd_decode_state {
+ float output_filter[DEC_FILTERLEN];
+};
+
+struct cvsd_encode_state {
+ float recon_int;
+ float input_filter[ENC_FILTERLEN];
+};
+
+struct cvsdpriv {
+ struct cvsd_common_state com;
+ union {
+ struct cvsd_decode_state dec;
+ struct cvsd_encode_state enc;
+ } c;
+ struct {
+ unsigned shreg;
+ unsigned mask;
+ unsigned cnt;
+ } bit;
+ unsigned bytes_written;
+ unsigned cvsd_rate;
+ char swapbits;
+};
+
+/* ---------------------------------------------------------------------- */
+
+float float_conv(fp1, fp2, n)
+float *fp1;
+float *fp2;
+int n;
+{
+ float res = 0;
+ for(; n > 0; n--)
+ res += (*fp1++) * (*fp2++);
+ return res;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * some remarks about the implementation of the CVSD decoder
+ * the principal integrator is integrated into the output filter
+ * to achieve this, the coefficients of the output filter are multiplied
+ * with (1/(1-1/z)) in the initialisation code.
+ * the output filter must have a sharp zero at f=0 (i.e. the sum of the
+ * filter parameters must be zero). This prevents an accumulation of
+ * DC voltage at the principal integration.
+ */
+/* ---------------------------------------------------------------------- */
+
+static void cvsdstartcommon(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+
+ /* sanity check */
+ if (sizeof(struct cvsdpriv) > PRIVSIZE)
+ fail("struct cvsdpriv is too big (%d); change PRIVSIZE in st.h and recompile sox", sizeof(struct cvsdpriv));
+ p->cvsd_rate = (ft->info.rate <= 24000) ? 16000 : 32000;
+ ft->info.rate = 8000;
+ ft->info.channels = 1;
+ ft->info.size = WORD; /* make output format default to words */
+ ft->info.style = SIGN2;
+ p->swapbits = ft->swap;
+ ft->swap = 0;
+ /*
+ * initialize the decoder
+ */
+ p->com.overload = 0x5;
+ p->com.mla_int = 0;
+ /*
+ * timeconst = (1/e)^(200 / SR) = exp(-200/SR)
+ * SR is the sampling rate
+ */
+ p->com.mla_tc0 = exp((-200.0)/((float)(p->cvsd_rate)));
+ /*
+ * phase_inc = 32000 / SR
+ */
+ p->com.phase_inc = 32000 / p->cvsd_rate;
+ /*
+ * initialize bit shift register
+ */
+ p->bit.shreg = p->bit.cnt = 0;
+ p->bit.mask = p->swapbits ? 0x80 : 1;
+ /*
+ * count the bytes written
+ */
+ p->bytes_written = 0;
+ p->com.v_min = 1;
+ p->com.v_max = -1;
+ report("cvsd: bit rate %dbit/s, bits from %s\n", p->cvsd_rate,
+ p->swapbits ? "msb to lsb" : "lsb to msb");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void cvsdstartread(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ float *fp1;
+ int i;
+
+ cvsdstartcommon(ft);
+ p->com.mla_tc1 = 0.1 * (1 - p->com.mla_tc0);
+ p->com.phase = 0;
+ /*
+ * initialize the output filter coeffs (i.e. multiply
+ * the coeffs with (1/(1-1/z)) to achieve integration
+ * this is now done in the filter parameter generation utility
+ */
+ /*
+ * zero the filter
+ */
+ for(fp1 = p->c.dec.output_filter, i = DEC_FILTERLEN; i > 0; i--)
+ *fp1++ = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void cvsdstartwrite(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ float *fp1;
+ int i;
+
+ cvsdstartcommon(ft);
+ p->com.mla_tc1 = 0.1 * (1 - p->com.mla_tc0);
+ p->com.phase = 4;
+ /*
+ * zero the filter
+ */
+ for(fp1 = p->c.enc.input_filter, i = ENC_FILTERLEN; i > 0; i--)
+ *fp1++ = 0;
+ p->c.enc.recon_int = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void
+cvsdstopwrite(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+
+ if (p->bit.cnt) {
+ putc(p->bit.shreg, ft->fp);
+ p->bytes_written++;
+ }
+ report("cvsd: min slope %f, max slope %f\n",
+ p->com.v_min, p->com.v_max);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void
+cvsdstopread(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+
+ report("cvsd: min value %f, max value %f\n",
+ p->com.v_min, p->com.v_max);
+}
+
+/* ---------------------------------------------------------------------- */
+
+#undef DEBUG
+
+#ifdef DEBUG
+static struct {
+ FILE *f1;
+ FILE *f2;
+ int cnt
+} dbg = { NULL, NULL, 0 };
+#endif
+
+LONG cvsdread(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ int done = 0;
+ float oval;
+
+#ifdef DEBUG
+ if (!dbg.f1) {
+ if (!(dbg.f1 = fopen("dbg1", "w")))
+ fail("debugging");
+ fprintf(dbg.f1, "\"input\"\n");
+ }
+ if (!dbg.f2) {
+ if (!(dbg.f2 = fopen("dbg2", "w")))
+ fail("debugging");
+ fprintf(dbg.f2, "\"recon\"\n");
+ }
+#endif
+ while (done < nsamp) {
+ if (!p->bit.cnt) {
+ p->bit.shreg = getc(ft->fp);
+ if (feof(ft->fp))
+ return done;
+ p->bit.cnt = 8;
+ p->bit.mask = p->swapbits ? 0x80 : 1;
+ }
+ /*
+ * handle one bit
+ */
+ p->bit.cnt--;
+ p->com.overload = ((p->com.overload << 1) |
+ (!!(p->bit.shreg & p->bit.mask))) & 7;
+ if (p->swapbits)
+ p->bit.mask >>= 1;
+ else
+ p->bit.mask <<= 1;
+ p->com.mla_int *= p->com.mla_tc0;
+ if ((p->com.overload == 0) || (p->com.overload == 7))
+ p->com.mla_int += p->com.mla_tc1;
+ memmove(p->c.dec.output_filter+1, p->c.dec.output_filter,
+ sizeof(p->c.dec.output_filter)-sizeof(float));
+ if (p->com.overload & 1)
+ p->c.dec.output_filter[0] = p->com.mla_int;
+ else
+ p->c.dec.output_filter[0] = -p->com.mla_int;
+ /*
+ * check if the next output is due
+ */
+ p->com.phase += p->com.phase_inc;
+ if (p->com.phase >= 4) {
+ oval = float_conv(p->c.dec.output_filter,
+ (p->cvsd_rate < 24000) ?
+ dec_filter_16 : dec_filter_32,
+ DEC_FILTERLEN);
+#ifdef DEBUG
+ fprintf(dbg.f1, "%f %f\n", (double)dbg.cnt,
+ (double)p->com.mla_int);
+ fprintf(dbg.f2, "%f %f\n", (double)dbg.cnt,
+ (double)oval);
+ dbg.cnt++;
+#endif
+ if (oval > p->com.v_max)
+ p->com.v_max = oval;
+ if (oval < p->com.v_min)
+ p->com.v_min = oval;
+ *buf++ = (oval * ((float)LONG_MAX));
+ done++;
+ }
+ p->com.phase &= 3;
+ }
+ return done;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void
+cvsdwrite(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ int done = 0;
+ float inval;
+
+#ifdef DEBUG
+ if (!dbg.f1) {
+ if (!(dbg.f1 = fopen("dbg1", "w")))
+ fail("debugging");
+ fprintf(dbg.f1, "\"input\"\n");
+ }
+ if (!dbg.f2) {
+ if (!(dbg.f2 = fopen("dbg2", "w")))
+ fail("debugging");
+ fprintf(dbg.f2, "\"recon\"\n");
+ }
+#endif
+ for(;;) {
+ /*
+ * check if the next input is due
+ */
+ if (p->com.phase >= 4) {
+ if (done >= nsamp)
+ return;
+ memmove(p->c.enc.input_filter+1, p->c.enc.input_filter,
+ sizeof(p->c.enc.input_filter)-sizeof(float));
+ p->c.enc.input_filter[0] = (*buf++) /
+ ((float)LONG_MAX);
+ done++;
+ }
+ p->com.phase &= 3;
+ /* insert input filter here! */
+ inval = float_conv(p->c.enc.input_filter,
+ (p->cvsd_rate < 24000) ?
+ (enc_filter_16[(p->com.phase >= 2)]) :
+ (enc_filter_32[p->com.phase]),
+ ENC_FILTERLEN);
+ /*
+ * encode one bit
+ */
+ p->com.overload = (((p->com.overload << 1) |
+ (inval > p->c.enc.recon_int)) & 7);
+ p->com.mla_int *= p->com.mla_tc0;
+ if ((p->com.overload == 0) || (p->com.overload == 7))
+ p->com.mla_int += p->com.mla_tc1;
+ if (p->com.mla_int > p->com.v_max)
+ p->com.v_max = p->com.mla_int;
+ if (p->com.mla_int < p->com.v_min)
+ p->com.v_min = p->com.mla_int;
+ if (p->com.overload & 1) {
+ p->c.enc.recon_int += p->com.mla_int;
+ p->bit.shreg |= p->bit.mask;
+ } else
+ p->c.enc.recon_int -= p->com.mla_int;
+ if ((++(p->bit.cnt)) >= 8) {
+ putc(p->bit.shreg, ft->fp);
+ p->bytes_written++;
+ p->bit.shreg = p->bit.cnt = 0;
+ p->bit.mask = p->swapbits ? 0x80 : 1;
+ } else {
+ if (p->swapbits)
+ p->bit.mask >>= 1;
+ else
+ p->bit.mask <<= 1;
+ }
+ p->com.phase += p->com.phase_inc;
+#ifdef DEBUG
+ fprintf(dbg.f1, "%f %f\n", (double)dbg.cnt, (double)inval);
+ fprintf(dbg.f2, "%f %f\n", (double)dbg.cnt,
+ (double)p->c.enc.recon_int);
+ dbg.cnt++;
+#endif
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * DVMS file header
+ */
+struct dvms_header {
+ char Filename[14];
+ unsigned Id;
+ unsigned State;
+ time_t Unixtime;
+ unsigned Usender;
+ unsigned Ureceiver;
+ ULONG Length;
+ unsigned Srate;
+ unsigned Days;
+ unsigned Custom1;
+ unsigned Custom2;
+ char Info[16];
+ char extend[64];
+ unsigned Crc;
+};
+
+#define DVMS_HEADER_LEN 120
+
+/* ---------------------------------------------------------------------- */
+
+static ULONG get32(p)
+unsigned char **p;
+{
+ ULONG val = (((*p)[3]) << 24) | (((*p)[2]) << 16) |
+ (((*p)[1]) << 8) | (**p);
+ (*p) += 4;
+ return val;
+}
+
+static unsigned get16(p)
+unsigned char **p;
+{
+ unsigned val = (((*p)[1]) << 8) | (**p);
+ (*p) += 2;
+ return val;
+}
+
+static void put32(p, val)
+unsigned char **p;
+ULONG val;
+{
+ *(*p)++ = val & 0xff;
+ *(*p)++ = (val >> 8) & 0xff;
+ *(*p)++ = (val >> 16) & 0xff;
+ *(*p)++ = (val >> 24) & 0xff;
+}
+
+static void put16(p, val)
+unsigned char **p;
+unsigned val;
+{
+ *(*p)++ = val & 0xff;
+ *(*p)++ = (val >> 8) & 0xff;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void dvms_read_header(f, hdr)
+FILE *f;
+struct dvms_header *hdr;
+{
+ unsigned char hdrbuf[DVMS_HEADER_LEN];
+ unsigned char *pch = hdrbuf;
+ int i;
+ unsigned sum;
+
+ if (fread(hdrbuf, sizeof(hdrbuf), 1, f) != 1)
+ fail("unable to read DVMS header\n");
+ for(i = sizeof(hdrbuf), sum = 0; i > /*2*/3; i--) /* Deti bug */
+ sum += *pch++;
+ pch = hdrbuf;
+ memcpy(hdr->Filename, pch, sizeof(hdr->Filename));
+ pch += sizeof(hdr->Filename);
+ hdr->Id = get16(&pch);
+ hdr->State = get16(&pch);
+ hdr->Unixtime = get32(&pch);
+ hdr->Usender = get16(&pch);
+ hdr->Ureceiver = get16(&pch);
+ hdr->Length = get32(&pch);
+ hdr->Srate = get16(&pch);
+ hdr->Days = get16(&pch);
+ hdr->Custom1 = get16(&pch);
+ hdr->Custom2 = get16(&pch);
+ memcpy(hdr->Info, pch, sizeof(hdr->Info));
+ pch += sizeof(hdr->Info);
+ memcpy(hdr->extend, pch, sizeof(hdr->extend));
+ pch += sizeof(hdr->extend);
+ hdr->Crc = get16(&pch);
+ if (sum != hdr->Crc)
+ fail("DVMS header checksum error, read %u, calculated %u\n",
+ hdr->Crc, sum);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * note! file must be seekable
+ */
+static void dvms_write_header(f, hdr)
+FILE *f;
+struct dvms_header *hdr;
+{
+ unsigned char hdrbuf[DVMS_HEADER_LEN];
+ unsigned char *pch = hdrbuf;
+ unsigned char *pchs = hdrbuf;
+ int i;
+ unsigned sum;
+
+ memcpy(pch, hdr->Filename, sizeof(hdr->Filename));
+ pch += sizeof(hdr->Filename);
+ put16(&pch, hdr->Id);
+ put16(&pch, hdr->State);
+ put32(&pch, hdr->Unixtime);
+ put16(&pch, hdr->Usender);
+ put16(&pch, hdr->Ureceiver);
+ put32(&pch, hdr->Length);
+ put16(&pch, hdr->Srate);
+ put16(&pch, hdr->Days);
+ put16(&pch, hdr->Custom1);
+ put16(&pch, hdr->Custom2);
+ memcpy(pch, hdr->Info, sizeof(hdr->Info));
+ pch += sizeof(hdr->Info);
+ memcpy(pch, hdr->extend, sizeof(hdr->extend));
+ pch += sizeof(hdr->extend);
+ for(i = sizeof(hdrbuf), sum = 0; i > /*2*/3; i--) /* Deti bug */
+ sum += *pchs++;
+ hdr->Crc = sum;
+ put16(&pch, hdr->Crc);
+ if (fseek(f, 0, SEEK_SET) < 0)
+ fail("cannot write DVMS header, seek failed\n");
+ if (fwrite(hdrbuf, sizeof(hdrbuf), 1, f) != 1)
+ fail("cannot write DVMS header\n");
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void make_dvms_hdr(ft, hdr)
+ft_t ft;
+struct dvms_header *hdr;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ int len;
+
+ memset(hdr->Filename, 0, sizeof(hdr->Filename));
+ len = strlen(ft->filename);
+ if (len >= sizeof(hdr->Filename))
+ len = sizeof(hdr->Filename)-1;
+ memcpy(hdr->Filename, ft->filename, len);
+ hdr->Id = hdr->State = 0;
+ hdr->Unixtime = time(NULL);
+ hdr->Usender = hdr->Ureceiver = 0;
+ hdr->Length = p->bytes_written;
+ hdr->Srate = p->cvsd_rate/100;
+ hdr->Days = hdr->Custom1 = hdr->Custom2 = 0;
+ memset(hdr->Info, 0, sizeof(hdr->Info));
+ len = strlen(ft->comment);
+ if (len >= sizeof(hdr->Info))
+ len = sizeof(hdr->Info)-1;
+ memcpy(hdr->Info, ft->comment, len);
+ memset(hdr->extend, 0, sizeof(hdr->extend));
+}
+
+/* ---------------------------------------------------------------------- */
+
+void dvmsstartread(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ struct dvms_header hdr;
+
+ dvms_read_header(ft->fp, &hdr);
+ report("DVMS header of source file \"%s\":");
+ report(" filename \"%.14s\"",ft->filename);
+ report(" id 0x%x", hdr.Filename);
+ report(" state 0x%x", hdr.Id, hdr.State);
+ report(" time %s",ctime(&hdr.Unixtime)); /* ctime generates lf */
+ report(" usender %u", hdr.Usender);
+ report(" ureceiver %u", hdr.Ureceiver);
+ report(" length %u", hdr.Length);
+ report(" srate %u", hdr.Srate);
+ report(" days %u", hdr.Days);
+ report(" custom1 %u", hdr.Custom1);
+ report(" custom2 %u", hdr.Custom2);
+ report(" info \"%.16s\"\n", hdr.Info);
+ ft->info.rate = (hdr.Srate < 240) ? 16000 : 32000;
+ report("DVMS rate %dbit/s using %dbit/s deviation %d%%\n",
+ hdr.Srate*100, ft->info.rate,
+ ((ft->info.rate - hdr.Srate*100) * 100) / ft->info.rate);
+ cvsdstartread(ft);
+ p->swapbits = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void dvmsstartwrite(ft)
+ft_t ft;
+{
+ struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
+ struct dvms_header hdr;
+
+ cvsdstartwrite(ft);
+ make_dvms_hdr(ft, &hdr);
+ dvms_write_header(ft->fp, &hdr);
+ if (!ft->seekable)
+ warn("Length in output .DVMS header will wrong since can't seek to fix it");
+ p->swapbits = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void
+dvmsstopwrite(ft)
+ft_t ft;
+{
+ struct dvms_header hdr;
+
+ cvsdstopwrite(ft);
+ if (!ft->seekable)
+ return;
+ if (fseek(ft->fp, 0L, 0) != 0)
+ fail("Can't rewind output file to rewrite DVMS header.");
+ make_dvms_hdr(ft, &hdr);
+ dvms_write_header(ft->fp, &hdr);
+}
+
+/* ---------------------------------------------------------------------- */
--- /dev/null
+++ b/src/cvsdfilt.h
@@ -1,0 +1,121 @@
+/*
+ * CVSD (Continuously Variable Slope Delta modulation)
+ * conversion routines
+ *
+ * The CVSD format is described in the MIL Std 188 113, which is
+ * available from http://bbs.itsi.disa.mil:5580/T3564
+ *
+ * Copyright (C) 1996
+ * Thomas Sailer (sailer@ife.ee.ethz.ch) (HB9JNX/AE4WA)
+ * Swiss Federal Institute of Technology, Electronics Lab
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* ---------------------------------------------------------------------- */
+
+#define ENC_FILTERLEN 16 /* PCM sampling rate */
+#define DEC_FILTERLEN 48 /* CVSD sampling rate */
+
+/* ---------------------------------------------------------------------- */
+
+static float dec_filter_16[48] = {
+ 0.001102, 0.001159, 0.000187, -0.000175,
+ 0.002097, 0.006543, 0.009384, 0.008004,
+ 0.006562, 0.013569, 0.030745, 0.047053,
+ 0.050491, 0.047388, 0.062171, 0.109115,
+ 0.167120, 0.197144, 0.195471, 0.222098,
+ 0.354745, 0.599184, 0.849632, 0.956536,
+ 0.849632, 0.599184, 0.354745, 0.222098,
+ 0.195471, 0.197144, 0.167120, 0.109115,
+ 0.062171, 0.047388, 0.050491, 0.047053,
+ 0.030745, 0.013569, 0.006562, 0.008004,
+ 0.009384, 0.006543, 0.002097, -0.000175,
+ 0.000187, 0.001159, 0.001102, 0.000000
+};
+
+/* ---------------------------------------------------------------------- */
+
+static float dec_filter_32[48] = {
+ 0.001950, 0.004180, 0.006331, 0.007907,
+ 0.008510, 0.008342, 0.008678, 0.011827,
+ 0.020282, 0.035231, 0.055200, 0.075849,
+ 0.091585, 0.098745, 0.099031, 0.101287,
+ 0.120058, 0.170672, 0.262333, 0.392047,
+ 0.542347, 0.684488, 0.786557, 0.823702,
+ 0.786557, 0.684488, 0.542347, 0.392047,
+ 0.262333, 0.170672, 0.120058, 0.101287,
+ 0.099031, 0.098745, 0.091585, 0.075849,
+ 0.055200, 0.035231, 0.020282, 0.011827,
+ 0.008678, 0.008342, 0.008510, 0.007907,
+ 0.006331, 0.004180, 0.001950, -0.000000
+};
+
+/* ---------------------------------------------------------------------- */
+
+static float enc_filter_16_0[16] = {
+ -0.000362, 0.004648, 0.001381, 0.008312,
+ 0.041490, -0.001410, 0.124061, 0.247446,
+ -0.106761, -0.236326, -0.023798, -0.023506,
+ -0.030097, 0.001493, -0.005363, -0.001672
+};
+
+static float enc_filter_16_1[16] = {
+ 0.001672, 0.005363, -0.001493, 0.030097,
+ 0.023506, 0.023798, 0.236326, 0.106761,
+ -0.247446, -0.124061, 0.001410, -0.041490,
+ -0.008312, -0.001381, -0.004648, 0.000362
+};
+
+static float *enc_filter_16[2] = {
+ enc_filter_16_0, enc_filter_16_1
+};
+
+/* ---------------------------------------------------------------------- */
+
+static float enc_filter_32_0[16] = {
+ -0.000289, 0.002112, 0.001421, 0.002235,
+ 0.021003, 0.001237, 0.047132, 0.129636,
+ -0.027328, -0.126462, -0.021456, -0.008069,
+ -0.017959, 0.000301, -0.002538, -0.001278
+};
+
+static float enc_filter_32_1[16] = {
+ -0.000010, 0.002787, 0.000055, 0.006813,
+ 0.020249, -0.000995, 0.077912, 0.112870,
+ -0.076980, -0.106971, -0.005096, -0.015449,
+ -0.012591, 0.000813, -0.003003, -0.000527
+};
+
+static float enc_filter_32_2[16] = {
+ 0.000527, 0.003003, -0.000813, 0.012591,
+ 0.015449, 0.005096, 0.106971, 0.076980,
+ -0.112870, -0.077912, 0.000995, -0.020249,
+ -0.006813, -0.000055, -0.002787, 0.000010
+};
+
+static float enc_filter_32_3[16] = {
+ 0.001278, 0.002538, -0.000301, 0.017959,
+ 0.008069, 0.021456, 0.126462, 0.027328,
+ -0.129636, -0.047132, -0.001237, -0.021003,
+ -0.002235, -0.001421, -0.002112, 0.000289
+};
+
+static float *enc_filter_32[4] = {
+ enc_filter_32_0, enc_filter_32_1, enc_filter_32_2, enc_filter_32_3
+};
+
+/* ---------------------------------------------------------------------- */
--- /dev/null
+++ b/src/dat.c
@@ -1,0 +1,133 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools text format file. Tom Littlejohn, March 93.
+ *
+ * Reads/writes sound files as text for use with fft and graph.
+ *
+ * June 28, 93: force output to mono.
+ *
+ * September 24, 1998: cbagwell - Set up extra output format info so that
+ * reports are accurate. Also warn user when forcing to mono.
+ *
+ */
+
+#include "st.h"
+#include "libst.h"
+
+/* Private data for dat file */
+typedef struct dat {
+ double timevalue, deltat;
+} *dat_t;
+
+LONG roundoff(x)
+double x;
+{
+ if (x < 0.0) return(x - 0.5);
+ else return(x + 0.5);
+ }
+
+void
+datstartread(ft)
+ft_t ft;
+{
+ char inpstr[82];
+ char sc;
+
+ while (ft->info.rate == 0) {
+ fgets(inpstr,82,ft->fp);
+ sscanf(inpstr," %c",&sc);
+ if (sc != ';') fail("Cannot determine sample rate.");
+#ifdef __alpha__
+ sscanf(inpstr," ; Sample Rate %d", &ft->info.rate);
+#else
+ sscanf(inpstr," ; Sample Rate %ld",&ft->info.rate);
+#endif
+ }
+
+ /* size and style are really not necessary except to satisfy caller. */
+
+ ft->info.size = DOUBLE;
+ ft->info.style = SIGN2;
+}
+
+void
+datstartwrite(ft)
+ft_t ft;
+{
+ dat_t dat = (dat_t) ft->priv;
+ double srate;
+
+ if (ft->info.channels > 1)
+ {
+ report("Can only create .dat files with one channel.");
+ report("Forcing output to 1 channel.");
+ ft->info.channels = 1;
+ }
+
+ ft->info.size = DOUBLE;
+ ft->info.style = SIGN2;
+ dat->timevalue = 0.0;
+ srate = ft->info.rate;
+ dat->deltat = 1.0 / srate;
+#ifdef __alpha__
+ fprintf(ft->fp,"; Sample Rate %d\015\n", ft->info.rate);
+#else
+ fprintf(ft->fp,"; Sample Rate %ld\015\n",ft->info.rate);
+#endif
+}
+
+LONG datread(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ char inpstr[82];
+ double sampval;
+ int retc;
+ int done = 0;
+ char sc;
+
+ while (done < nsamp) {
+ do {
+ fgets(inpstr,82,ft->fp);
+ if (feof(ft->fp)) {
+ return (done);
+ }
+ sscanf(inpstr," %c",&sc);
+ }
+ while(sc == ';'); /* eliminate comments */
+ retc = sscanf(inpstr,"%*s %lg",&sampval);
+ if (retc != 1) fail("Unable to read sample.");
+ *buf++ = roundoff(sampval * 2.147483648e9);
+ ++done;
+ }
+ return (done);
+}
+
+void
+datwrite(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ dat_t dat = (dat_t) ft->priv;
+ int done = 0;
+ double sampval;
+
+ while(done < nsamp) {
+ sampval = *buf++ ;
+ sampval = sampval / 2.147483648e9; /* normalize to approx 1.0 */
+ fprintf(ft->fp," %15.8g %15.8g \015\n",dat->timevalue,sampval);
+ dat->timevalue += dat->deltat;
+ done++;
+ }
+ return;
+}
+
--- /dev/null
+++ b/src/deemphas.c
@@ -1,0 +1,201 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Fixed deemphasis filter for processing pre-emphasized audio cd samples
+ * 09/02/98 (c) Heiko Ei�feldt
+ * License: GPL (Gnu Public License)
+ *
+ * This implements the inverse filter of the optional pre-emphasis stage as
+ * defined by ISO 908 (describing the audio cd format).
+ *
+ * Background:
+ * In the early days of audio cds, there were recording problems
+ * with noise (for example in classical recordings). The high dynamics
+ * of audio cds exposed these recording errors a lot.
+ *
+ * The commonly used solution at that time was to 'pre-emphasize' the
+ * trebles to have a better signal-noise-ratio. That is trebles were
+ * amplified before recording, so that they would give a stronger
+ * signal compared to the underlying (tape)noise.
+ *
+ * For that purpose the audio signal was prefiltered with the following
+ * frequency response (simple first order filter):
+ *
+ * V (in dB)
+ * ^
+ * |
+ * | _________________
+ * | /
+ * | / |
+ * | 20 dB / decade ->/ |
+ * | / |
+ * |____________________/_ _ |_ _ _ _ _ _ _ _ _ _ _ _ _ lg f
+ * |0 dB | |
+ * | | |
+ * | | |
+ * 3.1KHz ca. 10KHz
+ *
+ * So the recorded audio signal has amplified trebles compared to the
+ * original.
+ * HiFi cd players do correct this by applying an inverse filter
+ * automatically, the cd-rom drives or cd burners used by digital
+ * sampling programs (like cdda2wav) however do not.
+ *
+ * So, this is what this effect does.
+ *
+ * Here is the gnuplot file for the frequency response
+ of the deemphasis. The error is below +-0.1dB
+
+-------- Start of gnuplot file ---------------------
+# first define the ideal filter. We use the tenfold sampling frequency.
+T=1./441000.
+OmegaU=1./15E-6
+OmegaL=15./50.*OmegaU
+V0=OmegaL/OmegaU
+H0=V0-1.
+B=V0*tan(OmegaU*T/2.)
+# the coefficients follow
+a1=(B - 1.)/(B + 1.)
+b0=(1.0 + (1.0 - a1) * H0/2.)
+b1=(a1 + (a1 - 1.0) * H0/2.)
+# helper variables
+D=b1/b0
+o=2*pi*T
+H2(f)=b0*sqrt((1+2*cos(f*o)*D+D*D)/(1+2*cos(f*o)*a1+a1*a1))
+#
+# now approximate the ideal curve with a fitted one for sampling
+frequency
+# of 44100 Hz. Fitting parameters are
+# amplification at high frequencies V02
+# and tau of the upper edge frequency OmegaU2 = 2 *pi * f(upper)
+T2=1./44100.
+V02=0.3365
+OmegaU2=1./19E-6
+B2=V02*tan(OmegaU2*T2/2.)
+# the coefficients follow
+a12=(B2 - 1.)/(B2 + 1.)
+b02=(1.0 + (1.0 - a12) * (V02-1.)/2.)
+b12=(a12 + (a12 - 1.0) * (V02-1.)/2.)
+# helper variables
+D2=b12/b02
+o2=2*pi*T2
+H(f)=b02*sqrt((1+2*cos(f*o2)*D2+D2*D2)/(1+2*cos(f*o2)*a12+a12*a12))
+# plot best, real, ideal, level with halved attenuation,
+# level at full attentuation, 10fold magnified error
+set logscale x
+set grid xtics ytics mxtics mytics
+plot [f=1000:20000] [-12:2] 20*log10(H(f)),20*log10(H2(f)),
+20*log10(OmegaL/(2*
+pi*f)), 0.5*20*log10(V0), 20*log10(V0), 200*log10(H(f)/H2(f))
+pause -1 "Hit return to continue"
+-------- End of gnuplot file ---------------------
+
+ */
+
+/*
+ * adapted from Sound Tools skeleton effect file.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for deemph file */
+typedef struct deemphstuff {
+ LONG lastin;
+ double lastout;
+} *deemph_t;
+
+/*
+ * Process options
+ *
+ * Don't do initialization now.
+ * The 'info' fields are not yet filled in.
+ */
+void deemph_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Deemphasis filtering effect takes no options.\n");
+ if (sizeof(double)*PRIVSIZE < sizeof(struct deemphstuff))
+ fail("Internal error: PRIVSIZE too small.\n");
+}
+
+/*
+ * Prepare processing.
+ * Do all initializations.
+ */
+void deemph_start(effp)
+eff_t effp;
+{
+ /* check the input format */
+ if (effp->ininfo.style != SIGN2
+ || effp->ininfo.rate != 44100
+ || effp->ininfo.size != WORD)
+ fail("The deemphasis effect works only with audio cd like samples.\nThe input format however has %d Hz sample rate and %d-byte%s signed linearly coded samples.",
+ effp->ininfo.rate, effp->ininfo.size,
+ effp->ininfo.style != SIGN2 ? ", but not" : "");
+ {
+ deemph_t deemph = (deemph_t) effp->priv;
+
+ deemph->lastin = 0;
+ deemph->lastout = 0.0;
+ }
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+/* filter coefficients */
+#define a1 -0.62786881719628784282
+#define b0 0.45995451989513153057
+#define b1 -0.08782333709141937339
+
+void deemph_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ deemph_t deemph = (deemph_t) effp->priv;
+ int len, done;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = len; done; done--) {
+ deemph->lastout = *ibuf * b0 +
+ deemph->lastin * b1 -
+ deemph->lastout * a1;
+ deemph->lastin = *ibuf++;
+ *obuf++ = deemph->lastout > 0.0 ?
+ deemph->lastout + 0.5 :
+ deemph->lastout - 0.5;
+ }
+}
+
+/*
+ * Drain out remaining samples if the effect generates any.
+ */
+
+void deemph_drain(effp, obuf, osamp)
+LONG *obuf;
+int *osamp;
+{
+ /* nothing to do */
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * (free allocated memory, etc.)
+ */
+void deemph_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
--- /dev/null
+++ b/src/echo.c
@@ -1,0 +1,260 @@
+/*
+ * August 24, 1998
+ * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Juergen Mueller And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * This is the "echo.c" while the old "echo.c" from version 12 moves to
+ * "reverb.c" satisfying the defintions made in the Guitar FX FAQ.
+ *
+ *
+ * Echo effect for dsp.
+ *
+ * Flow diagram scheme for n delays ( 1 <= n <= MAX_ECHOS ):
+ *
+ * * gain-in ___
+ * ibuff -----------+------------------------------------------>| |
+ * | _________ | |
+ * | | | * decay 1 | |
+ * +----->| delay 1 |------------------------->| |
+ * | |_________| | |
+ * | _________ | + |
+ * | | | * decay 2 | |
+ * +---------->| delay 2 |-------------------->| |
+ * | |_________| | |
+ * : _________ | |
+ * | | | * decay n | |
+ * +--------------->| delay n |--------------->|___|
+ * |_________| |
+ * | * gain-out
+ * |
+ * +----->obuff
+ *
+ * Usage:
+ * echo gain-in gain-out delay-1 decay-1 [delay-2 decay-2 ... delay-n decay-n]
+ *
+ * Where:
+ * gain-in, decay-1 ... decay-n : 0.0 ... 1.0 volume
+ * gain-out : 0.0 ... volume
+ * delay-1 ... delay-n : > 0.0 msec
+ *
+ * Note:
+ * when decay is close to 1.0, the samples can begin clipping and the output
+ * can saturate!
+ *
+ * Hint:
+ * 1 / out-gain > gain-in ( 1 + decay-1 + ... + decay-n )
+ *
+*/
+
+/*
+ * Sound Tools reverb effect file.
+ */
+
+#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
+#include <math.h>
+#include "st.h"
+
+#define DELAY_BUFSIZ ( 50L * MAXRATE )
+#define MAX_ECHOS 7 /* 24 bit x ( 1 + MAX_ECHOS ) = */
+ /* 24 bit x 8 = 32 bit !!! */
+
+/* Private data for SKEL file */
+typedef struct echostuff {
+ int counter;
+ int num_delays;
+ double *delay_buf;
+ float in_gain, out_gain;
+ float delay[MAX_ECHOS], decay[MAX_ECHOS];
+ long samples[MAX_ECHOS], maxsamples, fade_out;
+} *echo_t;
+
+/* Private data for SKEL file */
+
+
+/* If we are not carefull with the output volume */
+LONG echo_clip24(l)
+LONG l;
+{
+ if (l >= ((LONG)1 << 24))
+ return ((LONG)1 << 24) - 1;
+ else if (l <= -((LONG)1 << 24))
+ return -((LONG)1 << 24) + 1;
+ else
+ return l;
+}
+
+
+
+/*
+ * Process options
+ */
+void echo_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ echo_t echo = (echo_t) effp->priv;
+ int i;
+
+ echo->num_delays = 0;
+
+ if ((n < 4) || (n % 2))
+ fail("Usage: echo gain-in gain-out delay decay [ delay decay ... ]");
+
+ i = 0;
+ sscanf(argv[i++], "%f", &echo->in_gain);
+ sscanf(argv[i++], "%f", &echo->out_gain);
+ while (i < n) {
+ if ( echo->num_delays >= MAX_ECHOS )
+ fail("echo: to many delays, use less than %i delays",
+ MAX_ECHOS);
+ /* Linux bug and it's cleaner. */
+ sscanf(argv[i++], "%f", &echo->delay[echo->num_delays]);
+ sscanf(argv[i++], "%f", &echo->decay[echo->num_delays]);
+ echo->num_delays++;
+ }
+}
+
+/*
+ * Prepare for processing.
+ */
+void echo_start(effp)
+eff_t effp;
+{
+ echo_t echo = (echo_t) effp->priv;
+ int i;
+ float sum_in_volume;
+ long j;
+
+ echo->maxsamples = 0L;
+ if ( echo->in_gain < 0.0 )
+ fail("echo: gain-in must be positive!\n");
+ if ( echo->in_gain > 1.0 )
+ fail("echo: gain-in must be less than 1.0!\n");
+ if ( echo->out_gain < 0.0 )
+ fail("echo: gain-in must be positive!\n");
+ for ( i = 0; i < echo->num_delays; i++ ) {
+ echo->samples[i] = echo->delay[i] * effp->ininfo.rate / 1000.0;
+ if ( echo->samples[i] < 1 )
+ fail("echo: delay must be positive!\n");
+ if ( echo->samples[i] > DELAY_BUFSIZ )
+ fail("echo: delay must be less than %g seconds!\n",
+ DELAY_BUFSIZ / (float) effp->ininfo.rate );
+ if ( echo->decay[i] < 0.0 )
+ fail("echo: decay must be positive!\n" );
+ if ( echo->decay[i] > 1.0 )
+ fail("echo: decay must be less than 1.0!\n" );
+ if ( echo->samples[i] > echo->maxsamples )
+ echo->maxsamples = echo->samples[i];
+ }
+ if (! (echo->delay_buf = (double *) malloc(sizeof (double) * echo->maxsamples)))
+ fail("echo: Cannot malloc %d bytes!\n",
+ sizeof(long) * echo->maxsamples);
+ for ( j = 0; j < echo->maxsamples; ++j )
+ echo->delay_buf[j] = 0.0;
+ /* Be nice and check the hint with warning, if... */
+ sum_in_volume = 1.0;
+ for ( i = 0; i < echo->num_delays; i++ )
+ sum_in_volume += echo->decay[i];
+ if ( sum_in_volume * echo->in_gain > 1.0 / echo->out_gain )
+ warn("echo: warning >>> gain-out can cause saturation of output <<<");
+ echo->counter = 0;
+ echo->fade_out = echo->maxsamples;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void echo_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ echo_t echo = (echo_t) effp->priv;
+ int len, done;
+ int j;
+
+ double d_in, d_out;
+ LONG out;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* Store delays as 24-bit signed longs */
+ d_in = (double) *ibuf++ / 256;
+ /* Compute output first */
+ d_out = d_in * echo->in_gain;
+ for ( j = 0; j < echo->num_delays; j++ ) {
+ d_out += echo->delay_buf[
+(echo->counter + echo->maxsamples - echo->samples[j]) % echo->maxsamples]
+ * echo->decay[j];
+ }
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * echo->out_gain;
+ out = echo_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Store input in delay buffer */
+ echo->delay_buf[echo->counter] = d_in;
+ /* Adjust the counter */
+ echo->counter = ( echo->counter + 1 ) % echo->maxsamples;
+ }
+ /* processed all samples */
+}
+
+/*
+ * Drain out reverb lines.
+ */
+void echo_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ echo_t echo = (echo_t) effp->priv;
+ double d_in, d_out;
+ LONG out;
+ int j;
+ long done;
+
+ done = 0;
+ /* drain out delay samples */
+ while ( ( done < *osamp ) && ( done < echo->fade_out ) ) {
+ d_in = 0;
+ d_out = 0;
+ for ( j = 0; j < echo->num_delays; j++ ) {
+ d_out += echo->delay_buf[
+(echo->counter + echo->maxsamples - echo->samples[j]) % echo->maxsamples]
+ * echo->decay[j];
+ }
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * echo->out_gain;
+ out = echo_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Store input in delay buffer */
+ echo->delay_buf[echo->counter] = d_in;
+ /* Adjust the counters */
+ echo->counter = ( echo->counter + 1 ) % echo->maxsamples;
+ done++;
+ echo->fade_out--;
+ };
+ /* samples played, it remains */
+ *osamp = done;
+}
+
+/*
+ * Clean up reverb effect.
+ */
+void echo_stop(effp)
+eff_t effp;
+{
+ echo_t echo = (echo_t) effp->priv;
+
+ free((char *) echo->delay_buf);
+ echo->delay_buf = (double *) -1; /* guaranteed core dump */
+}
+
--- /dev/null
+++ b/src/echos.c
@@ -1,0 +1,262 @@
+/*
+ * August 24, 1998
+ * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Juergen Mueller And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Echos effect for dsp.
+ *
+ * Flow diagram scheme for n delays ( 1 <= n <= MAX_ECHOS ):
+ *
+ * * gain-in ___
+ * ibuff --+--------------------------------------------------->| |
+ * | * decay 1 | |
+ * | +----------------------------------->| |
+ * | | * decay 2 | + |
+ * | | +--------------------->| |
+ * | | | * decay n | |
+ * | _________ | _________ | _________ +--->|___|
+ * | | | | | | | | | | |
+ * +-->| delay 1 |-+-| delay 2 |-+...-| delay n |--+ | * gain-out
+ * |_________| |_________| |_________| |
+ * +----->obuff
+ *
+ * Usage:
+ * echos gain-in gain-out delay-1 decay-1 [delay-2 decay-2 ... delay-n decay-n]
+ *
+ * Where:
+ * gain-in, decay-1 ... decay-n : 0.0 ... 1.0 volume
+ * gain-out : 0.0 ... volume
+ * delay-1 ... delay-n : > 0.0 msec
+ *
+ * Note:
+ * when decay is close to 1.0, the samples can begin clipping and the output
+ * can saturate!
+ *
+ * Hint:
+ * 1 / out-gain > gain-in ( 1 + decay-1 + ... + decay-n )
+ *
+*/
+
+/*
+ * Sound Tools reverb effect file.
+ */
+
+#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
+#include <math.h>
+#include "st.h"
+
+#define DELAY_BUFSIZ ( 50L * MAXRATE )
+#define MAX_ECHOS 7 /* 24 bit x ( 1 + MAX_ECHOS ) = */
+ /* 24 bit x 8 = 32 bit !!! */
+
+/* Private data for SKEL file */
+typedef struct echosstuff {
+ int counter[MAX_ECHOS];
+ int num_delays;
+ double *delay_buf;
+ float in_gain, out_gain;
+ float delay[MAX_ECHOS], decay[MAX_ECHOS];
+ long samples[MAX_ECHOS], pointer[MAX_ECHOS], sumsamples;
+} *echos_t;
+
+/* Private data for SKEL file */
+
+
+/* If we are not carefull with the output volume */
+LONG echos_clip24(l)
+LONG l;
+{
+ if (l >= ((LONG)1 << 24))
+ return ((LONG)1 << 24) - 1;
+ else if (l <= -((LONG)1 << 24))
+ return -((LONG)1 << 24) + 1;
+ else
+ return l;
+}
+
+
+
+/*
+ * Process options
+ */
+void echos_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ echos_t echos = (echos_t) effp->priv;
+ int i;
+
+ echos->num_delays = 0;
+
+ if ((n < 4) || (n % 2))
+ fail("Usage: echos gain-in gain-out delay decay [ delay decay ... ]");
+
+ i = 0;
+ sscanf(argv[i++], "%f", &echos->in_gain);
+ sscanf(argv[i++], "%f", &echos->out_gain);
+ while (i < n) {
+ /* Linux bug and it's cleaner. */
+ sscanf(argv[i++], "%f", &echos->delay[echos->num_delays]);
+ sscanf(argv[i++], "%f", &echos->decay[echos->num_delays]);
+ echos->num_delays++;
+ if ( echos->num_delays > MAX_ECHOS )
+ fail("echos: to many delays, use less than %i delays",
+ MAX_ECHOS);
+ }
+ echos->sumsamples = 0;
+}
+
+/*
+ * Prepare for processing.
+ */
+void echos_start(effp)
+eff_t effp;
+{
+ echos_t echos = (echos_t) effp->priv;
+ int i;
+ float sum_in_volume;
+ long j;
+
+ if ( echos->in_gain < 0.0 )
+ fail("echos: gain-in must be positive!\n");
+ if ( echos->in_gain > 1.0 )
+ fail("echos: gain-in must be less than 1.0!\n");
+ if ( echos->out_gain < 0.0 )
+ fail("echos: gain-in must be positive!\n");
+ for ( i = 0; i < echos->num_delays; i++ ) {
+ echos->samples[i] = echos->delay[i] * effp->ininfo.rate / 1000.0;
+ if ( echos->samples[i] < 1 )
+ fail("echos: delay must be positive!\n");
+ if ( echos->samples[i] > DELAY_BUFSIZ )
+ fail("echos: delay must be less than %g seconds!\n",
+ DELAY_BUFSIZ / (float) effp->ininfo.rate );
+ if ( echos->decay[i] < 0.0 )
+ fail("echos: decay must be positive!\n" );
+ if ( echos->decay[i] > 1.0 )
+ fail("echos: decay must be less than 1.0!\n" );
+ echos->counter[i] = 0;
+ echos->pointer[i] = echos->sumsamples;
+ echos->sumsamples += echos->samples[i];
+ }
+ if (! (echos->delay_buf = (double *) malloc(sizeof (double) * echos->sumsamples)))
+ fail("echos: Cannot malloc %d bytes!\n",
+ sizeof(long) * echos->sumsamples);
+ for ( j = 0; j < echos->samples[i]; ++j )
+ echos->delay_buf[j] = 0.0;
+ /* Be nice and check the hint with warning, if... */
+ sum_in_volume = 1.0;
+ for ( i = 0; i < echos->num_delays; i++ )
+ sum_in_volume += echos->decay[i];
+ if ( sum_in_volume * echos->in_gain > 1.0 / echos->out_gain )
+ warn("echos: warning >>> gain-out can cause saturation of output <<<");
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void echos_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ echos_t echos = (echos_t) effp->priv;
+ int len, done;
+ int j;
+
+ double d_in, d_out;
+ LONG out;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* Store delays as 24-bit signed longs */
+ d_in = (double) *ibuf++ / 256;
+ /* Compute output first */
+ d_out = d_in * echos->in_gain;
+ for ( j = 0; j < echos->num_delays; j++ ) {
+ d_out += echos->delay_buf[echos->counter[j] + echos->pointer[j]] * echos->decay[j];
+ }
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * echos->out_gain;
+ out = echos_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delays and input */
+ for ( j = 0; j < echos->num_delays; j++ ) {
+ if ( j == 0 )
+ echos->delay_buf[echos->counter[j] + echos->pointer[j]] = d_in;
+ else
+ echos->delay_buf[echos->counter[j] + echos->pointer[j]] =
+ echos->delay_buf[echos->counter[j-1] + echos->pointer[j-1]] + d_in;
+ }
+ /* Adjust the counters */
+ for ( j = 0; j < echos->num_delays; j++ )
+ echos->counter[j] =
+ ( echos->counter[j] + 1 ) % echos->samples[j];
+ }
+ /* processed all samples */
+}
+
+/*
+ * Drain out reverb lines.
+ */
+void echos_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ echos_t echos = (echos_t) effp->priv;
+ double d_in, d_out;
+ LONG out;
+ int j;
+ long done;
+
+ done = 0;
+ /* drain out delay samples */
+ while ( ( done < *osamp ) && ( done < echos->sumsamples ) ) {
+ d_in = 0;
+ d_out = 0;
+ for ( j = 0; j < echos->num_delays; j++ ) {
+ d_out += echos->delay_buf[echos->counter[j] + echos->pointer[j]] * echos->decay[j];
+ }
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * echos->out_gain;
+ out = echos_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delays and input */
+ for ( j = 0; j < echos->num_delays; j++ ) {
+ if ( j == 0 )
+ echos->delay_buf[echos->counter[j] + echos->pointer[j]] = d_in;
+ else
+ echos->delay_buf[echos->counter[j] + echos->pointer[j]] =
+ echos->delay_buf[echos->counter[j-1] + echos->pointer[j-1]];
+ }
+ /* Adjust the counters */
+ for ( j = 0; j < echos->num_delays; j++ )
+ echos->counter[j] =
+ ( echos->counter[j] + 1 ) % echos->samples[j];
+ done++;
+ echos->sumsamples--;
+ };
+ /* samples played, it remains */
+ *osamp = done;
+}
+
+/*
+ * Clean up reverb effect.
+ */
+void echos_stop(effp)
+eff_t effp;
+{
+ echos_t echos = (echos_t) effp->priv;
+
+ free((char *) echos->delay_buf);
+ echos->delay_buf = (double *) -1; /* guaranteed core dump */
+}
+
--- /dev/null
+++ b/src/flanger.c
@@ -1,0 +1,299 @@
+/*
+ * August 24, 1998
+ * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Juergen Mueller And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Flanger effect.
+ *
+ * Flow diagram scheme:
+ *
+ * * gain-in ___
+ * ibuff -----+--------------------------------------------->| |
+ * | _______ | |
+ * | | | * decay | |
+ * +---->| delay |------------------------------->| + |
+ * |_______| | |
+ * /|\ | |
+ * | |___|
+ * | |
+ * +---------------+ +------------------+ | * gain-out
+ * | Delay control |<-----| modulation speed | |
+ * +---------------+ +------------------+ +----->obuff
+ *
+ *
+ * The delay is controled by a sine or triangle modulation.
+ *
+ * Usage:
+ * flanger gain-in gain-out delay decay speed [ -s | -t ]
+ *
+ * Where:
+ * gain-in, decay : 0.0 ... 1.0 volume
+ * gain-out : 0.0 ... volume
+ * delay : 0.0 ... 5.0 msec
+ * speed : 0.1 ... 2.0 Hz modulation
+ * -s : modulation by sine (default)
+ * -t : modulation by triangle
+ *
+ * Note:
+ * when decay is close to 1.0, the samples may begin clipping or the output
+ * can saturate!
+ *
+ * Hint:
+ * 1 / out-gain > gain-in * ( 1 + decay )
+ *
+*/
+
+/*
+ * Sound Tools flanger effect file.
+ */
+
+#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
+#include <math.h>
+#include <string.h>
+#include "st.h"
+
+#define MOD_SINE 0
+#define MOD_TRIANGLE 1
+
+/* Private data for SKEL file */
+typedef struct flangerstuff {
+ int modulation;
+ int counter;
+ int phase;
+ double *flangerbuf;
+ float in_gain, out_gain;
+ float delay, decay;
+ float speed;
+ long length;
+ int *lookup_tab;
+ long maxsamples, fade_out;
+} *flanger_t;
+
+/* Private data for SKEL file */
+
+LONG flanger_clip24(l)
+LONG l;
+{
+ if (l >= ((LONG)1 << 24))
+ return ((LONG)1 << 24) - 1;
+ else if (l <= -((LONG)1 << 24))
+ return -((LONG)1 << 24) + 1;
+ else
+ return l;
+}
+
+/* This was very painful. We need a sine library. */
+
+void flanger_sine(buf, len, depth)
+int *buf;
+long len;
+long depth;
+{
+ long i;
+ double val;
+
+ for (i = 0; i < len; i++) {
+ val = sin((double)i/(double)len * 2.0 * M_PI);
+ buf[i] = (int) ((1.0 + val) * depth / 2.0);
+ }
+}
+
+void flanger_triangle(buf, len, depth)
+int *buf;
+long len;
+long depth;
+{
+ long i;
+ double val;
+
+ for (i = 0; i < len / 2; i++) {
+ val = i * 2.0 / len;
+ buf[i] = (int) (val * depth);
+ }
+ for (i = len / 2; i < len ; i++) {
+ val = (len - i) * 2.0 / len;
+ buf[i] = (int) (val * depth);
+ }
+}
+
+/*
+ * Process options
+ */
+void flanger_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ flanger_t flanger = (flanger_t) effp->priv;
+
+ if (!((n == 5) || (n == 6)))
+ fail("Usage: flanger gain-in gain-out delay decay speed [ -s | -t ]");
+
+ sscanf(argv[0], "%f", &flanger->in_gain);
+ sscanf(argv[1], "%f", &flanger->out_gain);
+ sscanf(argv[2], "%f", &flanger->delay);
+ sscanf(argv[3], "%f", &flanger->decay);
+ sscanf(argv[4], "%f", &flanger->speed);
+ flanger->modulation = MOD_SINE;
+ if ( n == 6 ) {
+ if ( !strcmp(argv[5], "-s"))
+ flanger->modulation = MOD_SINE;
+ else if ( ! strcmp(argv[5], "-t"))
+ flanger->modulation = MOD_TRIANGLE;
+ else
+ fail("Usage: flanger gain-in gain-out delay decay speed [ -s | -t ]");
+ }
+}
+
+/*
+ * Prepare for processing.
+ */
+void flanger_start(effp)
+eff_t effp;
+{
+ flanger_t flanger = (flanger_t) effp->priv;
+ int i;
+
+ flanger->maxsamples = flanger->delay * effp->ininfo.rate / 1000.0;
+
+ if ( flanger->in_gain < 0.0 )
+ fail("flanger: gain-in must be positive!\n");
+ if ( flanger->in_gain > 1.0 )
+ fail("flanger: gain-in must be less than 1.0!\n");
+ if ( flanger->out_gain < 0.0 )
+ fail("flanger: gain-out must be positive!\n");
+ if ( flanger->delay < 0.0 )
+ fail("flanger: delay must be positive!\n");
+ if ( flanger->delay > 5.0 )
+ fail("flanger: delay must be less than 5.0 msec!\n");
+ if ( flanger->speed < 0.1 )
+ fail("flanger: speed must be more than 0.1 Hz!\n");
+ if ( flanger->speed > 2.0 )
+ fail("flanger: speed must be less than 2.0 Hz!\n");
+ if ( flanger->decay < 0.0 )
+ fail("flanger: decay must be positive!\n" );
+ if ( flanger->decay > 1.0 )
+ fail("flanger: decay must be less that 1.0!\n" );
+ /* Be nice and check the hint with warning, if... */
+ if ( flanger->in_gain * ( 1.0 + flanger->decay ) > 1.0 / flanger->out_gain )
+ warn("flanger: warning >>> gain-out can cause saturation or clipping of output <<<");
+
+ flanger->length = effp->ininfo.rate / flanger->speed;
+
+ if (! (flanger->flangerbuf =
+ (double *) malloc(sizeof (double) * flanger->maxsamples)))
+ fail("flanger: Cannot malloc %d bytes!\n",
+ sizeof(double) * flanger->maxsamples);
+ for ( i = 0; i < flanger->maxsamples; i++ )
+ flanger->flangerbuf[i] = 0.0;
+ if (! (flanger->lookup_tab =
+ (int *) malloc(sizeof (int) * flanger->length)))
+ fail("flanger: Cannot malloc %d bytes!\n",
+ sizeof(int) * flanger->length);
+
+ if ( flanger->modulation == MOD_SINE )
+ flanger_sine(flanger->lookup_tab, flanger->length,
+ flanger->maxsamples - 1);
+ else
+ flanger_triangle(flanger->lookup_tab, flanger->length,
+ flanger->maxsamples - 1);
+ flanger->counter = 0;
+ flanger->phase = 0;
+ flanger->fade_out = flanger->maxsamples;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void flanger_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ flanger_t flanger = (flanger_t) effp->priv;
+ int len, done;
+
+ double d_in, d_out;
+ LONG out;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* Store delays as 24-bit signed longs */
+ d_in = (double) *ibuf++ / 256;
+ /* Compute output first */
+ d_out = d_in * flanger->in_gain;
+ d_out += flanger->flangerbuf[(flanger->maxsamples +
+ flanger->counter - flanger->lookup_tab[flanger->phase]) %
+ flanger->maxsamples] * flanger->decay;
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * flanger->out_gain;
+ out = flanger_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delay and input */
+ flanger->flangerbuf[flanger->counter] = d_in;
+ flanger->counter =
+ ( flanger->counter + 1 ) % flanger->maxsamples;
+ flanger->phase = ( flanger->phase + 1 ) % flanger->length;
+ }
+ /* processed all samples */
+}
+
+/*
+ * Drain out reverb lines.
+ */
+void flanger_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ flanger_t flanger = (flanger_t) effp->priv;
+ int done;
+
+ double d_in, d_out;
+ LONG out;
+
+ done = 0;
+ while ( ( done < *osamp ) && ( done < flanger->fade_out ) ) {
+ d_in = 0;
+ d_out = 0;
+ /* Compute output first */
+ d_out += flanger->flangerbuf[(flanger->maxsamples +
+ flanger->counter - flanger->lookup_tab[flanger->phase]) %
+ flanger->maxsamples] * flanger->decay;
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_out * flanger->out_gain;
+ out = flanger_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delay and input */
+ flanger->flangerbuf[flanger->counter] = d_in;
+ flanger->counter =
+ ( flanger->counter + 1 ) % flanger->maxsamples;
+ flanger->phase = ( flanger->phase + 1 ) % flanger->length;
+ done++;
+ flanger->fade_out--;
+ }
+ /* samples playd, it remains */
+ *osamp = done;
+}
+
+/*
+ * Clean up flanger effect.
+ */
+void flanger_stop(effp)
+eff_t effp;
+{
+ flanger_t flanger = (flanger_t) effp->priv;
+
+ free((char *) flanger->flangerbuf);
+ flanger->flangerbuf = (double *) -1; /* guaranteed core dump */
+ free((char *) flanger->lookup_tab);
+ flanger->lookup_tab = (int *) -1; /* guaranteed core dump */
+}
+
--- /dev/null
+++ b/src/g711.c
@@ -1,0 +1,288 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g711.c
+ *
+ * u-law, A-law and linear PCM conversions.
+ */
+#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
+#define QUANT_MASK (0xf) /* Quantization field mask. */
+#define NSEGS (8) /* Number of A-law segments. */
+#define SEG_SHIFT (4) /* Left shift for segment number. */
+#define SEG_MASK (0x70) /* Segment field mask. */
+
+/* copy from CCITT G.711 specifications */
+unsigned char _u2a[128] = { /* u- to A-law conversions */
+ 1, 1, 2, 2, 3, 3, 4, 4,
+ 5, 5, 6, 6, 7, 7, 8, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 27, 29, 31, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44,
+ 46, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128};
+
+unsigned char _a2u[128] = { /* A- to u-law conversions */
+ 1, 3, 5, 7, 9, 11, 13, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 32, 33, 33, 34, 34, 35, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 48, 49, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127};
+
+/* see libst.h */
+#ifdef SUPERCEDED
+
+static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
+ 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+
+static 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);
+}
+
+/*
+ * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
+ *
+ * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
+ *
+ * Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 0000000wxyza 000wxyz
+ * 0000001wxyza 001wxyz
+ * 000001wxyzab 010wxyz
+ * 00001wxyzabc 011wxyz
+ * 0001wxyzabcd 100wxyz
+ * 001wxyzabcde 101wxyz
+ * 01wxyzabcdef 110wxyz
+ * 1wxyzabcdefg 111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char
+linear2alaw(pcm_val)
+ int pcm_val; /* 2's complement (16-bit range) */
+{
+ int mask;
+ int seg;
+ unsigned char aval;
+
+ if (pcm_val >= 0) {
+ mask = 0xD5; /* sign (7th) bit = 1 */
+ } else {
+ mask = 0x55; /* sign bit = 0 */
+ pcm_val = -pcm_val - 8;
+ }
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_end, 8);
+
+ /* Combine the sign, segment, and quantization bits. */
+
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (0x7F ^ mask);
+ else {
+ aval = seg << SEG_SHIFT;
+ if (seg < 2)
+ aval |= (pcm_val >> 4) & QUANT_MASK;
+ else
+ aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
+ return (aval ^ mask);
+ }
+}
+
+/*
+ * alaw2linear() - Convert an A-law value to 16-bit linear PCM
+ *
+ */
+int
+alaw2linear(a_val)
+ unsigned char a_val;
+{
+ int t;
+ int seg;
+
+ a_val ^= 0x55;
+
+ t = (a_val & QUANT_MASK) << 4;
+ seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
+ switch (seg) {
+ case 0:
+ t += 8;
+ break;
+ case 1:
+ t += 0x108;
+ break;
+ default:
+ t += 0x108;
+ t <<= seg - 1;
+ }
+ return ((a_val & SIGN_BIT) ? t : -t);
+}
+
+#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.
+ */
+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);
+ }
+
+}
+
+/*
+ * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
+ *
+ * First, a biased linear code is derived from the code word. An unbiased
+ * output can then be obtained by subtracting 33 from the biased code.
+ *
+ * Note that this function expects to be passed the complement of the
+ * original code word. This is in keeping with ISDN conventions.
+ */
+int
+ulaw2linear(u_val)
+ unsigned char u_val;
+{
+ int t;
+
+ /* Complement to obtain normal u-law value. */
+ u_val = ~u_val;
+
+ /*
+ * Extract and bias the quantization bits. Then
+ * shift up by the segment number and subtract out the bias.
+ */
+ t = ((u_val & QUANT_MASK) << 3) + BIAS;
+ t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
+
+ return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
+}
+
+#endif
+
+/* A-law to u-law conversion */
+unsigned char
+alaw2ulaw(aval)
+ unsigned char aval;
+{
+ aval &= 0xff;
+ return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
+ (0x7F ^ _a2u[aval ^ 0x55]));
+}
+
+/* u-law to A-law conversion */
+unsigned char
+ulaw2alaw(uval)
+ unsigned char uval;
+{
+ uval &= 0xff;
+ return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
+ (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
+}
--- /dev/null
+++ b/src/g721.c
@@ -1,0 +1,176 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g721.c
+ *
+ * Description:
+ *
+ * g721_encoder(), g721_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.721 ADPCM
+ * coding algorithm. Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of work station attributes, such as hardware 2's
+ * complement arithmetic and large memory. Specifically, certain time
+ * consuming operations such as multiplications are replaced
+ * with lookup tables and software 2's complement operations are
+ * replaced with hardware 2's complement.
+ *
+ * The deviation from the bit level specification (lookup tables)
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.721 Recommendation, the algorithm is broken
+ * down into modules. Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+
+#include "st.h"
+#include "g72x.h"
+#include "libst.h"
+
+static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
+/*
+ * Maps G.721 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
+ 425, 373, 323, 273, 213, 135, 4, -2048};
+
+/* Maps G.721 code word to log of scale factor multiplier. */
+static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
+ 1122, 355, 198, 112, 64, 41, 18, -12};
+/*
+ * Maps G.721 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
+ 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
+
+/*
+ * g721_encoder()
+ *
+ * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
+ * the resulting code. -1 is returned for unknown input coding value.
+ */
+int
+g721_encoder(sl, in_coding,state_ptr)
+ int sl;
+ int in_coding;
+ struct g72x_state *state_ptr;
+{
+ short sezi, se, sez; /* ACCUM */
+ short d; /* SUBTA */
+ short sr; /* ADDB */
+ short y; /* MIX */
+ short dqsez; /* ADDC */
+ short dq, i;
+
+ switch (in_coding) { /* linearize input sample to 14-bit PCM */
+ case AUDIO_ENCODING_ALAW:
+ sl = st_Alaw_to_linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_ULAW:
+ sl = st_ulaw_to_linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_LINEAR:
+ sl >>= 2; /* 14-bit dynamic range */
+ break;
+ default:
+ return (-1);
+ }
+
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
+
+ d = sl - se; /* estimation difference */
+
+ /* quantize the prediction difference */
+ y = step_size(state_ptr); /* quantizer step size */
+ i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
+
+ dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
+
+ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
+
+ dqsez = sr + sez - se; /* pole prediction diff. */
+
+ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+ return (i);
+}
+
+/*
+ * g721_decoder()
+ *
+ * Description:
+ *
+ * Decodes a 4-bit code of G.721 encoded data of i and
+ * returns the resulting linear PCM, A-law or u-law value.
+ * return -1 for unknown out_coding value.
+ */
+int
+g721_decoder(i, out_coding, state_ptr)
+ int i;
+ int out_coding;
+ struct g72x_state *state_ptr;
+{
+ short sezi, sei, sez, se; /* ACCUM */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dq;
+ short dqsez;
+
+ i &= 0x0f; /* mask to get proper bits */
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ y = step_size(state_ptr); /* dynamic quantizer step size */
+
+ dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
+
+ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
+
+ dqsez = sr - se + sez; /* pole prediction diff. */
+
+ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+ switch (out_coding) {
+ case AUDIO_ENCODING_ALAW:
+ return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
+ case AUDIO_ENCODING_ULAW:
+ return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721));
+ case AUDIO_ENCODING_LINEAR:
+ return (sr << 2); /* sr was 14-bit dynamic range */
+ default:
+ return (-1);
+ }
+}
--- /dev/null
+++ b/src/g723_24.c
@@ -1,0 +1,160 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g723_24.c
+ *
+ * Description:
+ *
+ * g723_24_encoder(), g723_24_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 24 Kbps
+ * ADPCM coding algorithm. Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which take advantage
+ * of workstation attributes, such as hardware 2's complement arithmetic.
+ *
+ */
+#include "st.h"
+#include "libst.h"
+#include "g72x.h"
+
+/*
+ * Maps G.723_24 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
+
+/* Maps G.723_24 code word to log of scale factor multiplier. */
+static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
+
+/*
+ * Maps G.723_24 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
+
+static short qtab_723_24[3] = {8, 218, 331};
+
+/*
+ * g723_24_encoder()
+ *
+ * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
+ * Returns -1 if invalid input coding value.
+ */
+int
+g723_24_encoder(sl, in_coding, state_ptr)
+ int sl;
+ int in_coding;
+ struct g72x_state *state_ptr;
+{
+ short sei, sezi, se, sez; /* ACCUM */
+ short d; /* SUBTA */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dqsez; /* ADDC */
+ short dq, i;
+
+ switch (in_coding) { /* linearize input sample to 14-bit PCM */
+ case AUDIO_ENCODING_ALAW:
+ sl = st_Alaw_to_linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_ULAW:
+ sl = st_ulaw_to_linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_LINEAR:
+ sl >>= 2; /* sl of 14-bit dynamic range */
+ break;
+ default:
+ return (-1);
+ }
+
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ d = sl - se; /* d = estimation diff. */
+
+ /* quantize prediction difference d */
+ y = step_size(state_ptr); /* quantizer step size */
+ i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */
+ dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
+
+ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
+
+ dqsez = sr + sez - se; /* pole prediction diff. */
+
+ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ return (i);
+}
+
+/*
+ * g723_24_decoder()
+ *
+ * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_24_decoder(i, out_coding, state_ptr)
+ int i;
+ int out_coding;
+ struct g72x_state *state_ptr;
+{
+ short sezi, sei, sez, se; /* ACCUM */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dq;
+ short dqsez;
+
+ i &= 0x07; /* mask to get proper bits */
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ y = step_size(state_ptr); /* adaptive quantizer step size */
+ dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
+
+ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
+
+ dqsez = sr - se + sez; /* pole prediction diff. */
+
+ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ switch (out_coding) {
+ case AUDIO_ENCODING_ALAW:
+ return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
+ case AUDIO_ENCODING_ULAW:
+ return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24));
+ case AUDIO_ENCODING_LINEAR:
+ return (sr << 2); /* sr was of 14-bit dynamic range */
+ default:
+ return (-1);
+ }
+}
--- /dev/null
+++ b/src/g723_40.c
@@ -1,0 +1,180 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g723_40.c
+ *
+ * Description:
+ *
+ * g723_40_encoder(), g723_40_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 40Kbps
+ * ADPCM coding algorithm. Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of workstation attributes, such as hardware 2's
+ * complement arithmetic.
+ *
+ * The deviation from the bit level specification (lookup tables),
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.723 Recommendation, the algorithm is broken
+ * down into modules. Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+#include "st.h"
+#include "libst.h"
+#include "g72x.h"
+
+/*
+ * Maps G.723_40 code word to ructeconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
+ 358, 395, 429, 459, 488, 514, 539, 566,
+ 566, 539, 514, 488, 459, 429, 395, 358,
+ 318, 274, 224, 169, 104, 28, -66, -2048};
+
+/* Maps G.723_40 code word to log of scale factor multiplier. */
+static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
+ 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
+ 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
+ 3200, 1856, 1312, 1280, 1248, 768, 448, 448};
+
+/*
+ * Maps G.723_40 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
+ 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
+ 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
+ 0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
+
+static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
+ 378, 413, 445, 475, 502, 528, 553};
+
+/*
+ * g723_40_encoder()
+ *
+ * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
+ * the resulting 5-bit CCITT G.723 40Kbps code.
+ * Returns -1 if the input coding value is invalid.
+ */
+int
+g723_40_encoder(sl, in_coding, state_ptr)
+ int sl;
+ int in_coding;
+ struct g72x_state *state_ptr;
+{
+ short sei, sezi, se, sez; /* ACCUM */
+ short d; /* SUBTA */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dqsez; /* ADDC */
+ short dq, i;
+
+ switch (in_coding) { /* linearize input sample to 14-bit PCM */
+ case AUDIO_ENCODING_ALAW:
+ sl = st_Alaw_to_linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_ULAW:
+ sl = st_ulaw_to_linear(sl) >> 2;
+ break;
+ case AUDIO_ENCODING_LINEAR:
+ sl >>= 2; /* sl of 14-bit dynamic range */
+ break;
+ default:
+ return (-1);
+ }
+
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ d = sl - se; /* d = estimation difference */
+
+ /* quantize prediction difference */
+ y = step_size(state_ptr); /* adaptive quantizer step size */
+ i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */
+
+ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
+
+ sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
+
+ dqsez = sr + sez - se; /* dqsez = pole prediction diff. */
+
+ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ return (i);
+}
+
+/*
+ * g723_40_decoder()
+ *
+ * Decodes a 5-bit CCITT G.723 40Kbps code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_40_decoder( i, out_coding, state_ptr)
+ int i;
+ int out_coding;
+ struct g72x_state *state_ptr;
+{
+ short sezi, sei, sez, se; /* ACCUM */
+ short y; /* MIX */
+ short sr; /* ADDB */
+ short dq;
+ short dqsez;
+
+ i &= 0x1f; /* mask to get proper bits */
+ sezi = predictor_zero(state_ptr);
+ sez = sezi >> 1;
+ sei = sezi + predictor_pole(state_ptr);
+ se = sei >> 1; /* se = estimated signal */
+
+ y = step_size(state_ptr); /* adaptive quantizer step size */
+ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
+
+ sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
+
+ dqsez = sr - se + sez; /* pole prediction diff. */
+
+ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+ switch (out_coding) {
+ case AUDIO_ENCODING_ALAW:
+ return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
+ case AUDIO_ENCODING_ULAW:
+ return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40));
+ case AUDIO_ENCODING_LINEAR:
+ return (sr << 2); /* sr was of 14-bit dynamic range */
+ default:
+ return (-1);
+ }
+}
--- /dev/null
+++ b/src/g72x.c
@@ -1,0 +1,566 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g72x.c
+ *
+ * Common routines for G.721 and G.723 conversions.
+ */
+
+#include "st.h"
+#include "libst.h"
+#include "g72x.h"
+
+static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
+ 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};
+
+/*
+ * quan()
+ *
+ * quantizes the input val against the table of size short integers.
+ * It returns i if table[i - 1] <= val < table[i].
+ *
+ * Using linear search for simple coding.
+ */
+static int
+quan(val,table,size)
+ int val;
+ short *table;
+ int size;
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (val < *table++)
+ break;
+ return (i);
+}
+
+/*
+ * fmult()
+ *
+ * returns the integer product of the 14-bit integer "an" and
+ * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
+ */
+static int
+fmult(an, srn)
+ int an;
+ int srn;
+{
+ short anmag, anexp, anmant;
+ short wanexp, wanmant;
+ short retval;
+
+ anmag = (an > 0) ? an : ((-an) & 0x1FFF);
+ anexp = quan(anmag, power2, 15) - 6;
+ anmant = (anmag == 0) ? 32 :
+ (anexp >= 0) ? anmag >> anexp : anmag << -anexp;
+ wanexp = anexp + ((srn >> 6) & 0xF) - 13;
+
+ wanmant = (anmant * (srn & 077) + 0x30) >> 4;
+ retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
+ (wanmant >> -wanexp);
+
+ return (((an ^ srn) < 0) ? -retval : retval);
+}
+
+/*
+ * g72x_init_state()
+ *
+ * This routine initializes and/or resets the g72x_state structure
+ * pointed to by 'state_ptr'.
+ * All the initial state values are specified in the CCITT G.721 document.
+ */
+void
+g72x_init_state(state_ptr)
+ struct g72x_state *state_ptr;
+{
+ int cnta;
+
+ state_ptr->yl = 34816L;
+ state_ptr->yu = 544;
+ state_ptr->dms = 0;
+ state_ptr->dml = 0;
+ state_ptr->ap = 0;
+ for (cnta = 0; cnta < 2; cnta++) {
+ state_ptr->a[cnta] = 0;
+ state_ptr->pk[cnta] = 0;
+ state_ptr->sr[cnta] = 32;
+ }
+ for (cnta = 0; cnta < 6; cnta++) {
+ state_ptr->b[cnta] = 0;
+ state_ptr->dq[cnta] = 32;
+ }
+ state_ptr->td = 0;
+}
+
+/*
+ * predictor_zero()
+ *
+ * computes the estimated signal from 6-zero predictor.
+ *
+ */
+int
+predictor_zero(state_ptr)
+ struct g72x_state *state_ptr;
+{
+ int i;
+ int sezi;
+
+ sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
+ for (i = 1; i < 6; i++) /* ACCUM */
+ sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
+ return (sezi);
+}
+/*
+ * predictor_pole()
+ *
+ * computes the estimated signal from 2-pole predictor.
+ *
+ */
+int
+predictor_pole(state_ptr)
+ struct g72x_state *state_ptr;
+{
+ return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
+ fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
+}
+/*
+ * step_size()
+ *
+ * computes the quantization step size of the adaptive quantizer.
+ *
+ */
+int
+step_size(state_ptr)
+ struct g72x_state *state_ptr;
+{
+ int y;
+ int dif;
+ int al;
+
+ if (state_ptr->ap >= 256)
+ return (state_ptr->yu);
+ else {
+ y = state_ptr->yl >> 6;
+ dif = state_ptr->yu - y;
+ al = state_ptr->ap >> 2;
+ if (dif > 0)
+ y += (dif * al) >> 6;
+ else if (dif < 0)
+ y += (dif * al + 0x3F) >> 6;
+ return (y);
+ }
+}
+
+/*
+ * quantize()
+ *
+ * Given a raw sample, 'd', of the difference signal and a
+ * quantization step size scale factor, 'y', this routine returns the
+ * ADPCM codeword to which that sample gets quantized. The step
+ * size scale factor division operation is done in the log base 2 domain
+ * as a subtraction.
+ */
+int
+quantize(d, y,table,size)
+ int d; /* Raw difference signal sample */
+ int y; /* Step size multiplier */
+ short *table; /* quantization table */
+ int size; /* table size of short integers */
+{
+ short dqm; /* Magnitude of 'd' */
+ short exp; /* Integer part of base 2 log of 'd' */
+ short mant; /* Fractional part of base 2 log */
+ short dl; /* Log of magnitude of 'd' */
+ short dln; /* Step size scale factor normalized log */
+ int i;
+
+ /*
+ * LOG
+ *
+ * Compute base 2 log of 'd', and store in 'dl'.
+ */
+ dqm = abs(d);
+ exp = quan(dqm >> 1, power2, 15);
+ mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */
+ dl = (exp << 7) + mant;
+
+ /*
+ * SUBTB
+ *
+ * "Divide" by step size multiplier.
+ */
+ dln = dl - (y >> 2);
+
+ /*
+ * QUAN
+ *
+ * Obtain codword i for 'd'.
+ */
+ i = quan(dln, table, size);
+ if (d < 0) /* take 1's complement of i */
+ return ((size << 1) + 1 - i);
+ else if (i == 0) /* take 1's complement of 0 */
+ return ((size << 1) + 1); /* new in 1988 */
+ else
+ return (i);
+}
+/*
+ * reconstruct()
+ *
+ * Returns reconstructed difference signal 'dq' obtained from
+ * codeword 'i' and quantization step size scale factor 'y'.
+ * Multiplication is performed in log base 2 domain as addition.
+ */
+int
+reconstruct(sign, dqln, y)
+ int sign; /* 0 for non-negative value */
+ int dqln; /* G.72x codeword */
+ int y; /* Step size multiplier */
+{
+ short dql; /* Log of 'dq' magnitude */
+ short dex; /* Integer part of log */
+ short dqt;
+ short dq; /* Reconstructed difference signal sample */
+
+ dql = dqln + (y >> 2); /* ADDA */
+
+ if (dql < 0) {
+ return ((sign) ? -0x8000 : 0);
+ } else { /* ANTILOG */
+ dex = (dql >> 7) & 15;
+ dqt = 128 + (dql & 127);
+ dq = (dqt << 7) >> (14 - dex);
+ return ((sign) ? (dq - 0x8000) : dq);
+ }
+}
+
+
+/*
+ * update()
+ *
+ * updates the state variables for each output code
+ */
+void
+update(code_size, y, wi, fi, dq, sr, dqsez, state_ptr)
+ int code_size; /* distinguish 723_40 with others */
+ int y; /* quantizer step size */
+ int wi; /* scale factor multiplier */
+ int fi; /* for long/short term energies */
+ int dq; /* quantized prediction difference */
+ int sr; /* reconstructed signal */
+ int dqsez; /* difference from 2-pole predictor */
+ struct g72x_state *state_ptr; /* coder state pointer */
+{
+ int cnt;
+ short mag, exp; /* Adaptive predictor, FLOAT A */
+ short a2p=0; /* LIMC */
+ short a1ul; /* UPA1 */
+ short pks1; /* UPA2 */
+ short fa1;
+ char tr; /* tone/transition detector */
+ short ylint, thr2, dqthr;
+ short ylfrac, thr1;
+ short pk0;
+
+ pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */
+
+ mag = dq & 0x7FFF; /* prediction difference magnitude */
+ /* TRANS */
+ ylint = state_ptr->yl >> 15; /* exponent part of yl */
+ ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */
+ thr1 = (32 + ylfrac) << ylint; /* threshold */
+ thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */
+ dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */
+ if (state_ptr->td == 0) /* signal supposed voice */
+ tr = 0;
+ else if (mag <= dqthr) /* supposed data, but small mag */
+ tr = 0; /* treated as voice */
+ else /* signal is data (modem) */
+ tr = 1;
+
+ /*
+ * Quantizer scale factor adaptation.
+ */
+
+ /* FUNCTW & FILTD & DELAY */
+ /* update non-steady state step size multiplier */
+ state_ptr->yu = y + ((wi - y) >> 5);
+
+ /* LIMB */
+ if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */
+ state_ptr->yu = 544;
+ else if (state_ptr->yu > 5120)
+ state_ptr->yu = 5120;
+
+ /* FILTE & DELAY */
+ /* update steady state step size multiplier */
+ state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
+
+ /*
+ * Adaptive predictor coefficients.
+ */
+ if (tr == 1) { /* reset a's and b's for modem signal */
+ state_ptr->a[0] = 0;
+ state_ptr->a[1] = 0;
+ state_ptr->b[0] = 0;
+ state_ptr->b[1] = 0;
+ state_ptr->b[2] = 0;
+ state_ptr->b[3] = 0;
+ state_ptr->b[4] = 0;
+ state_ptr->b[5] = 0;
+ } else { /* update a's and b's */
+ pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */
+
+ /* update predictor pole a[1] */
+ a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
+ if (dqsez != 0) {
+ fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
+ if (fa1 < -8191) /* a2p = function of fa1 */
+ a2p -= 0x100;
+ else if (fa1 > 8191)
+ a2p += 0xFF;
+ else
+ a2p += fa1 >> 5;
+
+ if (pk0 ^ state_ptr->pk[1])
+ /* LIMC */
+ if (a2p <= -12160)
+ a2p = -12288;
+ else if (a2p >= 12416)
+ a2p = 12288;
+ else
+ a2p -= 0x80;
+ else if (a2p <= -12416)
+ a2p = -12288;
+ else if (a2p >= 12160)
+ a2p = 12288;
+ else
+ a2p += 0x80;
+ }
+
+ /* Possible bug: a2p not initialized if dqsez == 0) */
+ /* TRIGB & DELAY */
+ state_ptr->a[1] = a2p;
+
+ /* UPA1 */
+ /* update predictor pole a[0] */
+ state_ptr->a[0] -= state_ptr->a[0] >> 8;
+ if (dqsez != 0)
+ if (pks1 == 0)
+ state_ptr->a[0] += 192;
+ else
+ state_ptr->a[0] -= 192;
+
+ /* LIMD */
+ a1ul = 15360 - a2p;
+ if (state_ptr->a[0] < -a1ul)
+ state_ptr->a[0] = -a1ul;
+ else if (state_ptr->a[0] > a1ul)
+ state_ptr->a[0] = a1ul;
+
+ /* UPB : update predictor zeros b[6] */
+ for (cnt = 0; cnt < 6; cnt++) {
+ if (code_size == 5) /* for 40Kbps G.723 */
+ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
+ else /* for G.721 and 24Kbps G.723 */
+ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
+ if (dq & 0x7FFF) { /* XOR */
+ if ((dq ^ state_ptr->dq[cnt]) >= 0)
+ state_ptr->b[cnt] += 128;
+ else
+ state_ptr->b[cnt] -= 128;
+ }
+ }
+ }
+
+ for (cnt = 5; cnt > 0; cnt--)
+ state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
+ /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
+ if (mag == 0) {
+ state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
+ } else {
+ exp = quan(mag, power2, 15);
+ state_ptr->dq[0] = (dq >= 0) ?
+ (exp << 6) + ((mag << 6) >> exp) :
+ (exp << 6) + ((mag << 6) >> exp) - 0x400;
+ }
+
+ state_ptr->sr[1] = state_ptr->sr[0];
+ /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
+ if (sr == 0) {
+ state_ptr->sr[0] = 0x20;
+ } else if (sr > 0) {
+ exp = quan(sr, power2, 15);
+ state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp);
+ } else if (sr > -32768L) {
+ mag = -sr;
+ exp = quan(mag, power2, 15);
+ state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400;
+ } else
+ state_ptr->sr[0] = 0xFC20;
+
+ /* DELAY A */
+ state_ptr->pk[1] = state_ptr->pk[0];
+ state_ptr->pk[0] = pk0;
+
+ /* TONE */
+ if (tr == 1) /* this sample has been treated as data */
+ state_ptr->td = 0; /* next one will be treated as voice */
+ else if (a2p < -11776) /* small sample-to-sample correlation */
+ state_ptr->td = 1; /* signal may be data */
+ else /* signal is voice */
+ state_ptr->td = 0;
+
+ /*
+ * Adaptation speed control.
+ */
+ state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */
+ state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */
+
+ if (tr == 1)
+ state_ptr->ap = 256;
+ else if (y < 1536) /* SUBTC */
+ state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+ else if (state_ptr->td == 1)
+ state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+ else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
+ (state_ptr->dml >> 3))
+ state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+ else
+ state_ptr->ap += (-state_ptr->ap) >> 4;
+}
+
+/*
+ * tandem_adjust(sr, se, y, i, sign)
+ *
+ * At the end of ADPCM decoding, it simulates an encoder which may be receiving
+ * the output of this decoder as a tandem process. If the output of the
+ * simulated encoder differs from the input to this decoder, the decoder output
+ * is adjusted by one level of A-law or u-law codes.
+ *
+ * Input:
+ * sr decoder output linear PCM sample,
+ * se predictor estimate sample,
+ * y quantizer step size,
+ * i decoder input code,
+ * sign sign bit of code i
+ *
+ * Return:
+ * adjusted A-law or u-law compressed sample.
+ */
+int
+tandem_adjust_alaw(sr, se, y, i, sign, qtab)
+ int sr; /* decoder output linear PCM sample */
+ int se; /* predictor estimate sample */
+ int y; /* quantizer step size */
+ int i; /* decoder input code */
+ int sign;
+ short *qtab;
+{
+ unsigned char sp; /* A-law compressed 8-bit code */
+ short dx; /* prediction error */
+ char id; /* quantized prediction error */
+ int sd; /* adjusted A-law decoded sample value */
+ int im; /* biased magnitude of i */
+ int imx; /* biased magnitude of id */
+
+ if (sr <= -32768L)
+ sr = -1;
+ sp = st_linear_to_Alaw((sr >> 1) << 3); /* short to A-law compression */
+ dx = (st_Alaw_to_linear(sp) >> 2) - se; /* 16-bit prediction error */
+ id = quantize(dx, y, qtab, sign - 1);
+
+ if (id == i) { /* no adjustment on sp */
+ return (sp);
+ } else { /* sp adjustment needed */
+ /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
+ im = i ^ sign; /* 2's complement to biased unsigned */
+ imx = id ^ sign;
+
+ if (imx > im) { /* sp adjusted to next lower value */
+ if (sp & 0x80) {
+ sd = (sp == 0xD5) ? 0x55 :
+ ((sp ^ 0x55) - 1) ^ 0x55;
+ } else {
+ sd = (sp == 0x2A) ? 0x2A :
+ ((sp ^ 0x55) + 1) ^ 0x55;
+ }
+ } else { /* sp adjusted to next higher value */
+ if (sp & 0x80)
+ sd = (sp == 0xAA) ? 0xAA :
+ ((sp ^ 0x55) + 1) ^ 0x55;
+ else
+ sd = (sp == 0x55) ? 0xD5 :
+ ((sp ^ 0x55) - 1) ^ 0x55;
+ }
+ return (sd);
+ }
+}
+
+int
+tandem_adjust_ulaw(sr, se, y, i, sign, qtab)
+ int sr; /* decoder output linear PCM sample */
+ int se; /* predictor estimate sample */
+ int y; /* quantizer step size */
+ int i; /* decoder input code */
+ int sign;
+ short *qtab;
+{
+ unsigned char sp; /* u-law compressed 8-bit code */
+ short dx; /* prediction error */
+ char id; /* quantized prediction error */
+ int sd; /* adjusted u-law decoded sample value */
+ int im; /* biased magnitude of i */
+ int imx; /* biased magnitude of id */
+
+ if (sr <= -32768L)
+ sr = 0;
+ sp = st_linear_to_ulaw(sr << 2); /* short to u-law compression */
+ dx = (st_ulaw_to_linear(sp) >> 2) - se; /* 16-bit prediction error */
+ id = quantize(dx, y, qtab, sign - 1);
+ if (id == i) {
+ return (sp);
+ } else {
+ /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
+ im = i ^ sign; /* 2's complement to biased unsigned */
+ imx = id ^ sign;
+ if (imx > im) { /* sp adjusted to next lower value */
+ if (sp & 0x80)
+ sd = (sp == 0xFF) ? 0x7E : sp + 1;
+ else
+ sd = (sp == 0) ? 0 : sp - 1;
+
+ } else { /* sp adjusted to next higher value */
+ if (sp & 0x80)
+ sd = (sp == 0x80) ? 0x80 : sp - 1;
+ else
+ sd = (sp == 0x7F) ? 0xFE : sp + 1;
+ }
+ return (sd);
+ }
+}
--- /dev/null
+++ b/src/g72x.h
@@ -1,0 +1,133 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use. Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * g72x.h
+ *
+ * Header file for CCITT conversion routines.
+ *
+ */
+#ifndef _G72X_H
+#define _G72X_H
+
+#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */
+#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */
+#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */
+
+/*
+ * The following is the definition of the state structure
+ * used by the G.721/G.723 encoder and decoder to preserve their internal
+ * state between successive calls. The meanings of the majority
+ * of the state structure fields are explained in detail in the
+ * CCITT Recommendation G.721. The field names are essentially indentical
+ * to variable names in the bit level description of the coding algorithm
+ * included in this Recommendation.
+ */
+struct g72x_state {
+ LONG yl; /* Locked or steady state step size multiplier. */
+ short yu; /* Unlocked or non-steady state step size multiplier. */
+ short dms; /* Short term energy estimate. */
+ short dml; /* Long term energy estimate. */
+ short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */
+
+ short a[2]; /* Coefficients of pole portion of prediction filter. */
+ short b[6]; /* Coefficients of zero portion of prediction filter. */
+ short pk[2]; /*
+ * Signs of previous two samples of a partially
+ * reconstructed signal.
+ */
+ short dq[6]; /*
+ * Previous 6 samples of the quantized difference
+ * signal represented in an internal floating point
+ * format.
+ */
+ short sr[2]; /*
+ * Previous 2 samples of the quantized difference
+ * signal represented in an internal floating point
+ * format.
+ */
+ char td; /* delayed tone detect, new in 1988 version */
+};
+
+/* External function definitions. */
+
+extern void g72x_init_state(P1(struct g72x_state *));
+extern int g721_encoder(P3(
+ int sample,
+ int in_coding,
+ struct g72x_state *state_ptr));
+extern int g721_decoder(P3(
+ int code,
+ int out_coding,
+ struct g72x_state *state_ptr));
+extern int g723_24_encoder(P3(
+ int sample,
+ int in_coding,
+ struct g72x_state *state_ptr));
+extern int g723_24_decoder(P3(
+ int code,
+ int out_coding,
+ struct g72x_state *state_ptr));
+extern int g723_40_encoder(P3(
+ int sample,
+ int in_coding,
+ struct g72x_state *state_ptr));
+extern int g723_40_decoder(P3(
+ int code,
+ int out_coding,
+ struct g72x_state *state_ptr));
+
+int predictor_zero(P1(struct g72x_state *state_ptr));
+int predictor_pole(P1(struct g72x_state *state_ptr));
+int step_size(P1(struct g72x_state *state_ptr));
+int quantize(P4(int d,
+ int y,
+ short *table,
+ int size));
+int reconstruct(P3(int sign,
+ int dqln,
+ int y));
+void update(P8(int code_size,
+ int y,
+ int wi,
+ int fi,
+ int dq,
+ int sr,
+ int dqsez,
+ struct g72x_state *state_ptr));
+int tandem_adjust_alaw(P6(int sr,
+ int se,
+ int y,
+ int i,
+ int sign,
+ short *qtab));
+int tandem_adjust_ulaw(P6(int sr,
+ int se,
+ int y,
+ int i,
+ int sign,
+ short *qtab));
+#endif /* !_G72X_H */
--- /dev/null
+++ b/src/getopt.c
@@ -1,0 +1,114 @@
+/*
+Date: Tue, 25 Dec 84 19:20:50 EST
+From: Keith Bostic <harvard!seismo!keith>
+To: genrad!sources
+Subject: public domain getopt(3)
+
+There have recently been several requests for a public
+domain version of getopt(3), recently. Thought this
+might be worth reposting.
+
+ Keith Bostic
+ ARPA: keith@seismo
+ UUCP: seismo!keith
+
+======================================================================
+In April of this year, Henry Spencer (utzoo!henry) released a public
+domain version of getopt (USG, getopt(3)). Well, I've been trying to
+port some USG dependent software and it didn't seem to work. The problem
+ended up being that the USG version of getopt has some external variables
+that aren't mentioned in the documentation. Anyway, to fix these problems,
+I rewrote the public version of getopt. It has the following advantages:
+
+ -- it includes those "unknown" variables
+ -- it's smaller/faster 'cause it doesn't use the formatted
+ output conversion routines in section 3 of the UNIX manual.
+ -- the error messages are the same as S5's.
+ -- it has the same side-effects that S5's has.
+ -- the posted bug on how the error messages are flushed has been
+ implemented. (posting by Tony Hansen; pegasus!hansen)
+
+I won't post the man pages since Henry already did; a special note,
+it's not documented in the S5 manual that the options ':' and '?' are
+illegal. It should be obvious, but I thought I'd mention it...
+This software was derived from binaries of S5 and the S5 man page, and is
+(I think?) totally (I'm pretty sure?) compatible with S5 and backward
+compatible to Henry's version.
+
+ Keith Bostic
+ ARPA: keith@seismo
+ UUCP: seismo!keith
+
+*UNIX is a trademark of Bell Laboratories
+
+.. cut along the dotted line .........................................
+*/
+
+int ansi_c_needs_something_here_too;
+
+#ifdef NEED_GETOPT
+#include <stdio.h>
+
+#include <string.h>
+
+#include "st.h"
+
+/*
+ * get option letter from argument vector
+ */
+int optind = 1, /* index into parent argv vector */
+ optopt; /* character checked for validity */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define EMSG ""
+#define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \
+ fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
+
+int getopt(nargc,nargv,ostr)
+int nargc;
+char **nargv,
+ *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ static char *lastostr = (char *) 0;
+ register char *oli; /* option letter list index */
+
+ /* LANCE PATCH: dynamic reinitialization */
+ if (ostr != lastostr) {
+ lastostr = ostr;
+ place = EMSG;
+ }
+ if(!*place) { /* update scanning pointer */
+ if((optind >= nargc) || (*(place = nargv[optind]) != '-')
+ || ! *++place) {
+ place = EMSG;
+ return(EOF);
+ }
+ if (*place == '-') { /* found "--" */
+ ++optind;
+ return(EOF);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
+ if(!*place) ++optind;
+ tell(": illegal option -- ");
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place) ++optind;
+ }
+ else { /* need an argument */
+ if (*place) optarg = place; /* no white space */
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ tell(": option requires an argument -- ");
+ }
+ else optarg = nargv[optind]; /* white space */
+ place = EMSG;
+ ++optind;
+ }
+ return(optopt); /* dump back option letter */
+}
+
+#endif
--- /dev/null
+++ b/src/gsm.c
@@ -1,0 +1,162 @@
+#if defined(HAS_GSM)
+/*
+ * Copyright 1991, 1992, 1993 Guido van Rossum And Sundry Contributors.
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * GSM 06.10 courtesy Communications and Operating Systems Research Group,
+ * Technische Universitaet Berlin
+ *
+ * More information on this format can be obtained from
+ * http://www.cs.tu-berlin.de/~jutta/toast.html
+ *
+ * Source is available from ftp://ftp.cs.tu-berlin.de/pub/local/kbs/tubmik/gsm
+ *
+ * Written 26 Jan 1995 by Andrew Pam
+ * Portions Copyright (c) 1995 Serious Cybernetics
+ *
+ * July 19, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Added GSM support to SOX from patches floating around with the help
+ * of Dima Barsky (ess2db@ee.surrey.ac.uk).
+ */
+
+#include "st.h"
+#include "gsm.h"
+
+/* Private data */
+struct gsmpriv {
+ gsm handle;
+ gsm_signal sample[160];
+ int index;
+};
+
+void
+gsmstartread(ft)
+ft_t ft;
+{
+ struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+ /* Sanity check */
+ if (sizeof(struct gsmpriv) > PRIVSIZE)
+ fail(
+"struct gsmpriv is too big (%d); change PRIVSIZE in st.h and recompile sox",
+ sizeof(struct gsmpriv));
+
+ ft->info.style = GSM;
+ ft->info.size = BYTE;
+ if (!ft->info.rate)
+ ft->info.rate = 8000;
+ p->handle = gsm_create();
+ if (!p->handle)
+ fail("unable to create GSM stream");
+ p->index = 0;
+}
+
+void
+gsmstartwrite(ft)
+ft_t ft;
+{
+ struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+ ft->info.style = GSM;
+ ft->info.size = BYTE;
+ if (!ft->info.rate)
+ ft->info.rate = 8000;
+ p->handle = gsm_create();
+ if (!p->handle)
+ fail("unable to create GSM stream");
+ p->index = 0;
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG
+gsmread(ft, buf, samp)
+ft_t ft;
+long *buf, samp;
+{
+ int bytes;
+ int done = 0;
+ gsm_frame frame;
+ struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+ while (p->index && (p->index < 160) && (done < samp))
+ buf[done++] = LEFT(p->sample[p->index++], 16);
+
+ while (done < samp)
+ {
+ p->index = 0;
+ bytes = fread( frame, 1, sizeof(frame), ft->fp );
+ if (bytes <= 0)
+ return done;
+ if (bytes < sizeof(frame))
+ fail("invalid frame size: %d bytes", bytes);
+ if (gsm_decode(p->handle, frame, p->sample) < 0)
+ fail("error during GSM decode");
+ while ((p->index < 160) && (done < samp))
+ buf[done++] = LEFT(p->sample[p->index++], 16);
+ }
+
+ return done;
+}
+
+int
+gsmwrite(ft, buf, samp)
+ft_t ft;
+long *buf, samp;
+{
+ int done = 0;
+ gsm_frame frame;
+ struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+ while (done < samp)
+ {
+ while ((p->index < 160) && (done < samp))
+ p->sample[p->index++] = RIGHT(buf[done++], 16);
+ if (p->index < 160)
+ return done;
+ gsm_encode(p->handle, p->sample, frame);
+ if (fwrite(frame, 1, sizeof(frame), ft->fp) != sizeof(frame))
+ fail("write error");
+ p->index = 0;
+ }
+
+ return done;
+}
+
+void
+gsmstopread(ft)
+ft_t ft;
+{
+ struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+ gsm_destroy(p->handle);
+}
+
+void
+gsmstopwrite(ft)
+ft_t ft;
+{
+ gsm_frame frame;
+ struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+ if (p->index)
+ {
+ while (p->index < 160)
+ p->sample[p->index++] = 0;
+ gsm_encode(p->handle, p->sample, frame);
+ if (fwrite(frame, 1, sizeof(frame), ft->fp) != sizeof(frame))
+ fail("write error");
+ }
+ gsm_destroy(p->handle);
+}
+#endif /* HAS_GSM */
--- /dev/null
+++ b/src/handlers.c
@@ -1,0 +1,624 @@
+/*
+ * Originally created: July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#include "st.h"
+
+/*
+ * Sound Tools file format and effect tables.
+ */
+
+/* File format handlers. */
+
+char *aiffnames[] = {
+ "aiff",
+ "aif",
+ (char *) 0
+};
+extern void aiffstartread();
+extern LONG aiffread();
+extern void aiffstopread();
+extern void aiffstartwrite();
+extern void aiffwrite();
+extern void aiffstopwrite();
+
+char *alnames[] = {
+ "al",
+ (char *) 0
+};
+extern void alstartread();
+extern void alstartwrite();
+
+char *aunames[] = {
+ "au",
+#ifdef NeXT
+ "snd",
+#endif
+ (char *) 0
+};
+extern void austartread();
+extern LONG auread();
+extern void austartwrite();
+extern void auwrite();
+extern void austopwrite();
+
+char *autonames[] = {
+ "auto",
+ (char *) 0,
+};
+
+extern void autostartread();
+extern void autostartwrite();
+
+char *cdrnames[] = {
+ "cdr",
+ (char *) 0
+};
+extern void cdrstartread();
+extern LONG cdrread();
+extern void cdrstopread();
+extern void cdrstartwrite();
+extern void cdrwrite();
+extern void cdrstopwrite();
+
+char *cvsdnames[] = {
+ "cvs",
+ "cvsd",
+ (char *)0
+};
+extern void cvsdstartread();
+extern LONG cvsdread();
+extern void cvsdstopread();
+extern void cvsdstartwrite();
+extern void cvsdwrite();
+extern void cvsdstopwrite();
+
+char *datnames[] = {
+ "dat",
+ (char *) 0
+};
+extern void datstartread();
+extern LONG datread();
+extern void datstartwrite();
+extern void datwrite();
+
+char *dvmsnames[] = {
+ "vms",
+ "dvms",
+ (char *)0
+};
+extern void dvmsstartread();
+extern void dvmsstartwrite();
+extern void dvmsstopwrite();
+
+#ifdef HAS_GSM
+char *gsmnames[] = {
+ "gsm",
+ (char *) 0
+};
+
+extern void gsmstartread();
+extern LONG gsmread();
+extern void gsmstopread();
+extern void gsmstartwrite();
+extern void gsmwrite();
+extern void gsmstopwrite();
+#endif
+
+char *hcomnames[] = {
+ "hcom",
+ (char *) 0
+};
+extern void hcomstartread();
+extern LONG hcomread();
+extern void hcomstopread();
+extern void hcomstartwrite();
+extern void hcomwrite();
+extern void hcomstopwrite();
+
+char *maudnames[] = {
+ "maud",
+ (char *) 0,
+};
+extern void maudstartread();
+extern LONG maudread();
+extern void maudstopread();
+extern void maudwrite();
+extern void maudstartwrite();
+extern void maudstopwrite();
+
+#if defined(OSS_PLAYER)
+char *ossdspnames[] = {
+ "ossdsp",
+ (char *) 0
+};
+extern void ossdspstartread();
+extern LONG ossdspread();
+extern void ossdspstopread();
+extern void ossdspstartwrite();
+extern void ossdspwrite();
+extern void ossdspstopwrite();
+#endif
+
+char *rawnames[] = {
+ "raw",
+ (char *) 0
+};
+extern void rawstartread();
+extern LONG rawread();
+extern void rawstartwrite();
+extern void rawwrite();
+extern void rawstopwrite();
+
+#if defined(BLASTER) || defined(SBLAST)
+char *sbdspnames[] = {
+ "sbdsp",
+ (char *) 0
+};
+extern void sbdspstartread();
+extern LONG sbdspread();
+extern void sbdspstopread();
+extern void sbdspstartwrite();
+extern void sbdspwrite();
+extern void sbdspstopwrite();
+#endif
+
+char *sbnames[] = {
+ "sb",
+ (char *) 0
+};
+extern void sbstartread();
+extern void sbstartwrite();
+
+char *sfnames[] = {
+ "sf",
+ (char *) 0
+};
+extern void sfstartread();
+extern void sfstartwrite();
+
+char *smpnames[] = {
+ "smp",
+ (char *) 0,
+};
+
+extern void smpstartread();
+extern LONG smpread();
+extern void smpwrite();
+extern void smpstartwrite();
+extern void smpstopwrite();
+
+char *sndrnames[] = {
+ "sndr",
+ (char *) 0
+};
+extern void sndrstartwrite();
+
+char *sndtnames[] = {
+ "sndt",
+#ifdef DOS
+ "snd",
+#endif
+ (char *) 0
+};
+extern void sndtstartread();
+extern void sndtstartwrite();
+extern void sndtwrite();
+extern void sndtstopwrite();
+
+#if defined(SUNAUDIO_PLAYER)
+char *sunnames[] = {
+ "sunau",
+ (char *) 0
+};
+extern void sunstartread();
+extern LONG sunread();
+extern void sunstopread();
+extern void sunstartwrite();
+extern void sunwrite();
+extern void sunstopwrite();
+#endif
+
+char *svxnames[] = {
+ "8svx",
+ (char *) 0
+};
+extern void svxstartread();
+extern LONG svxread();
+extern void svxstopread();
+extern void svxstartwrite();
+extern void svxwrite();
+extern void svxstopwrite();
+
+char *swnames[] = {
+ "sw",
+ (char *) 0
+};
+extern void swstartread();
+extern void swstartwrite();
+
+char *txwnames[] = {
+ "txw",
+ (char *)0
+};
+extern void txwstartread();
+extern LONG txwread();
+extern void txwstopread();
+extern void txwstartwrite();
+extern void txwwrite();
+extern void txwstopwrite();
+
+char *ubnames[] = {
+ "ub",
+ "sou",
+ "fssd",
+#ifdef MAC
+ "snd",
+#endif
+ (char *) 0
+};
+extern void ubstartread();
+extern void ubstartwrite();
+
+char *ulnames[] = {
+ "ul",
+ (char *) 0
+};
+extern void ulstartread();
+extern void ulstartwrite();
+
+char *uwnames[] = {
+ "uw",
+ (char *) 0
+};
+extern void uwstartread();
+extern void uwstartwrite();
+
+char *vocnames[] = {
+ "voc",
+ (char *) 0
+};
+extern void vocstartread();
+extern LONG vocread();
+extern void vocstopread();
+extern void vocstartwrite();
+extern void vocwrite();
+extern void vocstopwrite();
+
+char *wavnames[] = {
+ "wav",
+ (char *) 0
+};
+extern void wavstartread();
+extern LONG wavread();
+extern void wavstartwrite();
+extern void wavwrite();
+extern void wavstopwrite();
+
+char *wvenames[] = {
+ "wve",
+ (char *) 0
+};
+extern void wvestartread();
+extern LONG wveread();
+extern void wvestartwrite();
+extern void wvewrite();
+extern void wvestopwrite();
+
+extern void nothing();
+extern LONG nothing_success();
+
+EXPORT format_t formats[] = {
+ {aiffnames, FILE_STEREO,
+ aiffstartread, aiffread, aiffstopread, /* SGI/Apple AIFF */
+ aiffstartwrite, aiffwrite, aiffstopwrite},
+ {alnames, FILE_STEREO,
+ alstartread, rawread, nothing, /* a-law byte raw */
+ alstartwrite, rawwrite, nothing},
+ {aunames, FILE_STEREO,
+ austartread, auread, nothing, /* SPARC .AU w/header */
+ austartwrite, auwrite, austopwrite},
+ {autonames, FILE_STEREO,
+ autostartread, nothing_success, nothing,/* Guess from header */
+ autostartwrite, nothing, nothing}, /* patched run time */
+ {cdrnames, FILE_STEREO,
+ cdrstartread, cdrread, cdrstopread, /* CD-R format */
+ cdrstartwrite, cdrwrite, cdrstopwrite},
+ {cvsdnames, 0,
+ cvsdstartread, cvsdread, cvsdstopread, /* Cont. Variable */
+ cvsdstartwrite, cvsdwrite, cvsdstopwrite}, /* Slope Delta */
+ {datnames, 0,
+ datstartread, datread, nothing, /* Text data samples */
+ datstartwrite, datwrite, nothing},
+ {dvmsnames, 0,
+ dvmsstartread, cvsdread, cvsdstopread, /* Cont. Variable */
+ dvmsstartwrite, cvsdwrite, dvmsstopwrite}, /* Slope Delta */
+#ifdef HAS_GSM
+ {gsmnames, 0,
+ gsmstartread, gsmread, gsmstopread, /* GSM 06.10 */
+ gsmstartwrite, gsmwrite, gsmstopwrite},
+#endif
+ {hcomnames, 0,
+ hcomstartread, hcomread, hcomstopread, /* Mac FSSD/HCOM */
+ hcomstartwrite, hcomwrite, hcomstopwrite},
+ {maudnames, FILE_STEREO, /* Amiga MAUD */
+ maudstartread, maudread, maudstopread,
+ maudstartwrite, maudwrite, maudstopwrite},
+#if defined(OSS_PLAYER)
+ /* OSS player. */
+ {ossdspnames, FILE_STEREO,
+ ossdspstartread, ossdspread, ossdspstopread, /* /dev/dsp */
+ ossdspstartwrite, ossdspwrite, ossdspstopwrite},
+#endif
+ {rawnames, FILE_STEREO,
+ rawstartread, rawread, nothing, /* Raw format */
+ rawstartwrite, rawwrite, nothing},
+#if defined(BLASTER) || defined(SBLAST)
+ /* 386 Unix sound blaster player. */
+ {sbdspnames, FILE_STEREO,
+ sbdspstartread, sbdspread, sbdspstopread, /* /dev/sbdsp */
+ sbdspstartwrite, sbdspwrite, sbdspstopwrite},
+#endif
+ {sbnames, FILE_STEREO,
+ sbstartread, rawread, nothing, /* signed byte raw */
+ sbstartwrite, rawwrite, nothing},
+ {sfnames, FILE_STEREO,
+ sfstartread, rawread, nothing, /* IRCAM Sound File */
+ sfstartwrite, rawwrite, nothing}, /* Relies on raw */
+ {smpnames, FILE_STEREO | FILE_LOOPS,
+ smpstartread, smpread, nothing, /* SampleVision sound */
+ smpstartwrite, smpwrite, smpstopwrite}, /* Turtle Beach */
+ {sndrnames, FILE_STEREO,
+ sndtstartread, rawread, nothing, /* Sounder Sound File */
+ sndrstartwrite, rawwrite, nothing},
+ {sndtnames, FILE_STEREO,
+ sndtstartread, rawread, nothing, /* Sndtool Sound File */
+ sndtstartwrite, sndtwrite, sndtstopwrite},
+#if defined(SUNAUDIO_PLAYER)
+ /* Sun /dev/audio player. */
+ {sunnames, FILE_STEREO,
+ sunstartread, sunread, sunstopread, /* /dev/audio */
+ sunstartwrite, sunwrite, sunstopwrite},
+#endif
+ {svxnames, FILE_STEREO,
+ svxstartread, svxread, svxstopread, /* Amiga 8SVX */
+ svxstartwrite, svxwrite, svxstopwrite},
+ {swnames, FILE_STEREO,
+ swstartread, rawread, nothing, /* signed word raw */
+ swstartwrite, rawwrite, nothing},
+ {txwnames, 0,
+ txwstartread, txwread, txwstopread, /* Yamaha TX16W and */
+ txwstartwrite, txwwrite, txwstopwrite}, /* SY99 waves */
+ {ubnames, FILE_STEREO,
+ ubstartread, rawread, nothing, /* unsigned byte raw */
+ ubstartwrite, rawwrite, nothing},
+ {ulnames, FILE_STEREO,
+ ulstartread, rawread, nothing, /* u-law byte raw */
+ ulstartwrite, rawwrite, nothing},
+ {uwnames, FILE_STEREO,
+ uwstartread, rawread, nothing, /* unsigned word raw */
+ uwstartwrite, rawwrite, nothing},
+ {vocnames, FILE_STEREO,
+ vocstartread, vocread, vocstopread, /* Sound Blaster .VOC */
+ vocstartwrite, vocwrite, vocstopwrite},
+ {wavnames, FILE_STEREO,
+ wavstartread, wavread, nothing, /* Microsoft .wav */
+ wavstartwrite, wavwrite, wavstopwrite},
+ {wvenames, 0,
+ wvestartread, wveread, nothing, /* Psion .wve */
+ wvestartwrite, wvewrite, wvestopwrite},
+ {0, 0,
+ 0, 0, 0, 0, 0, 0}
+};
+
+/* Effects handlers. */
+
+extern void null_drain(); /* dummy drain routine */
+
+extern void avg_getopts();
+extern void avg_start();
+extern void avg_flow();
+extern void avg_stop();
+
+extern void band_getopts();
+extern void band_start();
+extern void band_flow();
+extern void band_stop();
+
+extern void chorus_getopts();
+extern void chorus_start();
+extern void chorus_flow();
+extern void chorus_drain();
+extern void chorus_stop();
+
+extern void copy_getopts();
+extern void copy_start();
+extern void copy_flow();
+extern void copy_stop();
+
+extern void cut_getopts();
+extern void cut_start();
+extern void cut_flow();
+extern void cut_stop();
+
+extern void deemph_getopts();
+extern void deemph_start();
+extern void deemph_flow();
+extern void deemph_stop();
+
+#ifdef USE_DYN
+extern void dyn_getopts();
+extern void dyn_start();
+extern void dyn_flow();
+extern void dyn_stop();
+#endif
+
+extern void echo_getopts();
+extern void echo_start();
+extern void echo_flow();
+extern void echo_drain();
+extern void echo_stop();
+
+extern void echos_getopts();
+extern void echos_start();
+extern void echos_flow();
+extern void echos_drain();
+extern void echos_stop();
+
+extern void flanger_getopts();
+extern void flanger_start();
+extern void flanger_flow();
+extern void flanger_drain();
+extern void flanger_stop();
+
+extern void highp_getopts();
+extern void highp_start();
+extern void highp_flow();
+extern void highp_stop();
+
+extern void lowp_getopts();
+extern void lowp_start();
+extern void lowp_flow();
+extern void lowp_stop();
+
+extern void map_getopts();
+extern void map_start();
+extern void map_flow();
+
+extern void mask_getopts();
+extern void mask_flow();
+
+extern void phaser_getopts();
+extern void phaser_start();
+extern void phaser_flow();
+extern void phaser_drain();
+extern void phaser_stop();
+
+extern void pick_getopts();
+extern void pick_start();
+extern void pick_flow();
+extern void pick_stop();
+
+extern void poly_getopts();
+extern void poly_start();
+extern void poly_flow();
+extern void poly_drain();
+extern void poly_stop();
+
+extern void split_getopts();
+extern void split_start();
+extern void split_flow();
+extern void split_stop();
+
+extern void stat_getopts();
+extern void stat_start();
+extern void stat_flow();
+extern void stat_stop();
+
+extern void rate_getopts();
+extern void rate_start();
+extern void rate_flow();
+extern void rate_stop();
+
+extern void resample_getopts();
+extern void resample_start();
+extern void resample_flow();
+extern void resample_drain();
+extern void resample_stop();
+
+extern void reverb_getopts();
+extern void reverb_start();
+extern void reverb_flow();
+extern void reverb_drain();
+extern void reverb_stop();
+
+extern void reverse_getopts();
+extern void reverse_start();
+extern void reverse_flow();
+extern void reverse_drain();
+extern void reverse_stop();
+
+extern void vibro_getopts();
+extern void vibro_start();
+extern void vibro_flow();
+extern void vibro_stop();
+
+/*
+ * EFF_CHAN means that the number of channels can change.
+ * EFF_RATE means that the sample rate can change.
+ * The first effect which can handle a data rate change, stereo->mono, etc.
+ * is the default handler for that problem.
+ *
+ * EFF_MCHAN just means that the effect is coded for multiple channels.
+ */
+
+EXPORT effect_t effects[] = {
+ {"null", 0, /* stand-in, never gets called */
+ nothing, nothing, nothing, null_drain, nothing},
+ {"avg", EFF_CHAN | EFF_MCHAN,
+ avg_getopts, avg_start, avg_flow, null_drain, avg_stop},
+ {"band", 0,
+ band_getopts, band_start, band_flow, null_drain, band_stop},
+ {"chorus", 0,
+ chorus_getopts, chorus_start, chorus_flow,
+ chorus_drain, chorus_stop},
+ {"copy", EFF_MCHAN,
+ copy_getopts, copy_start, copy_flow, null_drain, nothing},
+ {"cut", EFF_MCHAN,
+ cut_getopts, cut_start, cut_flow, null_drain, nothing},
+ {"deemph", EFF_MCHAN,
+ deemph_getopts, deemph_start, deemph_flow,
+ null_drain, deemph_stop},
+#ifdef USE_DYN
+ {"dyn", 0,
+ dyn_getopts, dyn_start, dyn_flow, null_drain, dyn_stop},
+#endif
+ {"echo", 0,
+ echo_getopts, echo_start, echo_flow, echo_drain, echo_stop},
+ {"echos", 0,
+ echos_getopts, echos_start, echos_flow,
+ echos_drain, echos_stop},
+ {"flanger", 0,
+ flanger_getopts, flanger_start, flanger_flow,
+ flanger_drain, flanger_stop},
+ {"highp", 0,
+ highp_getopts, highp_start, highp_flow, null_drain,highp_stop},
+ {"lowp", 0,
+ lowp_getopts, lowp_start, lowp_flow, null_drain, lowp_stop},
+ {"map", EFF_REPORT,
+ map_getopts, map_start, map_flow, null_drain, nothing},
+ {"mask", EFF_MCHAN,
+ mask_getopts, nothing, mask_flow, null_drain, nothing},
+ {"phaser", 0,
+ phaser_getopts, phaser_start, phaser_flow,
+ phaser_drain, phaser_stop},
+ {"pick", EFF_CHAN | EFF_MCHAN,
+ pick_getopts, pick_start, pick_flow, null_drain, pick_stop},
+ {"polyphase", EFF_RATE,
+ poly_getopts, poly_start, poly_flow,
+ poly_drain, poly_stop},
+ {"rate", EFF_RATE,
+ rate_getopts, rate_start, rate_flow, null_drain, nothing},
+ {"resample", EFF_RATE,
+ resample_getopts, resample_start, resample_flow,
+ resample_drain, resample_stop},
+ {"reverb", 0,
+ reverb_getopts, reverb_start, reverb_flow,
+ reverb_drain, reverb_stop},
+ {"reverse", 0,
+ reverse_getopts, reverse_start,
+ reverse_flow, reverse_drain, reverse_stop},
+ {"split", EFF_CHAN | EFF_MCHAN,
+ split_getopts, split_start, split_flow, null_drain,split_stop},
+ {"stat", EFF_MCHAN | EFF_REPORT | EFF_RATE | EFF_CHAN,
+ stat_getopts, stat_start, stat_flow, null_drain, stat_stop},
+ {"vibro", 0,
+ vibro_getopts, vibro_start, vibro_flow, null_drain, nothing},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+
--- /dev/null
+++ b/src/hcom.c
@@ -1,0 +1,492 @@
+/*
+ * Sound Tools Macintosh HCOM format.
+ * These are really FSSD type files with Huffman compression,
+ * in MacBinary format.
+ * To do: make the MacBinary format optional (so that .data files
+ * are also acceptable). (How to do this on output?)
+ *
+ * September 25, 1991
+ * Copyright 1991 Guido van Rossum And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * April 28, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ *
+ * Rearranged some functions so that they are declared before they are
+ * used. Clears up some compiler warnings. Because this functions passed
+ * foats, it helped out some dump compilers pass stuff on the stack
+ * correctly.
+ *
+ */
+
+#include "st.h"
+#include <string.h>
+
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+IMPORT char *malloc(), *realloc();
+#endif
+
+/* Dictionary entry for Huffman (de)compression */
+typedef struct {
+ LONG frequ;
+ short dict_leftson;
+ short dict_rightson;
+} dictent;
+
+/* Private data used by reader */
+struct readpriv {
+ /* Static data from the header */
+ dictent *dictionary;
+ LONG checksum;
+ int deltacompression;
+ /* Engine state */
+ LONG huffcount;
+ LONG cksum;
+ int dictentry;
+ int nrbits;
+ ULONG current;
+ short sample;
+};
+
+void skipbytes(P2(ft_t, int));
+
+void hcomstartread(ft)
+ft_t ft;
+{
+ struct readpriv *p = (struct readpriv *) ft->priv;
+ int i;
+ char buf[4];
+ ULONG datasize, rsrcsize;
+ ULONG huffcount, checksum, compresstype, divisor;
+ unsigned short dictsize;
+
+ /* Skip first 65 bytes of header */
+ skipbytes(ft, 65);
+
+ /* Check the file type (bytes 65-68) */
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "FSSD", 4) != 0)
+ fail("Mac header type is not FSSD");
+
+ /* Skip to byte 83 */
+ skipbytes(ft, 83-69);
+
+ /* Get essential numbers from the header */
+ datasize = rblong(ft); /* bytes 83-86 */
+ rsrcsize = rblong(ft); /* bytes 87-90 */
+
+ /* Skip the rest of the header (total 128 bytes) */
+ skipbytes(ft, 128-91);
+
+ /* The data fork must contain a "HCOM" header */
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "HCOM", 4) != 0)
+ fail("Mac data fork is not HCOM");
+
+ /* Then follow various parameters */
+ huffcount = rblong(ft);
+ checksum = rblong(ft);
+ compresstype = rblong(ft);
+ if (compresstype > 1)
+ fail("Bad compression type in HCOM header");
+ divisor = rblong(ft);
+ if (divisor == 0 || divisor > 4)
+ fail("Bad sampling rate divisor in HCOM header");
+ dictsize = rbshort(ft);
+
+ /* Translate to sox parameters */
+ ft->info.style = UNSIGNED;
+ ft->info.size = BYTE;
+ ft->info.rate = 22050 / divisor;
+ ft->info.channels = 1;
+
+ /* Allocate memory for the dictionary */
+ p->dictionary = (dictent *) malloc(511 * sizeof(dictent));
+ if (p->dictionary == NULL)
+ fail("can't malloc memory for Huffman dictionary");
+
+ /* Read dictionary */
+ for(i = 0; i < dictsize; i++) {
+ p->dictionary[i].dict_leftson = rbshort(ft);
+ p->dictionary[i].dict_rightson = rbshort(ft);
+ /*
+ report("%d %d",
+ p->dictionary[i].dict_leftson,
+ p->dictionary[i].dict_rightson);
+ */
+ }
+ skipbytes(ft, 1); /* skip pad byte */
+
+ /* Initialized the decompression engine */
+ p->checksum = checksum;
+ p->deltacompression = compresstype;
+ if (!p->deltacompression)
+ report("HCOM data using value compression");
+ p->huffcount = huffcount;
+ p->cksum = 0;
+ p->dictentry = 0;
+ p->nrbits = -1; /* Special case to get first byte */
+}
+
+void skipbytes(ft, n)
+ft_t ft;
+int n;
+{
+ while (--n >= 0) {
+ if (getc(ft->fp) == EOF)
+ fail("unexpected EOF in Mac header");
+ }
+}
+
+int hcomread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register struct readpriv *p = (struct readpriv *) ft->priv;
+ int done = 0;
+
+ if (p->nrbits < 0) {
+ /* The first byte is special */
+ if (p->huffcount == 0)
+ return 0; /* Don't know if this can happen... */
+ p->sample = getc(ft->fp);
+ if (p->sample == EOF)
+ fail("unexpected EOF at start of HCOM data");
+ *buf++ = (p->sample - 128) * 0x1000000L;
+ p->huffcount--;
+ p->nrbits = 0;
+ done++;
+ len--;
+ if (len == 0)
+ return done;
+ }
+
+ while (p->huffcount > 0) {
+ if(p->nrbits == 0) {
+ p->current = rblong(ft);
+ if (feof(ft->fp))
+ fail("unexpected EOF in HCOM data");
+ p->cksum += p->current;
+ p->nrbits = 32;
+ }
+ if(p->current & 0x80000000L) {
+ p->dictentry =
+ p->dictionary[p->dictentry].dict_rightson;
+ } else {
+ p->dictentry =
+ p->dictionary[p->dictentry].dict_leftson;
+ }
+ p->current = p->current << 1;
+ p->nrbits--;
+ if(p->dictionary[p->dictentry].dict_leftson < 0) {
+ short datum;
+ datum = p->dictionary[p->dictentry].dict_rightson;
+ if (!p->deltacompression)
+ p->sample = 0;
+ p->sample = (p->sample + datum) & 0xff;
+ p->huffcount--;
+ if (p->sample == 0)
+ *buf++ = -127 * 0x1000000L;
+ else
+ *buf++ = (p->sample - 128) * 0x1000000L;
+ p->dictentry = 0;
+ done++;
+ len--;
+ if (len == 0)
+ break;
+ }
+ }
+
+ return done;
+}
+
+void hcomstopread(ft)
+ft_t ft;
+{
+ register struct readpriv *p = (struct readpriv *) ft->priv;
+
+ if (p->huffcount != 0)
+ fail("not all HCOM data read");
+ if(p->cksum != p->checksum)
+ fail("checksum error in HCOM data");
+ free((char *)p->dictionary);
+ p->dictionary = NULL;
+}
+
+struct writepriv {
+ unsigned char *data; /* Buffer allocated with malloc */
+ unsigned int size; /* Size of allocated buffer */
+ unsigned int pos; /* Where next byte goes */
+};
+
+#define BUFINCR (10*BUFSIZ)
+
+void hcomstartwrite(ft)
+ft_t ft;
+{
+ register struct writepriv *p = (struct writepriv *) ft->priv;
+
+ switch (ft->info.rate) {
+ case 22050:
+ case 22050/2:
+ case 22050/3:
+ case 22050/4:
+ break;
+ default:
+ fail("unacceptable output rate for HCOM: try 5512, 7350, 11025 or 22050 hertz");
+ }
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ ft->info.channels = 1;
+
+ p->size = BUFINCR;
+ p->pos = 0;
+ p->data = (unsigned char *) malloc(p->size);
+ if (p->data == NULL)
+ fail("can't malloc buffer for uncompressed HCOM data");
+}
+
+void hcomwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register struct writepriv *p = (struct writepriv *) ft->priv;
+ LONG datum;
+
+ if (p->pos + len > p->size) {
+ p->size = ((p->pos + len) / BUFINCR + 1) * BUFINCR;
+ p->data = (unsigned char *) realloc(p->data, p->size);
+ if (p->data == NULL)
+ fail("can't realloc buffer for uncompressed HCOM data");
+ }
+
+ while (--len >= 0) {
+ datum = *buf++;
+ datum >>= 24;
+ datum ^= 128;
+ p->data[p->pos++] = datum;
+ }
+}
+
+/* Some global compression stuff hcom uses. hcom currently has problems */
+/* compiling here. It could really use some cleaning up by someone that */
+/* understands this format. */
+
+/* XXX This uses global variables -- one day these should all be
+ passed around in a structure instead. */
+
+dictent dictionary[511];
+dictent *de;
+LONG codes[256];
+LONG codesize[256];
+LONG checksum;
+
+void makecodes(e, c, s, b)
+int e, c, s, b;
+{
+ if(dictionary[e].dict_leftson < 0) {
+ codes[dictionary[e].dict_rightson] = c;
+ codesize[dictionary[e].dict_rightson] = s;
+ } else {
+ makecodes(dictionary[e].dict_leftson, c, s + 1, b << 1);
+ makecodes(dictionary[e].dict_rightson, c + b, s + 1, b << 1);
+ }
+}
+
+LONG curword;
+int nbits;
+
+void putlong(c, v)
+unsigned char *c;
+LONG v;
+{
+ *c++ = (v >> 24) & 0xff;
+ *c++ = (v >> 16) & 0xff;
+ *c++ = (v >> 8) & 0xff;
+ *c++ = v & 0xff;
+}
+
+void putshort(c, v)
+unsigned char *c;
+short v;
+{
+ *c++ = (v >> 8) & 0xff;
+ *c++ = v & 0xff;
+}
+
+
+void putcode(c, df)
+unsigned char c;
+unsigned char ** df;
+{
+LONG code, size;
+int i;
+ code = codes[c];
+ size = codesize[c];
+ for(i = 0; i < size; i++) {
+ curword = (curword << 1);
+ if(code & 1) curword += 1;
+ nbits++;
+ if(nbits == 32) {
+ putlong(*df, curword);
+ checksum += curword;
+ (*df) += 4;
+ nbits = 0;
+ curword = 0;
+ }
+ code = code >> 1;
+ }
+}
+
+void compress(df, dl, fr)
+unsigned char **df;
+LONG *dl;
+float fr;
+{
+ LONG samplerate;
+ unsigned char *datafork = *df;
+ unsigned char *ddf;
+ short dictsize;
+ int frequtable[256];
+ int i, sample, j, k, d, l, frequcount;
+
+ sample = *datafork;
+ for(i = 0; i < 256; i++) frequtable[i] = 0;
+ for(i = 1; i < *dl; i++) {
+ d = (datafork[i] - (sample & 0xff)) & 0xff; /* creates absolute entries LMS */
+ sample = datafork[i];
+ datafork[i] = d;
+#if 0 /* checking our table is accessed correctly */
+ if(d < 0 || d > 255)
+ printf("d is outside array bounds %d\n", d);
+#endif
+ frequtable[d]++;
+ }
+ de = dictionary;
+ for(i = 0; i < 256; i++) if(frequtable[i] != 0) {
+ de->frequ = -frequtable[i];
+ de->dict_leftson = -1;
+ de->dict_rightson = i;
+ de++;
+ }
+ frequcount = de - dictionary;
+ for(i = 0; i < frequcount; i++) {
+ for(j = i + 1; j < frequcount; j++) {
+ if(dictionary[i].frequ > dictionary[j].frequ) {
+ k = dictionary[i].frequ;
+ dictionary[i].frequ = dictionary[j].frequ;
+ dictionary[j].frequ = k;
+ k = dictionary[i].dict_leftson;
+ dictionary[i].dict_leftson = dictionary[j].dict_leftson;
+ dictionary[j].dict_leftson = k;
+ k = dictionary[i].dict_rightson;
+ dictionary[i].dict_rightson = dictionary[j].dict_rightson;
+ dictionary[j].dict_rightson = k;
+ }
+ }
+ }
+ while(frequcount > 1) {
+ j = frequcount - 1;
+ de->frequ = dictionary[j - 1].frequ;
+ de->dict_leftson = dictionary[j - 1].dict_leftson;
+ de->dict_rightson = dictionary[j - 1].dict_rightson;
+ l = dictionary[j - 1].frequ + dictionary[j].frequ;
+ for(i = j - 2; i >= 0; i--) {
+ if(l >= dictionary[i].frequ) break;
+ dictionary[i + 1] = dictionary[i];
+ }
+ i = i + 1;
+ dictionary[i].frequ = l;
+ dictionary[i].dict_leftson = j;
+ dictionary[i].dict_rightson = de - dictionary;
+ de++;
+ frequcount--;
+ }
+ dictsize = de - dictionary;
+ for(i = 0; i < 256; i++) {
+ codes[i] = 0;
+ codesize[i] = 0;
+ }
+ makecodes(0, 0, 0, 1);
+ l = 0;
+ for(i = 0; i < 256; i++) {
+ l += frequtable[i] * codesize[i];
+ }
+ l = (((l + 31) >> 5) << 2) + 24 + dictsize * 4;
+ report(" Original size: %6d bytes", *dl);
+ report("Compressed size: %6d bytes", l);
+ if((datafork = (unsigned char *)malloc((unsigned)l)) == NULL)
+ fail("can't malloc buffer for compressed HCOM data");
+ ddf = datafork + 22;
+ for(i = 0; i < dictsize; i++) {
+ putshort(ddf, dictionary[i].dict_leftson);
+ ddf += 2;
+ putshort(ddf, dictionary[i].dict_rightson);
+ ddf += 2;
+ }
+ *ddf++ = 0;
+ *ddf++ = *(*df)++;
+ checksum = 0;
+ nbits = 0;
+ curword = 0;
+ for(i = 1; i < *dl; i++) putcode(*(*df)++, &ddf);
+ if(nbits != 0) {
+ codes[0] = 0;
+ codesize[0] = 32 - nbits;
+ putcode(0, &ddf);
+ }
+ strncpy((char *) datafork, "HCOM", 4);
+ putlong(datafork + 4, *dl);
+ putlong(datafork + 8, checksum);
+ putlong(datafork + 12, 1L);
+ samplerate = 22050 / (LONG)fr;
+ putlong(datafork + 16, samplerate);
+ putshort(datafork + 20, dictsize);
+ *df = datafork; /* reassign passed pointer to new datafork */
+ *dl = l; /* and its compressed length */
+}
+
+void padbytes(ft, n)
+ft_t ft;
+int n;
+{
+ while (--n >= 0)
+ putc('\0', ft->fp);
+}
+
+
+/* End of hcom utility routines */
+
+void hcomstopwrite(ft)
+ft_t ft;
+{
+ register struct writepriv *p = (struct writepriv *) ft->priv;
+ unsigned char *compressed_data = p->data;
+ LONG compressed_len = p->pos;
+
+ /* Compress it all at once */
+ compress(&compressed_data, &compressed_len, (double) ft->info.rate);
+ free((char *) p->data);
+
+ /* Write the header */
+ (void) fwrite("\000\001A", 1, 3, ft->fp); /* Dummy file name "A" */
+ padbytes(ft, 65-3);
+ (void) fwrite("FSSD", 1, 4, ft->fp);
+ padbytes(ft, 83-69);
+ wblong(ft, (ULONG) compressed_len); /* compressed_data size */
+ wblong(ft, (ULONG) 0); /* rsrc size */
+ padbytes(ft, 128 - 91);
+ if (ferror(ft->fp))
+ fail("write error in HCOM header");
+
+ /* Write the compressed_data fork */
+ if (fwrite((char *) compressed_data, 1, (int)compressed_len, ft->fp) != compressed_len)
+ fail("can't write compressed HCOM data");
+ free((char *) compressed_data);
+
+ /* Pad the compressed_data fork to a multiple of 128 bytes */
+ padbytes(ft, 128 - (int) (compressed_len%128));
+}
+
--- /dev/null
+++ b/src/highp.c
@@ -1,0 +1,105 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools High-Pass effect file.
+ *
+ * Algorithm: 1nd order filter.
+ * From Fugue source code:
+ *
+ * output[N] = B * (output[N-1] - input[N-1] + input[N])
+ *
+ * A = 2.0 * pi * center
+ * B = exp(-A / frequency)
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for Highpass effect */
+typedef struct highpstuff {
+ float center;
+ double A, B;
+ double in1, out1;
+} *highp_t;
+
+/*
+ * Process options
+ */
+void highp_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ highp_t highp = (highp_t) effp->priv;
+
+ if ((n < 1) || !sscanf(argv[0], "%f", &highp->center))
+ fail("Usage: highp center");
+}
+
+/*
+ * Prepare processing.
+ */
+void highp_start(effp)
+eff_t effp;
+{
+ highp_t highp = (highp_t) effp->priv;
+ if (highp->center > effp->ininfo.rate*2)
+ fail("Highpass: center must be < minimum data rate*2\n");
+
+ highp->A = (M_PI * 2.0 * highp->center) / effp->ininfo.rate;
+ highp->B = exp(-highp->A / effp->ininfo.rate);
+ highp->in1 = 0.0;
+ highp->out1 = 0.0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void highp_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ highp_t highp = (highp_t) effp->priv;
+ int len, done;
+ double d;
+ LONG l;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ d = highp->out1;
+
+ /* yeah yeah yeah registers & integer arithmetic yeah yeah yeah */
+ for(done = 0; done < len; done++) {
+ l = *ibuf++;
+ d = (highp->B * ((d - highp->in1) + (double) l)) / 65536.0;
+ d *= 0.8;
+ if (d > 32767)
+ d = 32767;
+ if (d < - 32767)
+ d = - 32767;
+ highp->in1 = l;
+ *obuf++ = d * 65536L;
+ }
+ highp->out1 = d;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void highp_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
--- /dev/null
+++ b/src/lowp.c
@@ -1,0 +1,102 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools Low-Pass effect file.
+ *
+ * Algorithm: 1nd order filter.
+ * From Fugue source code:
+ *
+ * output[N] = input[N] * A + input[N-1] * B
+ *
+ * A = 2.0 * pi * center
+ * B = exp(-A / frequency)
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for Lowpass effect */
+typedef struct lowpstuff {
+ float center;
+ double A, B;
+ double in1;
+} *lowp_t;
+
+/*
+ * Process options
+ */
+void lowp_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ lowp_t lowp = (lowp_t) effp->priv;
+
+ if ((n < 1) || !sscanf(argv[0], "%f", &lowp->center))
+ fail("Usage: lowp center");
+}
+
+/*
+ * Prepare processing.
+ */
+void lowp_start(effp)
+eff_t effp;
+{
+ lowp_t lowp = (lowp_t) effp->priv;
+ if (lowp->center > effp->ininfo.rate*2)
+ fail("Lowpass: center must be < minimum data rate*2\n");
+
+ lowp->A = (M_PI * 2.0 * lowp->center) / effp->ininfo.rate;
+ lowp->B = exp(-lowp->A / effp->ininfo.rate);
+ lowp->in1 = 0.0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void lowp_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ lowp_t lowp = (lowp_t) effp->priv;
+ int len, done;
+ double d;
+ LONG l;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+
+ /* yeah yeah yeah registers & integer arithmetic yeah yeah yeah */
+ for(done = 0; done < len; done++) {
+ l = *ibuf++;
+ d = lowp->A * (l / 65536L) + lowp->B * (lowp->in1 / 65536L);
+ d *= 0.8;
+ if (d > 32767)
+ d = 32767;
+ if (d < - 32767)
+ d = - 32767;
+ lowp->in1 = l;
+ *obuf++ = d * 65536L;
+ }
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void lowp_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
--- /dev/null
+++ b/src/map.c
@@ -1,0 +1,67 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools Map effect file.
+ *
+ * Print out map of sound file instrument specifications.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/*
+ * Process options
+ */
+void map_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Map effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ */
+void map_start(effp)
+eff_t effp;
+{
+ int i;
+
+ fprintf(stderr, "Loop info:\n");
+ for(i = 0; i < 8; i++) {
+ fprintf(stderr, "Loop %d: start: %6d",i,effp->loops[i].start);
+ fprintf(stderr, " length: %6d", effp->loops[i].length);
+ fprintf(stderr, " count: %6d", effp->loops[i].count);
+ fprintf(stderr, " type: ");
+ switch(effp->loops[i].type) {
+ case 0: fprintf(stderr, "off\n"); break;
+ case 1: fprintf(stderr, "forward\n"); break;
+ case 2: fprintf(stderr, "forward/backward\n"); break;
+ }
+ }
+ fprintf(stderr, "MIDI note: %d\n", effp->instr.MIDInote);
+ fprintf(stderr, "MIDI low : %d\n", effp->instr.MIDIlow);
+ fprintf(stderr, "MIDI hi : %d\n", effp->instr.MIDIhi);
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void map_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+}
--- /dev/null
+++ b/src/mask.c
@@ -1,0 +1,100 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools masking noise effect file.
+ */
+
+#include <math.h>
+#include "st.h"
+
+#define HALFABIT 1.44 /* square root of 2 */
+
+void newrand15();
+ULONG rand15();
+
+/*
+ * Problems:
+ * 1) doesn't allow specification of noise depth
+ * 2) does triangular noise, could do local shaping
+ * 3) can run over 32 bits.
+ */
+
+/*
+ * Process options
+ */
+void mask_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Mask effect takes no options.");
+ /* should take # of bits */
+
+ newrand15();
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void mask_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ int len, done;
+
+ LONG l;
+ LONG tri16; /* 16 signed bits of triangular noise */
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ switch (effp->outinfo.style) {
+ case ULAW:
+ case ALAW:
+ for(done = 0; done < len; done++) {
+ tri16 = (rand15() + rand15()) - 32767;
+
+ l = *ibuf++ + tri16*16*HALFABIT; /* 2^4.5 */
+ *obuf++ = l;
+ }
+ break;
+ default:
+ switch (effp->outinfo.size) {
+ case BYTE:
+ for(done = 0; done < len; done++) {
+ tri16 = (rand15() + rand15()) - 32767;
+
+ l = *ibuf++ + tri16*256*HALFABIT; /* 2^8.5 */
+ *obuf++ = l;
+ }
+ break;
+ case WORD:
+ for(done = 0; done < len; done++) {
+ tri16 = (rand15() + rand15()) - 32767;
+
+ l = *ibuf++ + tri16*HALFABIT; /* 2^.5 */
+ *obuf++ = l;
+ }
+ break;
+ default:
+ for(done = 0; done < len; done++) {
+ *obuf++ = *ibuf++;
+ }
+ break;
+ }
+ }
+
+ *isamp = done;
+ *osamp = done;
+}
+
--- /dev/null
+++ b/src/maud.c
@@ -1,0 +1,430 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools MAUD file format driver, by Lutz Vieweg 1993
+ *
+ * supports: mono and stereo, linear, a-lawa and u-law reading and writing
+ *
+ */
+
+#include "st.h"
+#include "libst.h"
+#include <string.h>
+#include <stdlib.h>
+
+#define SEEK_CUR 1 /* nasty nasty */
+
+/* Private data for MAUD file */
+struct maudstuff { /* max. 100 bytes!!!! */
+ ULONG nsamples;
+};
+
+void maudwriteheader(P1(ft_t));
+void rawwrite(P3(ft_t, LONG *, LONG));
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void maudstartread(ft)
+ft_t ft;
+{
+ struct maudstuff * p = (struct maudstuff *) ft->priv;
+
+ char buf[12];
+ char *endptr;
+ char *chunk_buf;
+
+ unsigned short bitpersam;
+ ULONG nom;
+ unsigned short denom;
+ unsigned short chaninf;
+
+ ULONG chunksize;
+
+ int littlendian = 0;
+
+ /* read FORM chunk */
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "FORM", 4) != 0)
+ fail("MAUD: header does not begin with magic word 'FORM'");
+
+ rblong(ft); /* totalsize */
+
+ if (fread(buf, 1, 4, ft->fp) != 4 || strncmp(buf, "MAUD", 4) != 0)
+ fail("MAUD: 'FORM' chunk does not specify 'MAUD' as type");
+
+ /* read chunks until 'BODY' (or end) */
+
+ while (fread(buf,1,4,ft->fp) == 4 && strncmp(buf,"MDAT",4) != 0) {
+
+ /*
+ buf[4] = 0;
+ report("chunk %s",buf);
+ */
+
+ if (strncmp(buf,"MHDR",4) == 0) {
+
+ chunksize = rblong(ft);
+ if (chunksize != 8*4) fail ("MAUD: MHDR chunk has bad size");
+
+ /* fseek(ft->fp,12,SEEK_CUR); */
+
+ p->nsamples = rblong(ft); /* number of samples stored in MDAT */
+ bitpersam = rbshort(ft); /* number of bits per sample as stored in MDAT */
+ rbshort(ft); /* number of bits per sample after decompression */
+ nom = rblong(ft); /* clock source frequency */
+ denom = rbshort(ft); /* clock devide */
+ if (denom == 0) fail("MAUD: frequency denominator == 0, failed");
+
+ ft->info.rate = nom / denom;
+
+ chaninf = rbshort(ft); /* channel information */
+ switch (chaninf) {
+ case 0:
+ ft->info.channels = 1;
+ break;
+ case 1:
+ ft->info.channels = 2;
+ break;
+ default:
+ fail("MAUD: unsupported number of channels in file");
+ break;
+ }
+
+ chaninf = rbshort(ft); /* number of channels (mono: 1, stereo: 2, ...) */
+ if (chaninf != ft->info.channels) fail("MAUD: unsupported number of channels in file");
+
+ chaninf = rbshort(ft); /* compression type */
+
+ rblong(ft); /* rest of chunk, unused yet */
+ rblong(ft);
+ rblong(ft);
+
+ if (bitpersam == 8 && chaninf == 0) {
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ }
+ else if (bitpersam == 8 && chaninf == 2) {
+ ft->info.size = BYTE;
+ ft->info.style = ALAW;
+ }
+ else if (bitpersam == 8 && chaninf == 3) {
+ ft->info.size = BYTE;
+ ft->info.style = ULAW;
+ }
+ else if (bitpersam == 16 && chaninf == 0) {
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ }
+ else fail("MAUD: unsupported compression type detected");
+
+ ft->comment = 0;
+
+ continue;
+ }
+
+ if (strncmp(buf,"ANNO",4) == 0) {
+ chunksize = rblong(ft);
+ if (chunksize & 1)
+ chunksize++;
+ chunk_buf = (char *) malloc(chunksize + 1);
+ if (fread(chunk_buf,1,(int)chunksize,ft->fp)
+ != chunksize)
+ fail("MAUD: Unexpected EOF in ANNO header");
+ chunk_buf[chunksize] = '\0';
+ report ("%s",chunk_buf);
+ free(chunk_buf);
+
+ continue;
+ }
+
+ /* some other kind of chunk */
+ chunksize = rblong(ft);
+ if (chunksize & 1)
+ chunksize++;
+ fseek(ft->fp,chunksize,SEEK_CUR);
+ continue;
+
+ }
+
+ if (strncmp(buf,"MDAT",4) != 0) fail("MAUD: MDAT chunk not found");
+ p->nsamples = rblong(ft);
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1) ft->swap = 1;
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG maudread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register int datum;
+ int done = 0;
+
+ if (ft->info.channels == 1) {
+ if (ft->info.size == BYTE) {
+ switch(ft->info.style) {
+ case UNSIGNED:
+ while(done < len) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp)) return done;
+ /* Convert to signed */
+ datum ^= 128;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ break;
+ case ULAW:
+ /* grab table from Posk stuff */
+ while(done < len) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp)) return done;
+ datum = st_ulaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ break;
+ case ALAW:
+ while(done < len) {
+ datum = st_Alaw_to_linear((unsigned char) getc(ft->fp));
+ if (feof(ft->fp)) return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ break;
+ }
+ }
+ else {
+ while(done < len) {
+ datum = rbshort(ft);
+ if (feof(ft->fp)) return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ }
+ }
+ else { /* stereo */
+ if (ft->info.size == BYTE) {
+ switch(ft->info.style) {
+ case UNSIGNED:
+ while(done < len) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp)) return done;
+ /* Convert to signed */
+ datum ^= 128;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+
+ datum = getc(ft->fp);
+ if (feof(ft->fp)) return done;
+ /* Convert to signed */
+ datum ^= 128;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done += 2;
+ }
+ break;
+ case ULAW:
+ /* grab table from Posk stuff */
+ while(done < len) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp)) return done;
+ datum = st_ulaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+
+ datum = getc(ft->fp);
+ if (feof(ft->fp)) return done;
+ datum = st_ulaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done += 2;
+ }
+ break;
+ case ALAW:
+ while(done < len) {
+ datum = st_Alaw_to_linear((unsigned char) getc(ft->fp));
+ if (feof(ft->fp)) return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+
+ datum = st_Alaw_to_linear((unsigned char) getc(ft->fp));
+ if (feof(ft->fp)) return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done += 2;
+ }
+ break;
+ }
+ }
+ else {
+ while(done < len) {
+ datum = rbshort(ft);
+ if (feof(ft->fp)) return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+
+ datum = rbshort(ft);
+ if (feof(ft->fp)) return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done += 2;
+ }
+ }
+ }
+ return done;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void maudstopread(ft)
+ft_t ft;
+{
+}
+
+void maudstartwrite(ft)
+ft_t ft;
+{
+ struct maudstuff * p = (struct maudstuff *) ft->priv;
+ int littlendian = 0;
+ char *endptr;
+
+ /* If you have to seek around the output file */
+ if (! ft->seekable) fail("Output .maud file must be a file, not a pipe");
+
+ if (ft->info.channels != 1 && ft->info.channels != 2) {
+ fail("MAUD: unsupported number of channels, unable to store");
+ }
+ if (ft->info.size == WORD) ft->info.style = SIGN2;
+ if (ft->info.style == ULAW || ft->info.style == ALAW) ft->info.size = BYTE;
+ if (ft->info.size == BYTE && ft->info.style == SIGN2) ft->info.style = UNSIGNED;
+
+ p->nsamples = 0x7f000000L;
+ maudwriteheader(ft);
+ p->nsamples = 0;
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1) ft->swap = 1;
+}
+
+void maudwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ struct maudstuff * p = (struct maudstuff *) ft->priv;
+
+ p->nsamples += len;
+
+ rawwrite(ft, buf, len);
+}
+
+void maudstopwrite(ft)
+ft_t ft;
+{
+ /* All samples are already written out. */
+
+ if (fseek(ft->fp, 0L, 0) != 0) fail("can't rewind output file to rewrite MAUD header");
+
+ maudwriteheader(ft);
+}
+
+#define MAUDHEADERSIZE (4+(4+4+32)+(4+4+32)+(4+4))
+void maudwriteheader(ft)
+ft_t ft;
+{
+ struct maudstuff * p = (struct maudstuff *) ft->priv;
+
+ fputs ("FORM", ft->fp);
+ wblong(ft, (p->nsamples*ft->info.size) + MAUDHEADERSIZE); /* size of file */
+ fputs("MAUD", ft->fp); /* File type */
+
+ fputs ("MHDR", ft->fp);
+ wblong(ft, (LONG) 8*4); /* number of bytes to follow */
+ wblong(ft, (LONG) (p->nsamples )); /* number of samples stored in MDAT */
+
+ switch (ft->info.style) {
+
+ case UNSIGNED:
+ wbshort(ft, (int) 8); /* number of bits per sample as stored in MDAT */
+ wbshort(ft, (int) 8); /* number of bits per sample after decompression */
+ break;
+
+ case SIGN2:
+ wbshort(ft, (int) 16); /* number of bits per sample as stored in MDAT */
+ wbshort(ft, (int) 16); /* number of bits per sample after decompression */
+ break;
+
+ case ALAW:
+ case ULAW:
+ wbshort(ft, (int) 8); /* number of bits per sample as stored in MDAT */
+ wbshort(ft, (int) 16); /* number of bits per sample after decompression */
+ break;
+
+ }
+
+ wblong(ft, (LONG) ft->info.rate); /* clock source frequency */
+ wbshort(ft, (int) 1); /* clock devide */
+
+ if (ft->info.channels == 1) {
+ wbshort(ft, (int) 0); /* channel information */
+ wbshort(ft, (int) 1); /* number of channels (mono: 1, stereo: 2, ...) */
+ }
+ else {
+ wbshort(ft, (int) 1);
+ wbshort(ft, (int) 2);
+ }
+
+ switch (ft->info.style) {
+
+ case UNSIGNED:
+ case SIGN2:
+ wbshort(ft, (int) 0); /* no compression */
+ break;
+
+ case ULAW:
+ wbshort(ft, (int) 3);
+ break;
+
+ case ALAW:
+ wbshort(ft, (int) 2);
+ break;
+
+ }
+
+ wblong(ft, (LONG) 0); /* reserved */
+ wblong(ft, (LONG) 0); /* reserved */
+ wblong(ft, (LONG) 0); /* reserved */
+
+ fputs ("ANNO", ft->fp);
+ wblong(ft, (LONG) 32); /* length of block */
+ fputs ("file written by SOX MAUD-export ", ft->fp);
+
+ fputs ("MDAT", ft->fp);
+ wblong(ft, p->nsamples * ft->info.size ); /* samples in file */
+}
+
--- /dev/null
+++ b/src/misc.c
@@ -1,0 +1,434 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools miscellaneous stuff.
+ */
+
+#include "st.h"
+#include "version.h"
+#include "patchlvl.h"
+#include <stdio.h>
+#include <time.h>
+
+EXPORT char *sizes[] = {
+ "NONSENSE!",
+ "bytes",
+ "shorts",
+ "NONSENSE",
+ "longs",
+ "32-bit floats",
+ "64-bit floats",
+ "IEEE floats"
+};
+
+EXPORT char *styles[] = {
+ "NONSENSE!",
+ "unsigned",
+ "signed (2's complement)",
+ "u-law",
+ "a-law",
+ "adpcm",
+ "gsm"
+};
+
+char readerr[] = "Premature EOF while reading sample file.";
+char writerr[] = "Error writing sample file. You are probably out of disk space.";
+
+/* Utilities */
+
+/* Read short, little-endian: little end first. VAX/386 style. */
+unsigned short
+rlshort(ft)
+ft_t ft;
+{
+ unsigned char uc, uc2;
+ uc = getc(ft->fp);
+ uc2 = getc(ft->fp);
+ return (uc2 << 8) | uc;
+}
+
+/* Read short, bigendian: big first. 68000/SPARC style. */
+unsigned short
+rbshort(ft)
+ft_t ft;
+{
+ unsigned char uc, uc2;
+ uc2 = getc(ft->fp);
+ uc = getc(ft->fp);
+ return (uc2 << 8) | uc;
+}
+
+/* Write short, little-endian: little end first. VAX/386 style. */
+unsigned short
+#if defined(__STDC__)
+wlshort(ft_t ft, unsigned short us)
+#else
+wlshort(ft, us)
+ft_t ft;
+unsigned short us;
+#endif
+{
+ putc(us, ft->fp);
+ putc(us >> 8, ft->fp);
+ if (ferror(ft->fp))
+ fail(writerr);
+ return(0);
+}
+
+/* Write short, big-endian: big end first. 68000/SPARC style. */
+unsigned short
+#if defined(__STDC__)
+wbshort(ft_t ft, unsigned short us)
+#else
+wbshort(ft, us)
+ft_t ft;
+unsigned short us;
+#endif
+{
+ putc(us >> 8, ft->fp);
+ putc(us, ft->fp);
+ if (ferror(ft->fp))
+ fail(writerr);
+ return(0);
+}
+
+/* Read long, little-endian: little end first. VAX/386 style. */
+ULONG
+rllong(ft)
+ft_t ft;
+{
+ unsigned char uc, uc2, uc3, uc4;
+/* if (feof(ft->fp))
+ fail(readerr); */ /* No worky! */
+ uc = getc(ft->fp);
+ uc2 = getc(ft->fp);
+ uc3 = getc(ft->fp);
+ uc4 = getc(ft->fp);
+ return ((LONG)uc4 << 24) | ((LONG)uc3 << 16) | ((LONG)uc2 << 8) | (LONG)uc;
+}
+
+/* Read long, bigendian: big first. 68000/SPARC style. */
+ULONG
+rblong(ft)
+ft_t ft;
+{
+ unsigned char uc, uc2, uc3, uc4;
+/* if (feof(ft->fp))
+ fail(readerr); */ /* No worky! */
+ uc = getc(ft->fp);
+ uc2 = getc(ft->fp);
+ uc3 = getc(ft->fp);
+ uc4 = getc(ft->fp);
+ return ((LONG)uc << 24) | ((LONG)uc2 << 16) | ((LONG)uc3 << 8) | (LONG)uc4;
+}
+
+/* Write long, little-endian: little end first. VAX/386 style. */
+ULONG
+wllong(ft, ul)
+ft_t ft;
+ULONG ul;
+{
+char datum;
+
+ datum = (char) (ul) & 0xff;
+ putc(datum, ft->fp);
+ datum = (char) (ul >> 8) & 0xff;
+ putc(datum, ft->fp);
+ datum = (char) (ul >> 16) & 0xff;
+ putc(datum, ft->fp);
+ datum = (char) (ul >> 24) & 0xff;
+ putc(datum, ft->fp);
+ if (ferror(ft->fp))
+ fail(writerr);
+ return(0);
+}
+
+/* Write long, big-endian: big end first. 68000/SPARC style. */
+ULONG
+wblong(ft, ul)
+ft_t ft;
+ULONG ul;
+{
+char datum;
+
+ datum = (char) (ul >> 24) & 0xff;
+ putc(datum, ft->fp);
+ datum = (char) (ul >> 16) & 0xff;
+ putc(datum, ft->fp);
+ datum = (char) (ul >> 8) & 0xff;
+ putc(datum, ft->fp);
+ datum = (char) (ul) & 0xff;
+ putc(datum, ft->fp);
+ if (ferror(ft->fp))
+ fail(writerr);
+ return(0);
+}
+
+/* Read and write words and longs in "machine format". Swap if indicated. */
+
+/* Read short. */
+unsigned short
+rshort(ft)
+ft_t ft;
+{
+ unsigned short us;
+
+/* if (feof(ft->fp))
+ fail(readerr); */ /* No worky! */
+ fread(&us, 2, 1, ft->fp);
+ if (ft->swap)
+ us = swapw(us);
+ return us;
+}
+
+/* Write short. */
+unsigned short
+#if defined(__STDC__)
+wshort(ft_t ft, unsigned short us)
+#else
+wshort(ft, us)
+ft_t ft;
+unsigned short us;
+#endif
+{
+ if (ft->swap)
+ us = swapw(us);
+ if (fwrite(&us, 2, 1, ft->fp) != 1)
+ fail(writerr);
+ return(0);
+}
+
+/* Read long. */
+ULONG
+rlong(ft)
+ft_t ft;
+{
+ ULONG ul;
+
+/* if (feof(ft->fp))
+ fail(readerr); */ /* No worky! */
+ fread(&ul, 4, 1, ft->fp);
+ if (ft->swap)
+ ul = swapl(ul);
+ return ul;
+}
+
+/* Write long. */
+ULONG
+wlong(ft, ul)
+ft_t ft;
+ULONG ul;
+{
+ if (ft->swap)
+ ul = swapl(ul);
+ if (fwrite(&ul, 4, 1, ft->fp) != 1)
+ fail(writerr);
+ return(0);
+}
+
+/* Read float. */
+float
+rfloat(ft)
+ft_t ft;
+{
+ float f;
+
+/* if (feof(ft->fp))
+ fail(readerr); */ /* No worky! */
+ fread(&f, sizeof(float), 1, ft->fp);
+ if (ft->swap)
+ f = swapf(f);
+ return f;
+}
+
+void
+wfloat(ft, f)
+ft_t ft;
+float f;
+{
+ float t = f;
+
+ if (ft->swap)
+ t = swapf(t);
+ if (fwrite(&t, sizeof(float), 1, ft->fp) != 1)
+ fail(writerr);
+}
+
+/* Read double. */
+double
+rdouble(ft)
+ft_t ft;
+{
+ double d;
+
+/* if (feof(ft->fp))
+ fail(readerr); */ /* No worky! */
+ fread(&d, sizeof(double), 1, ft->fp);
+ if (ft->swap)
+ d = swapd(d);
+ return d;
+}
+
+/* Write double. */
+void
+wdouble(ft, d)
+ft_t ft;
+double d;
+{
+ if (ft->swap)
+ d = swapd(d);
+ if (fwrite(&d, sizeof(double), 1, ft->fp) != 1)
+ fail(writerr);
+}
+
+/* generic swap routine */
+static void
+swapb(l, f, n)
+char *l, *f;
+int n;
+{ register int i;
+
+ for (i= 0; i< n; i++)
+ f[i]= l[n-i-1];
+}
+
+
+/* Byte swappers */
+
+unsigned short
+#if defined(__STDC__)
+swapw(unsigned short us)
+#else
+swapw(us)
+unsigned short us;
+#endif
+{
+ return ((us >> 8) | (us << 8)) & 0xffff;
+}
+
+ULONG
+swapl(ul)
+ULONG ul;
+{
+ return (ul >> 24) | ((ul >> 8) & 0xff00) | ((ul << 8) & 0xff0000L) | (ul << 24);
+}
+
+/* return swapped 32-bit float */
+float
+#if defined(__STDC__)
+swapf(float uf)
+#else
+swapf(uf)
+float uf;
+#endif
+{
+ union {
+ ULONG l;
+ float f;
+ } u;
+
+ u.f= uf;
+ u.l= (u.l>>24) | ((u.l>>8)&0xff00) | ((u.l<<8)&0xff0000L) | (u.l<<24);
+ return u.f;
+}
+
+double
+swapd(df)
+double df;
+{
+ double sdf;
+ swapb(&df, &sdf, sizeof(double));
+ return (sdf);
+}
+
+
+/* dummy routines for do-nothing functions */
+void nothing() {}
+LONG nothing_success() {return(0);}
+
+/* dummy drain routine for effects */
+void null_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+LONG *osamp;
+{
+ *osamp = 0;
+}
+
+/* here for linear interp. might be useful for other things */
+LONG gcd(a, b)
+LONG a, b;
+{
+ if (b == 0)
+ return a;
+ else
+ return gcd(b, a % b);
+}
+
+LONG lcm(a, b)
+LONG a, b;
+{
+ return (a * b) / gcd(a, b);
+}
+
+/*
+ * Cribbed from Unix SVR3 programmer's manual
+ */
+
+static ULONG rand15_seed;
+
+ULONG rand15() {
+ rand15_seed = (rand15_seed * 1103515245L) + 12345L;
+ return (ULONG) ((rand15_seed/65536L) % 32768L);
+}
+
+void srand15(seed)
+ULONG seed;
+{
+ rand15_seed = seed;
+}
+
+void newrand15() {
+ time_t t;
+
+ time(&t);
+ srand15(t);
+}
+
+/* sine wave gen should be here, also */
+
+char *
+version()
+{
+ static char versionstr[20];
+
+ sprintf(versionstr, "Version %d.%d", VERSION, PATCHLEVEL);
+ return(versionstr);
+}
+
+
+#ifdef NEED_STRERROR
+/* strerror function */
+char *strerror(errcode)
+int errcode;
+{
+ static char nomesg[30];
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+
+ if (errcode < sys_nerr)
+ return (sys_errlist[errcode]);
+ else
+ {
+ sprintf (nomesg, "Undocumented error %d", errcode);
+ return (nomesg);
+ }
+}
+#endif
--- /dev/null
+++ b/src/oss.c
@@ -1,0 +1,474 @@
+#if defined(OSS_PLAYER)
+/*
+ * Copyright 1997 Chris Bagwell And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Chris Bagwell And Sundry Contributors are not
+ * responsible for the consequences of using this software.
+ */
+
+/* Direct to Open Sound System (OSS) sound driver
+ * OSS is a popular unix sound driver for Intel x86 unices (eg. Linux)
+ * and several other unixes (such as SunOS/Solaris).
+ * This driver is compatible with OSS original source that was called
+ * USS, Voxware and TASD.
+ *
+ * added by Chris Bagwell (cbagwell@sprynet.com) on 2/19/96
+ * based on info grabed from vplay.c in Voxware snd-utils-3.5 package.
+ * and on LINUX_PLAYER patches added by Greg Lee
+ * which was originally from Directo to Sound Blaster device driver (sbdsp.c).
+ * SBLAST patches by John T. Kohl.
+ */
+
+#include <malloc.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/soundcard.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include "st.h"
+#include "libst.h"
+
+static int got_int = 0;
+
+static int abuf_size = 0;
+static int abuf_cnt = 0;
+static char *audiobuf;
+
+/* This is how we know when to stop recording. User sends interrupt
+ * (eg. control-c) and then we mark a flag to show we are done.
+ * Must call "sigint(0)" during init so that the OS can be notified
+ * what to do.
+ */
+static void
+sigint(s)
+{
+ if (s) got_int = 1;
+ else signal(SIGINT, sigint);
+}
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void ossdspstartread(ft)
+ft_t ft;
+{
+ int tmp;
+ int samplesize = 8, dsp_stereo;
+
+ if (ft->info.rate == 0.0) ft->info.rate = 8000;
+ if (ft->info.size == -1) ft->info.size = BYTE;
+ if (ft->info.size == BYTE) {
+ samplesize = 8;
+ if (ft->info.style == -1)
+ ft->info.style = UNSIGNED;
+ if (ft->info.style != UNSIGNED) {
+ fail("OSS driver only supports unsigned with bytes");
+ }
+ }
+ else if (ft->info.size == WORD) {
+ samplesize = 16;
+ if (ft->info.style == -1)
+ ft->info.style = SIGN2;
+ if (ft->info.style != SIGN2) {
+ fail("OSS driver only supports signed with words");
+ }
+ }
+ else {
+ fail("OSS driver only supports bytes and words");
+ }
+
+ if (ft->info.channels == -1) ft->info.channels = 1;
+ else if (ft->info.channels > 2) ft->info.channels = 2;
+
+ ioctl(fileno(ft->fp), SNDCTL_DSP_RESET, 0);
+ ioctl (fileno(ft->fp), SNDCTL_DSP_GETBLKSIZE, &abuf_size);
+ if (abuf_size < 4 || abuf_size > 65536) {
+ fail("Invalid audio buffer size %d", abuf_size);
+ }
+
+ if ((audiobuf = malloc (abuf_size)) == NULL) {
+ fail("Unable to allocate input/output buffer of size %d", abuf_size);
+ }
+
+ if (ioctl(fileno(ft->fp), SNDCTL_DSP_SYNC, NULL) < 0) {
+ fail("Unable to sync dsp");
+ }
+
+ tmp = samplesize;
+ ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+ if (tmp != samplesize) {
+ fail("Unable to set the sample size to %d", samplesize);
+ }
+
+ if (ft->info.channels == 2) dsp_stereo = 1;
+ else dsp_stereo = 0;
+
+ tmp = dsp_stereo;
+ ioctl(fileno(ft->fp), SNDCTL_DSP_STEREO, &tmp);
+ if (tmp != dsp_stereo) {
+ ft->info.channels = 1;
+ warn("Couldn't set to %s", dsp_stereo? "stereo":"mono");
+ dsp_stereo = 0;
+ }
+
+ tmp = ft->info.rate;
+ ioctl (fileno(ft->fp), SNDCTL_DSP_SPEED, &tmp);
+ if (ft->info.rate != tmp) {
+ if (ft->info.rate - tmp > tmp/10 || tmp - ft->info.rate > tmp/10)
+ warn("Unable to set audio speed to %d (set to %d)",
+ ft->info.rate, tmp);
+ ft->info.rate = tmp;
+ }
+
+ sigint(0); /* Prepare to catch SIGINT */
+}
+
+int dspget(ft)
+ft_t ft;
+{
+ int rval;
+
+ if (abuf_cnt < 1) {
+ abuf_cnt = read (fileno(ft->fp), (char *)audiobuf, abuf_size);
+ if (abuf_cnt == 0) {
+ got_int = 1; /* Act like user said end record */
+ return(0);
+ }
+ }
+ rval = *(audiobuf + (abuf_size-abuf_cnt));
+ abuf_cnt--;
+ return(rval);
+}
+
+/* Read short. */
+unsigned short dsprshort(ft)
+ft_t ft;
+{
+ unsigned short rval;
+ if (abuf_cnt < 2) {
+ abuf_cnt = read (fileno(ft->fp), (char *)audiobuf, abuf_size);
+ if (abuf_cnt == 0) {
+ got_int = 1; /* act like user said end recording */
+ return(0);
+ }
+ }
+ rval = *((unsigned short *)(audiobuf + (abuf_size-abuf_cnt)));
+ abuf_cnt -= 2;
+ return(rval);
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG ossdspread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register int datum;
+ int done = 0;
+
+ if (got_int)
+ return(0); /* Return with length 0 read so program will end */
+
+ switch(ft->info.size) {
+ case BYTE:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ return done;
+ case UNSIGNED:
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* Convert to unsigned */
+ datum ^= 128;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ return done;
+ case ULAW:
+ /* grab table from Posk stuff */
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ datum = st_ulaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case ALAW:
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ datum = st_Alaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ }
+ case WORD:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ datum = dsprshort(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case UNSIGNED:
+ while(done < len) {
+ datum = dsprshort(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* Convert to unsigned */
+ datum ^= 0x8000;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case ULAW:
+ fail("No U-Law support for shorts");
+ return done;
+ case ALAW:
+ fail("No A-Law support");
+ return done;
+ }
+ }
+ fail("Drop through in ossdspread!");
+
+ /* Return number of samples read */
+ return(done);
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void ossdspstopread(ft)
+ft_t ft;
+{
+}
+
+void ossdspstartwrite(ft)
+ft_t ft;
+{
+ int samplesize = 8, dsp_stereo;
+ int tmp;
+
+ if (ft->info.rate == 0.0) ft->info.rate = 8000;
+ if (ft->info.size == -1) ft->info.size = BYTE;
+ if (ft->info.size == BYTE) {
+ samplesize = 8;
+ if (ft->info.style == -1)
+ ft->info.style = UNSIGNED;
+ if (ft->info.style != UNSIGNED) {
+ report("OSS driver only supports unsigned with bytes");
+ report("Forcing to unsigned");
+ ft->info.style = UNSIGNED;
+ }
+ }
+ else if (ft->info.size == WORD) {
+ samplesize = 16;
+ if (ft->info.style == -1)
+ ft->info.style = SIGN2;
+ if (ft->info.style != SIGN2) {
+ report("OSS driver only supports signed with words");
+ report("Forcing to signed linear");
+ ft->info.style = SIGN2;
+ }
+ }
+ else {
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ report("OSS driver only supports bytes and words");
+ report("Forcing to signed linear word");
+ }
+
+ if (ft->info.channels == -1) ft->info.channels = 1;
+ else if (ft->info.channels > 2) ft->info.channels = 2;
+
+ ioctl(fileno(ft->fp), SNDCTL_DSP_RESET, 0);
+ ioctl (fileno(ft->fp), SNDCTL_DSP_GETBLKSIZE, &abuf_size);
+ if (abuf_size < 4 || abuf_size > 65536) {
+ fail("Invalid audio buffer size %d", abuf_size);
+ }
+
+ if ((audiobuf = malloc (abuf_size)) == NULL) {
+ fail("Unable to allocate input/output buffer of size %d", abuf_size);
+ }
+
+ if (ioctl(fileno(ft->fp), SNDCTL_DSP_SYNC, NULL) < 0) {
+ fail("Unable to sync dsp");
+ }
+
+ tmp = samplesize;
+ ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+ if (tmp != samplesize) {
+ fail("Unable to set the sample size to %d", samplesize);
+ }
+
+ if (ft->info.channels == 2) dsp_stereo = 1;
+ else dsp_stereo = 0;
+
+ tmp = dsp_stereo;
+ ioctl(fileno(ft->fp), SNDCTL_DSP_STEREO, &tmp);
+ if (tmp != dsp_stereo) {
+ ft->info.channels = 1;
+ warn("Couldn't set to %s", dsp_stereo? "stereo":"mono");
+ dsp_stereo = 0;
+ }
+
+ tmp = ft->info.rate;
+ ioctl (fileno(ft->fp), SNDCTL_DSP_SPEED, &tmp);
+ if (ft->info.rate != tmp) {
+ if (ft->info.rate - tmp > tmp/10 || tmp - ft->info.rate > tmp/10)
+ warn("Unable to set audio speed to %d (set to %d)",
+ ft->info.rate, tmp);
+ ft->info.rate = tmp;
+ }
+}
+
+void dspflush(ft)
+ft_t ft;
+{
+ if (write (fileno(ft->fp), audiobuf, abuf_cnt) != abuf_cnt) {
+ fail("Error writing to sound driver");
+ }
+ abuf_cnt = 0;
+}
+
+void dspput(ft,c)
+ft_t ft;
+int c;
+{
+ if (abuf_cnt > abuf_size-1) dspflush(ft);
+ *(audiobuf + abuf_cnt) = c;
+ abuf_cnt++;
+}
+
+/* Write short. */
+void
+dspshort(ft,ui)
+ft_t ft;
+unsigned short ui;
+{
+ if (abuf_cnt > abuf_size-2) dspflush(ft);
+ *((unsigned short *)(audiobuf + abuf_cnt)) = ui;
+ abuf_cnt += 2;
+}
+
+void ossdspwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register int datum;
+ int done = 0;
+
+ switch(ft->info.size) {
+ case BYTE:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 24);
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ case UNSIGNED:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 24);
+ /* Convert to unsigned */
+ datum ^= 128;
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ case ULAW:
+ /* grab table from Posk stuff */
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ datum = st_linear_to_ulaw(datum);
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ case ALAW:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ /* round up to 12 bits of data */
+ datum += 0x8; /* + 0b1000 */
+ datum = st_linear_to_Alaw(datum);
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ }
+ case WORD:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ dspshort(ft,datum);
+ done++;
+ }
+ return;
+ case UNSIGNED:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ /* Convert to unsigned */
+ datum ^= 0x8000;
+ dspshort(ft,datum);
+ done++;
+ }
+ return;
+ case ULAW:
+ fail("No U-Law support for shorts");
+ return;
+ case ALAW:
+ fail("No A-Law support");
+ return;
+ }
+ }
+ fail("Drop through in ossdspwrite!");
+}
+
+void ossdspstopwrite(ft)
+ft_t ft;
+{
+ dspflush(ft);
+}
+#endif
--- /dev/null
+++ b/src/phaser.c
@@ -1,0 +1,298 @@
+
+/*
+ * August 24, 1998
+ * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Juergen Mueller And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Phaser effect.
+ *
+ * Flow diagram scheme:
+ *
+ * * gain-in +---+ * gain-out
+ * ibuff ----------->| |----------------------------------> obuff
+ * | + | * decay
+ * | |<------------+
+ * +---+ _______ |
+ * | | | |
+ * +---| delay |---+
+ * |_______|
+ * /|\
+ * |
+ * +---------------+ +------------------+
+ * | Delay control |<-----| modulation speed |
+ * +---------------+ +------------------+
+ *
+ *
+ * The delay is controled by a sine or triangle modulation.
+ *
+ * Usage:
+ * phaser gain-in gain-out delay decay speed [ -s | -t ]
+ *
+ * Where:
+ * gain-in, decay : 0.0 ... 1.0 volume
+ * gain-out : 0.0 ... volume
+ * delay : 0.0 ... 5.0 msec
+ * speed : 0.1 ... 2.0 Hz modulation
+ * -s : modulation by sine (default)
+ * -t : modulation by triangle
+ *
+ * Note:
+ * when decay is close to 1.0, the samples may begin clipping or the output
+ * can saturate!
+ *
+ * Hint:
+ * in-gain < ( 1 - decay * decay )
+ * 1 / out-gain > gain-in / ( 1 - decay )
+ *
+*/
+
+/*
+ * Sound Tools phaser effect file.
+ */
+
+#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
+#include <math.h>
+#include <string.h>
+#include "st.h"
+
+#define MOD_SINE 0
+#define MOD_TRIANGLE 1
+
+/* Private data for SKEL file */
+typedef struct phaserstuff {
+ int modulation;
+ int counter;
+ int phase;
+ double *phaserbuf;
+ float in_gain, out_gain;
+ float delay, decay;
+ float speed;
+ long length;
+ int *lookup_tab;
+ long maxsamples, fade_out;
+} *phaser_t;
+
+/* Private data for SKEL file */
+
+LONG phaser_clip24(l)
+LONG l;
+{
+ if (l >= ((LONG)1 << 24))
+ return ((LONG)1 << 24) - 1;
+ else if (l <= -((LONG)1 << 24))
+ return -((LONG)1 << 24) + 1;
+ else
+ return l;
+}
+
+/* This was very painful. We need a sine library. */
+
+void phaser_sine(buf, len, depth)
+int *buf;
+long len;
+long depth;
+{
+ long i;
+ double val;
+
+ for (i = 0; i < len; i++) {
+ val = sin((double)i/(double)len * 2.0 * M_PI);
+ buf[i] = (int) ((1.0 + val) * depth / 2.0);
+ }
+}
+
+void phaser_triangle(buf, len, depth)
+int *buf;
+long len;
+long depth;
+{
+ long i;
+ double val;
+
+ for (i = 0; i < len / 2; i++) {
+ val = i * 2.0 / len;
+ buf[i] = (int) (val * depth);
+ }
+ for (i = len / 2; i < len ; i++) {
+ val = (len - i) * 2.0 / len;
+ buf[i] = (int) (val * depth);
+ }
+}
+
+/*
+ * Process options
+ */
+void phaser_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ phaser_t phaser = (phaser_t) effp->priv;
+
+ if (!((n == 5) || (n == 6)))
+ fail("Usage: phaser gain-in gain-out delay decay speed [ -s | -t ]");
+
+ sscanf(argv[0], "%f", &phaser->in_gain);
+ sscanf(argv[1], "%f", &phaser->out_gain);
+ sscanf(argv[2], "%f", &phaser->delay);
+ sscanf(argv[3], "%f", &phaser->decay);
+ sscanf(argv[4], "%f", &phaser->speed);
+ phaser->modulation = MOD_SINE;
+ if ( n == 6 ) {
+ if ( !strcmp(argv[5], "-s"))
+ phaser->modulation = MOD_SINE;
+ else if ( ! strcmp(argv[5], "-t"))
+ phaser->modulation = MOD_TRIANGLE;
+ else
+ fail("Usage: phaser gain-in gain-out delay decay speed [ -s | -t ]");
+ }
+}
+
+/*
+ * Prepare for processing.
+ */
+void phaser_start(effp)
+eff_t effp;
+{
+ phaser_t phaser = (phaser_t) effp->priv;
+ int i;
+
+ phaser->maxsamples = phaser->delay * effp->ininfo.rate / 1000.0;
+
+ if ( phaser->delay < 0.0 )
+ fail("phaser: delay must be positive!\n");
+ if ( phaser->delay > 5.0 )
+ fail("phaser: delay must be less than 5.0 msec!\n");
+ if ( phaser->speed < 0.1 )
+ fail("phaser: speed must be more than 0.1 Hz!\n");
+ if ( phaser->speed > 2.0 )
+ fail("phaser: speed must be less than 2.0 Hz!\n");
+ if ( phaser->decay < 0.0 )
+ fail("phaser: decay must be positive!\n" );
+ if ( phaser->decay >= 1.0 )
+ fail("phaser: decay must be less that 1.0!\n" );
+ /* Be nice and check the hint with warning, if... */
+ if ( phaser->in_gain > ( 1.0 - phaser->decay * phaser->decay ) )
+ warn("phaser: warning >>> gain-in can cause saturation or clipping of output <<<");
+ if ( phaser->in_gain / ( 1.0 - phaser->decay ) > 1.0 / phaser->out_gain )
+ warn("phaser: warning >>> gain-out can cause saturation or clipping of output <<<");
+
+ phaser->length = effp->ininfo.rate / phaser->speed;
+
+ if (! (phaser->phaserbuf =
+ (double *) malloc(sizeof (double) * phaser->maxsamples)))
+ fail("phaser: Cannot malloc %d bytes!\n",
+ sizeof(double) * phaser->maxsamples);
+ for ( i = 0; i < phaser->maxsamples; i++ )
+ phaser->phaserbuf[i] = 0.0;
+ if (! (phaser->lookup_tab =
+ (int *) malloc(sizeof (int) * phaser->length)))
+ fail("phaser: Cannot malloc %d bytes!\n",
+ sizeof(int) * phaser->length);
+
+ if ( phaser->modulation == MOD_SINE )
+ phaser_sine(phaser->lookup_tab, phaser->length,
+ phaser->maxsamples - 1);
+ else
+ phaser_triangle(phaser->lookup_tab, phaser->length,
+ phaser->maxsamples - 1);
+ phaser->counter = 0;
+ phaser->phase = 0;
+ phaser->fade_out = phaser->maxsamples;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void phaser_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ phaser_t phaser = (phaser_t) effp->priv;
+ int len, done;
+
+ double d_in, d_out;
+ LONG out;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* Store delays as 24-bit signed longs */
+ d_in = (double) *ibuf++ / 256;
+ /* Compute output first */
+ d_in = d_in * phaser->in_gain;
+ d_in += phaser->phaserbuf[(phaser->maxsamples +
+ phaser->counter - phaser->lookup_tab[phaser->phase]) %
+ phaser->maxsamples] * phaser->decay * -1.0;
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_in * phaser->out_gain;
+ out = phaser_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delay and input */
+ phaser->phaserbuf[phaser->counter] = d_in;
+ phaser->counter =
+ ( phaser->counter + 1 ) % phaser->maxsamples;
+ phaser->phase = ( phaser->phase + 1 ) % phaser->length;
+ }
+ /* processed all samples */
+}
+
+/*
+ * Drain out reverb lines.
+ */
+void phaser_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ phaser_t phaser = (phaser_t) effp->priv;
+ int done;
+
+ double d_in, d_out;
+ LONG out;
+
+ done = 0;
+ while ( ( done < *osamp ) && ( done < phaser->fade_out ) ) {
+ d_in = 0;
+ d_out = 0;
+ /* Compute output first */
+ d_in += phaser->phaserbuf[(phaser->maxsamples +
+ phaser->counter - phaser->lookup_tab[phaser->phase]) %
+ phaser->maxsamples] * phaser->decay * -1.0;
+ /* Adjust the output volume and size to 24 bit */
+ d_out = d_in * phaser->out_gain;
+ out = phaser_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ /* Mix decay of delay and input */
+ phaser->phaserbuf[phaser->counter] = d_in;
+ phaser->counter =
+ ( phaser->counter + 1 ) % phaser->maxsamples;
+ phaser->phase = ( phaser->phase + 1 ) % phaser->length;
+ done++;
+ phaser->fade_out--;
+ }
+ /* samples playd, it remains */
+ *osamp = done;
+}
+
+/*
+ * Clean up phaser effect.
+ */
+void phaser_stop(effp)
+eff_t effp;
+{
+ phaser_t phaser = (phaser_t) effp->priv;
+
+ free((char *) phaser->phaserbuf);
+ phaser->phaserbuf = (double *) -1; /* guaranteed core dump */
+ free((char *) phaser->lookup_tab);
+ phaser->lookup_tab = (int *) -1; /* guaranteed core dump */
+}
+
--- /dev/null
+++ b/src/polyphas.c
@@ -1,0 +1,648 @@
+
+/*
+ * July 14, 1998
+ * Copyright 1998 K. Bradley, Carnegie Mellon University
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools rate change effect file.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "st.h"
+
+typedef struct _list {
+ int number;
+ float *data_buffer;
+ struct _list *next;
+} List;
+
+typedef struct polyphase {
+
+ unsigned long lcmrate; /* least common multiple of rates */
+ unsigned long inskip, outskip; /* LCM increments for I & O rates */
+ unsigned long total;
+ unsigned long intot, outtot; /* total samples in terms of LCM rate */
+ long lastsamp;
+
+ float **filt_array;
+ float **past_hist;
+ float *input_buffer;
+ int *filt_len;
+
+ List *l1, *l2;
+
+} *poly_t;
+
+/*
+ * Process options
+ */
+
+/* Options:
+
+ -w <nut / ham> : window type
+ -width <short / long> : window width
+ short = 128 samples
+ long = 1024 samples
+ <num> num: explicit number
+
+ -cutoff <float> : frequency cutoff for base bandwidth.
+ Default = 0.95 = 95%
+*/
+
+static int win_type = 0;
+static int win_width = 1024;
+static float cutoff = 0.95;
+
+void poly_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ /* 0: nuttall
+ 1: hamming */
+ win_type = 0;
+
+ /* width: short = 128
+ long = 1024 (default) */
+ win_width = 1024;
+
+ /* cutoff: frequency cutoff of base bandwidth in percentage. */
+ cutoff = 0.95;
+
+ while(n >= 2) {
+
+ /* Window type check */
+ if(!strcmp(argv[0], "-w")) {
+ if(!strcmp(argv[1], "ham"))
+ win_type = 1;
+ if(!strcmp(argv[1], "nut"))
+ win_type = 0;
+
+ argv += 2;
+ n -= 2;
+ continue;
+ }
+
+ /* Window width check */
+ if(!strcmp(argv[0], "-width")) {
+ if(!strcmp(argv[1], "short"))
+ win_width = 128;
+ else if(!strcmp(argv[1], "long"))
+ win_width = 1024;
+ else
+ win_width = atoi(argv[1]);
+
+ argv += 2;
+ n -= 2;
+ continue;
+ }
+
+ /* Cutoff frequency check */
+ if(!strcmp(argv[0], "-cutoff")) {
+ cutoff = atof(argv[1]);
+ argv += 2;
+ n -= 2;
+ continue;
+ }
+
+ fail("Polyphase: unknown argument (%s %s)!", argv[0], argv[1]);
+ }
+}
+
+/*
+ * Prepare processing.
+ */
+
+static int primes[] = {
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
+ 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
+ 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
+ 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433,
+ 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
+ 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
+ 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
+ 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997
+};
+
+#ifndef max
+#define max(x,y) ((x > y) ? x : y)
+#endif
+
+List *prime(number)
+int number;
+{
+ int j;
+ List *element = NULL;
+
+ if(number == 1)
+ return NULL;
+
+ for(j=167;j>= 0;j--) {
+ if(number % primes[j] == 0) {
+ element = (List *) malloc(sizeof(List));
+ element->number = primes[j];
+ element->data_buffer = NULL;
+ element->next = prime(number / primes[j]);
+ break;
+ }
+ }
+
+ if(element == NULL) {
+ fail("Number %d too large of a prime.\n",number);
+ }
+
+ return element;
+}
+
+List *prime_inv(number)
+int number;
+{
+ int j;
+ List *element = NULL;
+
+ if(number == 1)
+ return NULL;
+
+ for(j=0;j<168;j++) {
+ if(number % primes[j] == 0) {
+ element = (List *) malloc(sizeof(List));
+ element->number = primes[j];
+ element->data_buffer = NULL;
+ element->next = prime_inv(number / primes[j]);
+ break;
+ }
+ }
+
+ if(element == NULL) {
+ fail("Number %d too large of a prime.\n",number);
+ }
+
+ return element;
+}
+
+#ifndef PI
+#define PI 3.14159265358979
+#endif
+
+/* Calculate a Nuttall window of a given length.
+ Buffer must already be allocated to appropriate size.
+ */
+
+void nuttall(buffer, length)
+float *buffer;
+int length;
+{
+ int j;
+ double N;
+ double N1;
+
+ if(buffer == NULL || length < 0)
+ fail("Illegal buffer %p or length %d to nuttall.\n", buffer, length);
+
+ /* Initial variable setups. */
+ N = (double) length - 1.0;
+ N1 = N / 2.0;
+
+ for(j = 0; j < length; j++) {
+ buffer[j] = 0.36335819 +
+ 0.4891775 * cos(2*PI*1*(j - N1) / N) +
+ 0.1365995 * cos(2*PI*2*(j - N1) / N) +
+ 0.0106411 * cos(2*PI*3*(j - N1) / N);
+ }
+}
+/* Calculate a Hamming window of given length.
+ Buffer must already be allocated to appropriate size.
+*/
+
+void hamming(buffer, length)
+float *buffer;
+int length;
+{
+ int j;
+
+ if(buffer == NULL || length < 0)
+ fail("Illegal buffer %p or length %d to hamming.\n",buffer,length);
+
+ for(j=0;j<length;j++)
+ buffer[j] = 0.5 - 0.46 * cos(2*PI*j/(length-1));
+}
+
+/* Calculate the sinc function properly */
+
+float sinc(value)
+float value;
+{
+ return(fabs(value) < 1E-50 ? 1.0 : sin(value) / value);
+}
+
+/* Design a low-pass FIR filter using window technique.
+ Length of filter is in length, cutoff frequency in cutoff.
+ 0 < cutoff <= 1.0 (normalized frequency)
+
+ buffer must already be allocated.
+*/
+void fir_design(buffer, length, cutoff)
+float *buffer;
+int length;
+float cutoff;
+{
+ int j;
+ float sum;
+ float *ham_win;
+
+ if(buffer == NULL || length < 0 || cutoff < 0 || cutoff > PI)
+ fail("Illegal buffer %p, length %d, or cutoff %f.\n",buffer,length,cutoff);
+
+ /* Design Hamming window: 43 dB cutoff */
+ ham_win = (float *)malloc(sizeof(float) * length);
+
+ /* Use the user-option of window type */
+ if(win_type == 0)
+ nuttall(ham_win, length);
+ else
+ hamming(ham_win,length);
+
+ /* Design filter: windowed sinc function */
+ sum = 0.0;
+ for(j=0;j<length;j++) {
+ buffer[j] = sinc(PI*cutoff*(j-length/2)) * ham_win[j] / (2*cutoff);
+ sum += buffer[j];
+ }
+
+ /* Normalize buffer to have gain of 1.0: prevent roundoff error */
+ for(j=0;j<length;j++)
+ buffer[j] /= sum;
+
+ free((void *) ham_win);
+}
+
+
+void poly_start(effp)
+eff_t effp;
+{
+ poly_t rate = (poly_t) effp->priv;
+ List *t, *t2;
+ int num_l1, num_l2;
+ int j,k;
+ float f_cutoff;
+
+ extern long lcm();
+
+ rate->lcmrate = lcm((long)effp->ininfo.rate, (long)effp->outinfo.rate);
+
+ /* Cursory check for LCM overflow.
+ * If both rate are below 65k, there should be no problem.
+ * 16 bits x 16 bits = 32 bits, which we can handle.
+ */
+
+ rate->inskip = rate->lcmrate / effp->ininfo.rate;
+ rate->outskip = rate->lcmrate / effp->outinfo.rate;
+
+ /* Find the prime factors of inskip and outskip */
+ rate->l1 = prime(rate->inskip);
+
+ /* If we're going up, order things backwards. */
+ if(effp->ininfo.rate < effp->outinfo.rate)
+ rate->l2 = prime_inv(rate->outskip);
+ else
+ rate->l2 = prime(rate->outskip);
+
+ /* Find how many factors there were */
+ if(rate->l1 == NULL)
+ num_l1 = 0;
+ else
+ for(num_l1=0, t = rate->l1; t != NULL; num_l1++, t=t->next);
+
+ if(rate->l2 == NULL)
+ num_l2 = 0;
+ else
+ for(num_l2=0, t = rate->l2; t != NULL; num_l2++, t=t->next);
+
+ k = 0;
+ t = rate->l1;
+
+ /* Compact the lists to be less than 10 */
+ while(k < num_l1 - 1) {
+ if(t->number * t->next->number < 10) {
+ t->number = t->number * t->next->number;
+ t2 = t->next;
+ t->next = t->next->next;
+ t2->next = NULL;
+ free((void *) t2);
+ num_l1--;
+ } else {
+ k++;
+ t = t->next;
+ }
+ }
+
+ k = 0;
+ t = rate->l2;
+
+ while(k < num_l2 - 1) {
+ if(t->number * t->next->number < 10) {
+ t->number = t->number * t->next->number;
+ t2 = t->next;
+ t->next = t->next->next;
+ t2->next = NULL;
+ free((void *) t2);
+ num_l2--;
+ } else {
+ k++;
+ t = t->next;
+ }
+ }
+
+ /* l1 and l2 are now lists of the prime factors compacted,
+ meaning that they're the lists of up/down sampling we need
+ */
+
+ /* Stretch them to be the same length by padding with 1 (no-op) */
+ if(num_l1 < num_l2) {
+ t = rate->l1;
+
+ if(t == NULL) {
+ rate->l1 = (List *)malloc(sizeof(List));
+ rate->l1->next = NULL;
+ rate->l1->number = 1;
+ rate->l1->data_buffer = NULL;
+ t = rate->l1;
+ num_l1++;
+ }
+
+ while(t->next != NULL)
+ t = t->next;
+
+ for(k=0;k<num_l2-num_l1;k++) {
+ t->next = (List *) malloc(sizeof(List));
+ t->next->number = 1;
+ t->next->data_buffer = NULL;
+ t = t->next;
+ }
+
+ t->next = NULL;
+ num_l1 = num_l2;
+ } else {
+ t = rate->l2;
+
+ if(t == NULL) {
+ rate->l2 = (List *)malloc(sizeof(List));
+ rate->l2->next = NULL;
+ rate->l2->number = 1;
+ rate->l2->data_buffer = NULL;
+ t = rate->l2;
+ num_l2++;
+ }
+
+ /*
+ while(t->next != NULL)
+ t = t->next;
+ */
+
+ for(k=0;k<num_l1-num_l2;k++) {
+ t = rate->l2;
+ rate->l2 = (List *) malloc(sizeof(List));
+ rate->l2->number = 1;
+ rate->l2->data_buffer = NULL;
+ rate->l2->next = t;
+ }
+
+ /* t->next = NULL; */
+ num_l2 = num_l1;
+ }
+
+ /* l1 and l2 are now the same size. */
+ rate->total = num_l1;
+
+ report("Poly: input rate %d, output rate %d. %d stages.",effp->ininfo.rate, effp->outinfo.rate,num_l1);
+ report("Poly: window: %s size: %d cutoff: %f.", (win_type == 0) ? ("nut") : ("ham"), win_width, cutoff);
+
+ for(k=0, t=rate->l1, t2=rate->l2;k<num_l1;k++,t=t->next,t2=t2->next)
+ report("Poly: stage %d: Up by %d, down by %d.",k+1,t->number,t2->number);
+
+ /* We'll have an array of filters and past history */
+ rate->filt_array = (float **) malloc(sizeof(float *) * num_l1);
+ rate->past_hist = (float **) malloc(sizeof(float *) * num_l1);
+ rate->filt_len = (int *) malloc(sizeof(int) * num_l1);
+
+ for(k = 0, t = rate->l1, t2 = rate->l2; k < num_l1; k++) {
+
+ rate->filt_len[k] = max(2 * 10 * max(t->number,t2->number), win_width);
+ rate->filt_array[k] = (float *) malloc(sizeof(float) * rate->filt_len[k]);
+ rate->past_hist[k] = (float *) malloc(sizeof(float) * rate->filt_len[k]);
+
+ t->data_buffer = (float *) malloc(sizeof(float) * 1024 * rate->inskip);
+
+ for(j = 0; j < rate->filt_len[k]; j++)
+ rate->past_hist[k][j] = 0.0;
+
+ f_cutoff = (t->number > t2->number) ?
+ (float) t->number : (float) t2->number;
+
+ fir_design(rate->filt_array[k], rate->filt_len[k]-1, cutoff / f_cutoff);
+
+ t = t->next;
+ t2 = t2->next;
+ }
+
+ rate->input_buffer = (float *) malloc(sizeof(float) * 2048);
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+static float *h;
+static int M, L, N;
+
+void polyphase_init(coef, num_coef, up_rate, down_rate)
+float *coef;
+int num_coef;
+int up_rate;
+int down_rate;
+{
+ h = coef;
+ M = down_rate;
+ L = up_rate;
+ N = num_coef;
+}
+
+void polyphase(input, output, past, num_samples_input)
+float *input;
+float *output;
+float *past;
+int num_samples_input;
+{
+ int num_output;
+ int m,n;
+ float sum;
+ float inp;
+ int base;
+ int h_base;
+
+ num_output = num_samples_input * L / M;
+
+ for(m=0;m<num_output;m++) {
+ sum = 0.0;
+ base = (int) (m*M/L);
+ h_base = (m*M) % L;
+
+ for(n=0;n<N / L;n++) {
+ if(base - n < 0)
+ inp = past[base - n + N];
+ else
+ inp = input[base - n];
+
+ sum += h[n*L + h_base] * inp;
+ }
+
+ output[m] = sum * L * 0.95;
+ }
+}
+
+void poly_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+long *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ poly_t rate = (poly_t) effp->priv;
+ float *temp_buf, *temp_buf2;
+ int j,k;
+ List *t1, *t2;
+ int in_size, out_size;
+
+ /* Sanity check: how much can we tolerate? */
+ in_size = *isamp;
+ out_size = in_size * rate->inskip / rate->outskip;
+ if(out_size > *osamp) {
+ in_size = *osamp * rate->outskip / rate->inskip;
+ *isamp = in_size;
+ }
+
+ /* Check to see if we're really draining */
+ if(ibuf != NULL) {
+ for(k=0;k<*isamp;k++)
+ rate->input_buffer[k] = (float) (ibuf[k] >> 16);
+ } else {
+ for(k=0;k<*isamp;k++)
+ rate->input_buffer[k] = 0.0;
+ }
+
+ temp_buf = rate->input_buffer;
+
+ t1 = rate->l1;
+ t2 = rate->l2;
+
+ for(k=0;k<rate->total;k++,t1=t1->next,t2=t2->next) {
+
+ polyphase_init(rate->filt_array[k], rate->filt_len[k],
+ t1->number,t2->number);
+
+ out_size = (in_size) * t1->number / t2->number;
+
+ temp_buf2 = t1->data_buffer;
+
+ polyphase(temp_buf, temp_buf2, rate->past_hist[k], in_size);
+
+ for(j = 0; j < rate->filt_len[k]; j++)
+ rate->past_hist[k][j] = temp_buf[j+in_size - rate->filt_len[k]];
+
+ in_size = out_size;
+
+ temp_buf = temp_buf2;
+ }
+
+ if(out_size > *osamp)
+ out_size = *osamp;
+
+ *osamp = out_size;
+
+ if(ibuf != NULL) {
+ for(k=0;k < out_size;k++)
+ obuf[k] = ((int) temp_buf[k]) << 16;
+ } else {
+
+ /* Wait for all-zero samples to come through.
+ Should happen eventually with all-zero
+ input */
+ int found = 0;
+
+ for(k=0; k < out_size; k++) {
+ obuf[k] = ((int) temp_buf[k] << 16);
+ if(obuf[k] != 0)
+ found = 1;
+ }
+ if(!found)
+ *osamp = 0;
+ }
+}
+
+/*
+ * Process tail of input samples.
+ */
+void poly_drain(effp, obuf, osamp)
+eff_t effp;
+long *obuf;
+long *osamp;
+{
+ long in_size = 1024;
+
+ /* Call "flow" with NULL input. */
+ poly_flow(effp, NULL, obuf, &in_size, osamp);
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void poly_stop(effp)
+eff_t effp;
+{
+ List *t, *t2;
+ poly_t rate = (poly_t) effp->priv;
+ int k;
+
+ /* Free lists */
+ for(t = rate->l1; t != NULL; ) {
+ t2 = t->next;
+ t->next = NULL;
+ if(t->data_buffer != NULL)
+ free((void *) t->data_buffer);
+ free((void *) t);
+ t = t2;
+ }
+
+ for(t = rate->l2; t != NULL; ) {
+ t2 = t->next;
+ t->next = NULL;
+ if(t->data_buffer != NULL)
+ free((void *) t->data_buffer);
+ free((void *) t);
+ t = t2;
+ }
+
+ for(k = 0; k < rate->total;k++) {
+ free((void *) rate->past_hist[k]);
+ free((void *) rate->filt_array[k]);
+ }
+
+ free((void *) rate->past_hist);
+ free((void *) rate->filt_array);
+ free((void *) rate->filt_len);
+}
+
--- /dev/null
+++ b/src/rate.c
@@ -1,0 +1,319 @@
+#ifndef USE_OLD_RATE
+/*
+ * August 21, 1998
+ * Copyright 1998 Fabrice Bellard.
+ *
+ * [Rewrote completly the code of Lance Norskog And Sundry
+ * Contributors with a more efficient algorithm.]
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools rate change effect file.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/*
+ * Linear Interpolation.
+ *
+ * The use of fractional increment allows us to use no buffer. It
+ * avoid the problems at the end of the buffer we had with the old
+ * method which stored a possibly big buffer of size
+ * lcm(in_rate,out_rate).
+ *
+ * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
+ * the input & output frequencies are equal, a delay of one sample is
+ * introduced
+ *
+ * 1 << FRAC_BITS evaluating to zero in several places. Changed with
+ * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
+ */
+
+#define FRAC_BITS 16
+
+/* Private data */
+typedef struct ratestuff {
+ u_l opos_frac; /* fractional position of the output stream in input stream unit */
+ u_l opos;
+
+ u_l opos_inc_frac; /* fractional position increment in the output stream */
+ u_l opos_inc;
+
+ u_l ipos; /* position in the input stream (integer) */
+
+ LONG ilast; /* last sample in the input stream */
+} *rate_t;
+
+/*
+ * Process options
+ */
+void rate_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Rate effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ */
+void rate_start(effp)
+eff_t effp;
+{
+ rate_t rate = (rate_t) effp->priv;
+ u_l incr;
+
+ rate->opos_frac=0;
+ rate->opos=0;
+
+ /* increment */
+ incr=(u_l)((double)effp->ininfo.rate / (double)effp->outinfo.rate *
+ (double) ((unsigned long) 1 << FRAC_BITS));
+
+ rate->opos_inc_frac = incr & (((unsigned long) 1 << FRAC_BITS)-1);
+ rate->opos_inc = incr >> FRAC_BITS;
+
+ rate->ipos=0;
+
+ rate->ilast = 0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void rate_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ rate_t rate = (rate_t) effp->priv;
+ LONG *istart,*iend;
+ LONG *ostart,*oend;
+ LONG ilast,icur,out;
+ u_l tmp;
+ double t;
+
+ ilast=rate->ilast;
+
+ istart = ibuf;
+ iend = ibuf + *isamp;
+
+ ostart = obuf;
+ oend = obuf + *osamp;
+
+ while (obuf < oend) {
+
+ /* read as many input samples so that ipos > opos */
+
+ while (rate->ipos <= rate->opos) {
+ if (ibuf >= iend) goto the_end;
+ ilast = *ibuf++;
+ rate->ipos++;
+ }
+ icur = *ibuf;
+
+ /* interpolate */
+ t=(double) rate->opos_frac / ((unsigned long) 1 << FRAC_BITS);
+ out = (double) ilast * (1.0 - t) + (double) icur * t;
+
+ /* output sample & increment position */
+
+ *obuf++=(LONG) out;
+
+ tmp = rate->opos_frac + rate->opos_inc_frac;
+ rate->opos = rate->opos + rate->opos_inc + (tmp >> FRAC_BITS);
+ rate->opos_frac = tmp & (((unsigned long) 1 << FRAC_BITS)-1);
+ }
+the_end:
+ *isamp = ibuf - istart;
+ *osamp = obuf - ostart;
+ rate->ilast = ilast;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void rate_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+#else /* USE_OLD_RATE */
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools rate change effect file.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/*
+ * Least Common Multiple Linear Interpolation
+ *
+ * Find least common multiple of the two sample rates.
+ * Construct the signal at the LCM by interpolating successive
+ * input samples as straight lines. Pull output samples from
+ * this line at output rate.
+ *
+ * Of course, actually calculate only the output samples.
+ *
+ * LCM must be 32 bits or less. Two prime number sample rates
+ * between 32768 and 65535 will yield a 32-bit LCM, so this is
+ * stretching it.
+ */
+
+/*
+ * Algorithm:
+ *
+ * Generate a master sample clock from the LCM of the two rates.
+ * Interpolate linearly along it. Count up input and output skips.
+ *
+ * Input: |inskip | | | | |
+ *
+ *
+ *
+ * LCM: | | | | | | | | | | |
+ *
+ *
+ *
+ * Output: | outskip | | |
+ *
+ *
+ */
+
+
+/* Private data for Lerp via LCM file */
+typedef struct ratestuff {
+ u_l lcmrate; /* least common multiple of rates */
+ u_l inskip, outskip; /* LCM increments for I & O rates */
+ u_l total;
+ u_l intot, outtot; /* total samples in LCM basis */
+ LONG lastsamp; /* history */
+} *rate_t;
+
+/*
+ * Process options
+ */
+void rate_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Rate effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ */
+void rate_start(effp)
+eff_t effp;
+{
+ rate_t rate = (rate_t) effp->priv;
+ IMPORT LONG lcm();
+
+ rate->lcmrate = lcm((LONG)effp->ininfo.rate, (LONG)effp->outinfo.rate);
+ /* Cursory check for LCM overflow.
+ * If both rate are below 65k, there should be no problem.
+ * 16 bits x 16 bits = 32 bits, which we can handle.
+ */
+ rate->inskip = rate->lcmrate / effp->ininfo.rate;
+ rate->outskip = rate->lcmrate / effp->outinfo.rate;
+ rate->total = rate->intot = rate->outtot = 0;
+ rate->lastsamp = 0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void rate_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ rate_t rate = (rate_t) effp->priv;
+ int len, done;
+ LONG *istart = ibuf;
+ LONG last;
+
+ done = 0;
+ if (rate->total == 0) {
+ /* Emit first sample. We know the fence posts meet. */
+ *obuf = *ibuf++;
+ rate->lastsamp = *obuf++ / 65536L;
+ done = 1;
+ rate->total = 1;
+ /* advance to second output */
+ rate->outtot += rate->outskip;
+ /* advance input range to span next output */
+ while ((rate->intot + rate->inskip) <= rate->outtot){
+ last = *ibuf++ / 65536L;
+ rate->intot += rate->inskip;
+ }
+ }
+
+ /* start normal flow-through operation */
+ last = rate->lastsamp;
+
+ /* number of output samples the input can feed */
+ len = (*isamp * rate->inskip) / rate->outskip;
+ if (len > *osamp)
+ len = *osamp;
+ for(; done < len; done++) {
+ *obuf = last;
+ *obuf += ((float)((*ibuf / 65536L) - last)* ((float)rate->outtot -
+ rate->intot))/rate->inskip;
+ *obuf *= 65536L;
+ obuf++;
+ /* advance to next output */
+ rate->outtot += rate->outskip;
+ /* advance input range to span next output */
+ while ((rate->intot + rate->inskip) <= rate->outtot){
+ last = *ibuf++ / 65536L;
+ rate->intot += rate->inskip;
+ if (ibuf - istart == *isamp)
+ goto out;
+ }
+ /* long samples with high LCM's overrun counters! */
+ if (rate->outtot == rate->intot)
+ rate->outtot = rate->intot = 0;
+ }
+out:
+ *isamp = ibuf - istart;
+ *osamp = len;
+ rate->lastsamp = last;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void rate_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+#endif /* USE_OLD_RATE */
--- /dev/null
+++ b/src/raw.c
@@ -1,0 +1,361 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools raw format file.
+ *
+ * Includes .ub, .uw, .sb, .sw, and .ul formats at end
+ */
+
+/*
+ * Notes: most of the headerless formats set their handlers to raw
+ * in their startread/write routines.
+ *
+ */
+
+#include "st.h"
+#include "libst.h"
+
+void rawstartread(ft)
+ft_t ft;
+{
+}
+
+void rawstartwrite(ft)
+ft_t ft;
+{
+}
+
+/* Read raw file data, and convert it to */
+/* the sox internal signed long format. */
+
+LONG rawread(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ register LONG datum;
+ int done = 0;
+
+ switch(ft->info.size) {
+ case BYTE:
+ switch(ft->info.style)
+ {
+ case SIGN2:
+ while(done < nsamp) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp))
+ return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ return done;
+ case UNSIGNED:
+ while(done < nsamp) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp))
+ return done;
+ /* Convert to signed */
+ datum ^= 128;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ return done;
+ case ULAW:
+ while(done < nsamp) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp))
+ return done;
+ datum = st_ulaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case ALAW:
+ while(done < nsamp) {
+ datum = getc(ft->fp);
+ if (feof(ft->fp))
+ return done;
+ datum = st_Alaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+
+ return done;
+ }
+ break;
+ case WORD:
+ switch(ft->info.style)
+ {
+ case SIGN2:
+ while(done < nsamp) {
+ datum = rshort(ft);
+ if (feof(ft->fp))
+ return done;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case UNSIGNED:
+ while(done < nsamp) {
+ datum = rshort(ft);
+ if (feof(ft->fp))
+ return done;
+ /* Convert to signed */
+ datum ^= 0x8000;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case ULAW:
+ fail("No U-Law support for shorts");
+ return done;
+ case ALAW:
+ fail("No A-Law support for shorts");
+ return done;
+ }
+ break;
+ case FLOAT:
+ while(done < nsamp) {
+ datum = dovolume? volume * rfloat(ft)
+ : rfloat(ft);
+ if (feof(ft->fp))
+ return done;
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ default:
+ fail("Drop through in rawread!");
+ }
+ fail("Sorry, don't have code to read %s, %s",
+ styles[ft->info.style], sizes[ft->info.size]);
+ return(0);
+}
+
+/* Convert the sox internal signed long format */
+/* to the raw file data, and write it. */
+
+void
+rawwrite(ft, buf, nsamp)
+ft_t ft;
+LONG *buf, nsamp;
+{
+ register int datum;
+ int done = 0;
+
+ switch(ft->info.size) {
+ case BYTE:
+ switch(ft->info.style)
+ {
+ case SIGN2:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 24);
+ putc(datum, ft->fp);
+ done++;
+ }
+ return;
+ case UNSIGNED:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 24);
+ /* Convert to unsigned */
+ datum ^= 128;
+ putc(datum, ft->fp);
+ done++;
+ }
+ return;
+ case ULAW:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 16);
+ /* round up to 12 bits of data */
+ datum += 0x8; /* + 0b1000 */
+ datum = st_linear_to_ulaw(datum);
+ putc(datum, ft->fp);
+ done++;
+ }
+ return;
+ case ALAW:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 16);
+ /* round up to 12 bits of data */
+ datum += 0x8; /* + 0b1000 */
+ datum = st_linear_to_Alaw(datum);
+ putc(datum, ft->fp);
+ done++;
+ }
+ return;
+ }
+ break;
+ case WORD:
+ switch(ft->info.style)
+ {
+ case SIGN2:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 16);
+ wshort(ft, datum);
+ done++;
+ }
+ return;
+ case UNSIGNED:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 16);
+ /* Convert to unsigned */
+ datum ^= 0x8000;
+ wshort(ft, datum);
+ done++;
+ }
+ return;
+ case ULAW:
+fail("No U-Law support for shorts (try -b option ?)");
+ return;
+ case ALAW:
+fail("No A-Law support for shorts (try -b option ?)");
+ return;
+ }
+ break;
+ case FLOAT:
+ while(done < nsamp) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 16);
+ wfloat(ft, (double) datum);
+ done++;
+ }
+ return;
+ default:
+ fail("Drop through in rawwrite!");
+ }
+ fail("Sorry, don't have code to write %s, %s",
+ styles[ft->info.style], sizes[ft->info.size]);
+}
+
+/*
+* Set parameters to the fixed parameters known for this format,
+* and change format to raw format.
+*/
+
+void rawdefaults();
+
+/* Signed byte */
+void sbstartread(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = SIGN2;
+ rawdefaults(ft);
+}
+
+void sbstartwrite(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = SIGN2;
+ rawdefaults(ft);
+}
+
+void ubstartread(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ rawdefaults(ft);
+}
+
+void ubstartwrite(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = UNSIGNED;
+ rawdefaults(ft);
+}
+
+void uwstartread(ft)
+ft_t ft;
+{
+ ft->info.size = WORD;
+ ft->info.style = UNSIGNED;
+ rawdefaults(ft);
+}
+
+void uwstartwrite(ft)
+ft_t ft;
+{
+ ft->info.size = WORD;
+ ft->info.style = UNSIGNED;
+ rawdefaults(ft);
+}
+
+void swstartread(ft)
+ft_t ft;
+{
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ rawdefaults(ft);
+}
+
+void swstartwrite(ft)
+ft_t ft;
+{
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ rawdefaults(ft);
+}
+
+void ulstartread(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = ULAW;
+ rawdefaults(ft);
+}
+
+void ulstartwrite(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = ULAW;
+ rawdefaults(ft);
+}
+
+void alstartread(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = ALAW;
+ rawdefaults(ft);
+}
+
+void alstartwrite(ft)
+ft_t ft;
+{
+ ft->info.size = BYTE;
+ ft->info.style = ALAW;
+ rawdefaults(ft);
+}
+
+void rawdefaults(ft)
+ft_t ft;
+{
+ if (ft->info.rate == 0)
+ ft->info.rate = 8000;
+ if (ft->info.channels == -1)
+ ft->info.channels = 1;
+}
+
+
--- /dev/null
+++ b/src/resampl.h
@@ -1,0 +1,75 @@
+
+/*
+ * FILE: resample.h
+ * BY: Julius Smith (at CCRMA, Stanford U)
+ * C BY: translated from SAIL to C by Christopher Lee Fraley
+ * (cf0v@andrew.cmu.edu)
+ * DATE: 7-JUN-88
+ * VERS: 2.0 (17-JUN-88, 3:00pm)
+ */
+
+#define MAXNWING 5122
+#define MAXFACTOR 4 /* Maximum Factor without output buff overflow */
+
+
+
+/* Conversion constants */
+#define Nhc 8
+#define Na 7
+#define Np (Nhc+Na)
+#define Npc (1<<Nhc)
+#define Amask ((1<<Na)-1)
+#define Pmask ((1<<Np)-1)
+#define Nh 16
+#define Nb 16
+#define Nhxn 14
+#define Nhg (Nh-Nhxn)
+#define NLpScl 13
+
+/* Description of constants:
+ *
+ * Npc - is the number of look-up values available for the lowpass filter
+ * between the beginning of its impulse response and the "cutoff time"
+ * of the filter. The cutoff time is defined as the reciprocal of the
+ * lowpass-filter cut off frequence in Hz. For example, if the
+ * lowpass filter were a sinc function, Npc would be the index of the
+ * impulse-response lookup-table corresponding to the first zero-
+ * crossing of the sinc function. (The inverse first zero-crossing
+ * time of a sinc function equals its nominal cutoff frequency in Hz.)
+ * Npc must be a power of 2 due to the details of the current
+ * implementation. The default value of 512 is sufficiently high that
+ * using linear interpolation to fill in between the table entries
+ * gives approximately 16-bit accuracy in filter coefficients.
+ *
+ * Nhc - is log base 2 of Npc.
+ *
+ * Na - is the number of bits devoted to linear interpolation of the
+ * filter coefficients.
+ *
+ * Np - is Na + Nhc, the number of bits to the right of the binary point
+ * in the integer "time" variable. To the left of the point, it indexes
+ * the input array (X), and to the right, it is interpreted as a number
+ * between 0 and 1 sample of the input X. Np must be less than 16 in
+ * this implementation.
+ *
+ * Nh - is the number of bits in the filter coefficients. The sum of Nh and
+ * the number of bits in the input data (typically 16) cannot exceed 32.
+ * Thus Nh should be 16. The largest filter coefficient should nearly
+ * fill 16 bits (32767).
+ *
+ * Nb - is the number of bits in the input data. The sum of Nb and Nh cannot
+ * exceed 32.
+ *
+ * Nhxn - is the number of bits to right shift after multiplying each input
+ * sample times a filter coefficient. It can be as great as Nh and as
+ * small as 0. Nhxn = Nh-2 gives 2 guard bits in the multiply-add
+ * accumulation. If Nhxn=0, the accumulation will soon overflow 32 bits.
+ *
+ * Nhg - is the number of guard bits in mpy-add accumulation (equal to Nh-Nhxn).
+ *
+ * NLpScl - is the number of bits allocated to the unity-gain normalization
+ * factor. The output of the lowpass filter is multiplied by LpScl and
+ * then right-shifted NLpScl bits. To avoid overflow, we must have
+ * Nb+Nhg+NLpScl < 32.
+ */
+
--- /dev/null
+++ b/src/resample.c
@@ -1,0 +1,680 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools rate change effect file.
+ * Spiffy rate changer using Smith & Wesson Bandwidth-Limited Interpolation.
+ * The algorithm is described in "Bandlimited Interpolation -
+ * Introduction and Algorithm" by Julian O. Smith III.
+ * Available on ccrma-ftp.stanford.edu as
+ * pub/BandlimitedInterpolation.eps.Z or similar.
+ *
+ * The latest stand alone version of this algorithm can be found
+ * at ftp://ccrma-ftp.stanford.edu/pub/NeXT/
+ * under the name of resample-version.number.tar.Z
+ *
+ * NOTE: This source badly needs to be updated to reflect the latest
+ * version of the above software! Someone please perform this and
+ * send patches to cbagwell@sprynet.com.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include "st.h"
+
+/* resample includes */
+#include "resdefs.h"
+#include "resampl.h"
+
+#define IBUFFSIZE 1024 /* Input buffer size */
+#define OBUFFSIZE (IBUFFSIZE*MAXFACTOR+2) /* Calc'd out buffer size */
+
+/* Private data for Lerp via LCM file */
+typedef struct resamplestuff {
+ double Factor; /* Factor = Fout/Fin sample rates */
+ double rolloff; /* roll-off frequency */
+ double beta; /* passband/stopband tuning magic */
+ short InterpFilt; /* TRUE means interpolate filter coeffs */
+ UHWORD Oskip; /* number of bogus output samples at start */
+ UHWORD LpScl, Nmult, Nwing;
+ HWORD *Imp; /* impulse [MAXNWING] Filter coefficients */
+ HWORD *ImpD; /* [MAXNWING] ImpD[n] = Imp[n+1]-Imp[n] */
+ /* for resample main loop */
+ UWORD Time; /* Current time/pos in input sample */
+ UHWORD Xp, Xoff, Xread;
+ HWORD *X, *Y; /* I/O buffers */
+} *resample_t;
+
+int makeFilter(P6(HWORD Imp[],
+ HWORD ImpD[],
+ UHWORD *LpScl,
+ UHWORD Nwing,
+ double Froll,
+ double Beta));
+HWORD SrcUp(P10(HWORD X[],
+ HWORD Y[],
+ double Factor,
+ UWORD *Time,
+ UHWORD Nx,
+ UHWORD Nwing,
+ UHWORD LpScl,
+ HWORD Imp[],
+ HWORD ImpD[],
+ BOOL Interp));
+HWORD SrcUD(P10(HWORD X[],
+ HWORD Y[],
+ double Factor,
+ UWORD *Time,
+ UHWORD Nx,
+ UHWORD Nwing,
+ UHWORD LpScl,
+ HWORD Imp[],
+ HWORD ImpD[],
+ BOOL Interp));
+IWORD FilterUp(P7(HWORD Imp[],
+ HWORD ImpD[],
+ UHWORD Nwing,
+ BOOL Interp,
+ HWORD *Xp,
+ HWORD Ph,
+ HWORD Inc));
+IWORD FilterUD(P8(HWORD Imp[],
+ HWORD ImpD[],
+ UHWORD Nwing,
+ BOOL Interp,
+ HWORD *Xp,
+ HWORD Ph,
+ HWORD Inc,
+ UHWORD dhb));
+
+/*
+ * Process options
+ */
+void resample_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ resample_t resample = (resample_t) effp->priv;
+
+ resample->rolloff = 0.85;
+ resample->beta = 2.120;
+
+ /* I don't know why this fails! */
+ if ((n >= 1) && !sscanf(argv[0], "%lf", &resample->rolloff))
+ fail("Usage: resample [ rolloff [ beta ] ]");
+ else if ((resample->rolloff < 0.01) || (resample->rolloff > 1.0))
+ fail("resample: rolloff factor (%f) no good, should be 0.01<x<1.0",
+ resample->rolloff);
+ if ((n >= 2) && !sscanf(argv[1], "%lf", &resample->beta))
+ fail("Usage: resample [ rolloff [ beta ] ]");
+ else if (resample->beta < 1.0)
+ fail("resample: beta factor (%f) no good, should be >= 1.0",
+ resample->beta);
+ /*
+ fprintf(stderr, "resample opts: %f, %f\n",
+ resample->rolloff, resample->beta);
+ */
+}
+
+/*
+ * Prepare processing.
+ */
+void resample_start(effp)
+eff_t effp;
+{
+ resample_t resample = (resample_t) effp->priv;
+ int i;
+
+ if ((LONG)effp->ininfo.rate > (LONG)effp->outinfo.rate)
+ resample->rolloff = ((double)effp->outinfo.rate /
+ (double)effp->ininfo.rate) * 0.97; /* empirical */
+ else
+ resample->rolloff = 0.85;
+
+ resample->InterpFilt = 1; /* interpolate filter: slower */
+ resample->Factor =
+ (double)effp->outinfo.rate / (double)effp->ininfo.rate;
+
+ /* Check for illegal constants */
+ if (Np >= 16)
+ fail("Error: Np>=16");
+ if (Nb+Nhg+NLpScl >= 32)
+ fail("Error: Nb+Nhg+NLpScl>=32");
+ if (Nh+Nb > 32)
+ fail("Error: Nh+Nb>32");
+
+
+ resample->Imp = (HWORD *) malloc(sizeof(HWORD) * MAXNWING);
+ resample->ImpD = (HWORD *) malloc(sizeof(HWORD) * MAXNWING);
+ resample->X = (HWORD *) malloc(sizeof(HWORD) * IBUFFSIZE);
+ resample->Y = (HWORD *) malloc(sizeof(HWORD) * OBUFFSIZE);
+
+ /* upsampling requires smaller Nmults */
+ for(resample->Nmult = 37; resample->Nmult > 1; resample->Nmult -= 2) {
+ /* # of filter coeffs in right wing */
+ resample->Nwing = Npc*(resample->Nmult+1)/2;
+ /* This prevents just missing last coeff */
+ /* for integer conversion factors */
+ resample->Nwing += Npc/2 + 1;
+
+ /* returns error # or 0 for success */
+ if (makeFilter(resample->Imp, resample->ImpD,
+ &resample->LpScl, resample->Nwing,
+ resample->rolloff, resample->beta))
+ continue;
+ else
+ break;
+
+ }
+
+ if(resample->Nmult == 1)
+ fail("resample: Unable to make filter\n");
+
+ if (resample->Factor < 1)
+ resample->LpScl = resample->LpScl*resample->Factor + 0.5;
+ /* Calc reach of LP filter wing & give some creeping room */
+ resample->Xoff = ((resample->Nmult+1)/2.0) *
+ MAX(1.0,1.0/resample->Factor) + 10;
+ if (IBUFFSIZE < 2*resample->Xoff) /* Check input buffer size */
+ fail("IBUFFSIZE (or Factor) is too small");
+
+ /* Current "now"-sample pointer for input */
+ resample->Xp = resample->Xoff;
+ /* Position in input array to read into */
+ resample->Xread = resample->Xoff;
+ /* Current-time pointer for converter */
+ resample->Time = (resample->Xoff<<Np);
+
+ /* Set sample drop at beginning */
+ resample->Oskip = resample->Xread * resample->Factor;
+
+ /* Need Xoff zeros at begining of sample */
+ for (i=0; i<resample->Xoff; i++)
+ resample->X[i] = 0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void resample_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+LONG *isamp, *osamp;
+{
+ resample_t resample = (resample_t) effp->priv;
+ LONG i, last, creep, Nout, Nx;
+ UHWORD Nproc;
+
+ /* constrain amount we actually process */
+ Nproc = IBUFFSIZE - resample->Xp;
+ if (Nproc * resample->Factor >= OBUFFSIZE)
+ Nproc = OBUFFSIZE / resample->Factor;
+ if (Nproc * resample->Factor >= *osamp)
+ Nproc = *osamp / resample->Factor;
+
+ Nx = Nproc - resample->Xread;
+ if (Nx <= 0)
+ fail("Nx negative: %d", Nx);
+ if (Nx > *isamp) {
+ Nx = *isamp;
+ }
+ for(i = resample->Xread; i < Nx + resample->Xread ; i++)
+ resample->X[i] = RIGHT(*ibuf++ + 0x8000, 16);
+ last = i;
+ Nproc = last - (resample->Xoff * 2);
+ for(; i < last + resample->Xoff ; i++)
+ resample->X[i] = 0;
+
+ /* If we're draining out a buffer tail,
+ * just do it next time or in drain.
+ */
+ if ((Nx == *isamp) && (Nx <= resample->Xoff)) {
+ /* fill in starting here next time */
+ resample->Xread = last;
+ /* leave *isamp alone, we consumed it */
+ *osamp = 0;
+ return;
+ }
+
+
+ /* SrcUp() is faster if we can use it */
+ if (resample->Factor > 1) /* Resample stuff in input buffer */
+ Nout = SrcUp(resample->X, resample->Y,
+ resample->Factor, &resample->Time, Nproc,
+ resample->Nwing, resample->LpScl,
+ resample->Imp, resample->ImpD,
+ resample->InterpFilt);
+ else
+ Nout = SrcUD(resample->X, resample->Y,
+ resample->Factor, &resample->Time, Nproc,
+ resample->Nwing, resample->LpScl,
+ resample->Imp, resample->ImpD,
+ resample->InterpFilt);
+
+ /* Move converter Nproc samples back in time */
+ resample->Time -= (Nproc<<Np);
+ /* Advance by number of samples processed */
+ resample->Xp += Nproc;
+ /* Calc time accumulation in Time */
+ creep = (resample->Time>>Np) - resample->Xoff;
+ if (creep)
+ {
+ resample->Time -= (creep<<Np); /* Remove time accumulation */
+ resample->Xp += creep; /* and add it to read pointer */
+ }
+
+ /* Copy back portion of input signal that must be re-used */
+ for (i=0; i<last - resample->Xp + resample->Xoff; i++)
+ resample->X[i] = resample->X[i + resample->Xp - resample->Xoff];
+
+ /* Pos in input buff to read new data into */
+ resample->Xread = i;
+ resample->Xp = resample->Xoff;
+
+ /* copy to output buffer, zero-filling beginning */
+ /* zero-fill to preserve length and loop points */
+ for(i = 0; i < resample->Oskip; i++) {
+ *obuf++ = 0;
+ }
+ for(i = resample->Oskip; i < Nout + resample->Oskip; i++) {
+ *obuf++ = LEFT(resample->Y[i], 16);
+ }
+
+ *isamp = Nx;
+ *osamp = Nout;
+
+ resample->Oskip = 0;
+}
+
+/*
+ * Process tail of input samples.
+ */
+void resample_drain(effp, obuf, osamp)
+eff_t effp;
+ULONG *obuf;
+ULONG *osamp;
+{
+ resample_t resample = (resample_t) effp->priv;
+ LONG i, Nout;
+ UHWORD Nx;
+
+ Nx = resample->Xread - resample->Xoff;
+ if (Nx <= resample->Xoff * 2) {
+ /* zero-fill end */
+ for(i = 0; i < resample->Xoff; i++)
+ *obuf++ = 0;
+ *osamp = resample->Xoff;
+ return;
+ }
+
+ if (Nx * resample->Factor >= *osamp)
+ fail("resample_drain: Overran output buffer!\n");
+
+ /* fill out end with zeros */
+ for(i = 0; i < resample->Xoff; i++)
+ resample->X[i + resample->Xread] = 0;
+ /* SrcUp() is faster if we can use it */
+ if (resample->Factor >= 1) /* Resample stuff in input buffer */
+ Nout = SrcUp(resample->X, resample->Y,
+ resample->Factor, &resample->Time, Nx,
+ resample->Nwing, resample->LpScl,
+ resample->Imp, resample->ImpD,
+ resample->InterpFilt);
+ else
+ Nout = SrcUD(resample->X, resample->Y,
+ resample->Factor, &resample->Time, Nx,
+ resample->Nwing, resample->LpScl,
+ resample->Imp, resample->ImpD,
+ resample->InterpFilt);
+
+ for(i = resample->Oskip; i < Nout; i++) {
+ *obuf++ = LEFT(resample->Y[i], 16);
+ }
+ *osamp = Nout - resample->Oskip;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void resample_stop(effp)
+eff_t effp;
+{
+ resample_t resample = (resample_t) effp->priv;
+
+ free(resample->Imp);
+ free(resample->ImpD);
+ free(resample->X);
+ free(resample->Y);
+}
+
+/* From resample:filters.c */
+
+/* Sampling rate up-conversion only subroutine;
+ * Slightly faster than down-conversion;
+ */
+HWORD SrcUp(X, Y, Factor, Time, Nx, Nwing, LpScl, Imp, ImpD, Interp)
+HWORD X[], Y[];
+double Factor;
+UWORD *Time;
+UHWORD Nx, Nwing, LpScl;
+HWORD Imp[], ImpD[];
+BOOL Interp;
+{
+ HWORD *Xp, *Ystart;
+ IWORD v;
+
+ double dt; /* Step through input signal */
+ UWORD dtb; /* Fixed-point version of Dt */
+ UWORD endTime; /* When Time reaches EndTime, return to user */
+
+ dt = 1.0/Factor; /* Output sampling period */
+ dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */
+
+ Ystart = Y;
+ endTime = *Time + (1<<Np)*(IWORD)Nx;
+ while (*Time < endTime)
+ {
+ Xp = &X[*Time>>Np]; /* Ptr to current input sample */
+ v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask),
+ -1); /* Perform left-wing inner product */
+ v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1, (HWORD)((-*Time)&Pmask),
+ 1); /* Perform right-wing inner product */
+ v >>= Nhg; /* Make guard bits */
+ v *= LpScl; /* Normalize for unity filter gain */
+ *Y++ = v>>NLpScl; /* Deposit output */
+ *Time += dtb; /* Move to next sample by time increment */
+ }
+ return (Y - Ystart); /* Return the number of output samples */
+}
+
+
+/* Sampling rate conversion subroutine */
+
+HWORD SrcUD(X, Y, Factor, Time, Nx, Nwing, LpScl, Imp, ImpD, Interp)
+HWORD X[], Y[];
+double Factor;
+UWORD *Time;
+UHWORD Nx, Nwing, LpScl;
+HWORD Imp[], ImpD[];
+BOOL Interp;
+{
+ HWORD *Xp, *Ystart;
+ IWORD v;
+
+ double dh; /* Step through filter impulse response */
+ double dt; /* Step through input signal */
+ UWORD endTime; /* When Time reaches EndTime, return to user */
+ UWORD dhb, dtb; /* Fixed-point versions of Dh,Dt */
+
+ dt = 1.0/Factor; /* Output sampling period */
+ dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */
+
+ dh = MIN(Npc, Factor*Npc); /* Filter sampling period */
+ dhb = dh*(1<<Na) + 0.5; /* Fixed-point representation */
+
+ Ystart = Y;
+ endTime = *Time + (1<<Np)*(IWORD)Nx;
+ while (*Time < endTime)
+ {
+ Xp = &X[*Time>>Np]; /* Ptr to current input sample */
+ v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask),
+ -1, dhb); /* Perform left-wing inner product */
+ v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, (HWORD)((-*Time)&Pmask),
+ 1, dhb); /* Perform right-wing inner product */
+ v >>= Nhg; /* Make guard bits */
+ v *= LpScl; /* Normalize for unity filter gain */
+ *Y++ = v>>NLpScl; /* Deposit output */
+ *Time += dtb; /* Move to next sample by time increment */
+ }
+ return (Y - Ystart); /* Return the number of output samples */
+}
+
+void LpFilter();
+
+int makeFilter(Imp, ImpD, LpScl, Nwing, Froll, Beta)
+HWORD Imp[], ImpD[];
+UHWORD *LpScl, Nwing;
+double Froll, Beta;
+{
+ double DCgain, Scl, Maxh;
+ double *ImpR;
+ HWORD Dh;
+ LONG i, temp;
+
+ if (Nwing > MAXNWING) /* Check for valid parameters */
+ return(1);
+ if ((Froll<=0) || (Froll>1))
+ return(2);
+ if (Beta < 1)
+ return(3);
+
+ ImpR = (double *) malloc(sizeof(double) * MAXNWING);
+ LpFilter(ImpR, (int)Nwing, Froll, Beta, Npc); /* Design a Kaiser-window */
+ /* Sinc low-pass filter */
+
+ /* Compute the DC gain of the lowpass filter, and its maximum coefficient
+ * magnitude. Scale the coefficients so that the maximum coeffiecient just
+ * fits in Nh-bit fixed-point, and compute LpScl as the NLpScl-bit (signed)
+ * scale factor which when multiplied by the output of the lowpass filter
+ * gives unity gain. */
+ DCgain = 0;
+ Dh = Npc; /* Filter sampling period for factors>=1 */
+ for (i=Dh; i<Nwing; i+=Dh)
+ DCgain += ImpR[i];
+ DCgain = 2*DCgain + ImpR[0]; /* DC gain of real coefficients */
+
+ for (Maxh=i=0; i<Nwing; i++)
+ Maxh = MAX(Maxh, fabs(ImpR[i]));
+
+ Scl = ((1<<(Nh-1))-1)/Maxh; /* Map largest coeff to 16-bit maximum */
+ temp = fabs((1<<(NLpScl+Nh))/(DCgain*Scl));
+ if (temp >= (1L<<16)) {
+ free(ImpR);
+ return(4); /* Filter scale factor overflows UHWORD */
+ }
+ *LpScl = temp;
+
+ /* Scale filter coefficients for Nh bits and convert to integer */
+ if (ImpR[0] < 0) /* Need pos 1st value for LpScl storage */
+ Scl = -Scl;
+ for (i=0; i<Nwing; i++) /* Scale them */
+ ImpR[i] *= Scl;
+ for (i=0; i<Nwing; i++) /* Round them */
+ Imp[i] = ImpR[i] + 0.5;
+
+ /* ImpD makes linear interpolation of the filter coefficients faster */
+ for (i=0; i<Nwing-1; i++)
+ ImpD[i] = Imp[i+1] - Imp[i];
+ ImpD[Nwing-1] = - Imp[Nwing-1]; /* Last coeff. not interpolated */
+
+ free(ImpR);
+ return(0);
+}
+
+
+
+/* LpFilter()
+ *
+ * reference: "Digital Filters, 2nd edition"
+ * R.W. Hamming, pp. 178-179
+ *
+ * Izero() computes the 0th order modified bessel function of the first kind.
+ * (Needed to compute Kaiser window).
+ *
+ * LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with
+ * the following characteristics:
+ *
+ * c[] = array in which to store computed coeffs
+ * frq = roll-off frequency of filter
+ * N = Half the window length in number of coeffs
+ * Beta = parameter of Kaiser window
+ * Num = number of coeffs before 1/frq
+ *
+ * Beta trades the rejection of the lowpass filter against the transition
+ * width from passband to stopband. Larger Beta means a slower
+ * transition and greater stopband rejection. See Rabiner and Gold
+ * (Theory and Application of DSP) under Kaiser windows for more about
+ * Beta. The following table from Rabiner and Gold gives some feel
+ * for the effect of Beta:
+ *
+ * All ripples in dB, width of transition band = D*N where N = window length
+ *
+ * BETA D PB RIP SB RIP
+ * 2.120 1.50 +-0.27 -30
+ * 3.384 2.23 0.0864 -40
+ * 4.538 2.93 0.0274 -50
+ * 5.658 3.62 0.00868 -60
+ * 6.764 4.32 0.00275 -70
+ * 7.865 5.0 0.000868 -80
+ * 8.960 5.7 0.000275 -90
+ * 10.056 6.4 0.000087 -100
+ */
+
+
+#define IzeroEPSILON 1E-21 /* Max error acceptable in Izero */
+
+double Izero(x)
+double x;
+{
+ double sum, u, halfx, temp;
+ LONG n;
+
+ sum = u = n = 1;
+ halfx = x/2.0;
+ do {
+ temp = halfx/(double)n;
+ n += 1;
+ temp *= temp;
+ u *= temp;
+ sum += u;
+ } while (u >= IzeroEPSILON*sum);
+ return(sum);
+}
+
+
+void LpFilter(c,N,frq,Beta,Num)
+double c[], frq, Beta;
+int N, Num;
+{
+ double IBeta, temp;
+ int i;
+
+ /* Calculate filter coeffs: */
+ c[0] = 2.0*frq;
+ for (i=1; i<N; i++)
+ {
+ temp = PI*(double)i/(double)Num;
+ c[i] = sin(2.0*temp*frq)/temp;
+ }
+
+ /* Calculate and Apply Kaiser window to filter coeffs: */
+ IBeta = 1.0/Izero(Beta);
+ for (i=1; i<N; i++)
+ {
+ temp = (double)i / ((double)N * (double)1.0);
+ c[i] *= Izero(Beta*sqrt(1.0-temp*temp)) * IBeta;
+ }
+}
+
+
+
+
+IWORD FilterUp(Imp, ImpD, Nwing, Interp, Xp, Ph, Inc)
+HWORD Imp[], ImpD[];
+UHWORD Nwing;
+BOOL Interp;
+HWORD *Xp, Ph, Inc;
+{
+ HWORD a=0, *Hp, *Hdp=0, *End;
+ IWORD v, t;
+
+ v=0;
+ Hp = &Imp[Ph>>Na];
+ End = &Imp[Nwing];
+ if (Interp)
+ {
+ Hdp = &ImpD[Ph>>Na];
+ a = Ph & Amask;
+ }
+ /* Possible Bug: Hdp and a are not initialized if Interp == 0 */
+ if (Inc == 1) /* If doing right wing... */
+ { /* ...drop extra coeff, so when Ph is */
+ End--; /* 0.5, we don't do too many mult's */
+ if (Ph == 0) /* If the phase is zero... */
+ { /* ...then we've already skipped the */
+ Hp += Npc; /* first sample, so we must also */
+ Hdp += Npc; /* skip ahead in Imp[] and ImpD[] */
+ }
+ }
+ while (Hp < End)
+ {
+ t = *Hp; /* Get filter coeff */
+ if (Interp)
+ {
+ t += (((IWORD)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
+ Hdp += Npc; /* Filter coeff differences step */
+ }
+ t *= *Xp; /* Mult coeff by input sample */
+ if (t & (1<<(Nhxn-1))) /* Round, if needed */
+ t += (1<<(Nhxn-1));
+ t >>= Nhxn; /* Leave some guard bits, but come back some */
+ v += t; /* The filter output */
+ Hp += Npc; /* Filter coeff step */
+ Xp += Inc; /* Input signal step. NO CHECK ON ARRAY BOUNDS */
+ }
+ return(v);
+}
+
+
+IWORD FilterUD(Imp, ImpD, Nwing, Interp, Xp, Ph, Inc, dhb)
+HWORD Imp[], ImpD[];
+UHWORD Nwing;
+BOOL Interp;
+HWORD *Xp, Ph, Inc;
+UHWORD dhb;
+{
+ HWORD a, *Hp, *Hdp, *End;
+ IWORD v, t;
+ UWORD Ho;
+
+ v=0;
+ Ho = (Ph*(UWORD)dhb)>>Np;
+ End = &Imp[Nwing];
+ if (Inc == 1) /* If doing right wing... */
+ { /* ...drop extra coeff, so when Ph is */
+ End--; /* 0.5, we don't do too many mult's */
+ if (Ph == 0) /* If the phase is zero... */
+ Ho += dhb; /* ...then we've already skipped the */
+ } /* first sample, so we must also */
+ /* skip ahead in Imp[] and ImpD[] */
+ while ((Hp = &Imp[Ho>>Na]) < End)
+ {
+ t = *Hp; /* Get IR sample */
+ if (Interp)
+ {
+ Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table */
+ a = Ho & Amask; /* a is logically between 0 and 1 */
+ t += (((IWORD)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
+ }
+ t *= *Xp; /* Mult coeff by input sample */
+ if (t & (1<<(Nhxn-1))) /* Round, if needed */
+ t += (1<<(Nhxn-1));
+ t >>= Nhxn; /* Leave some guard bits, but come back some */
+ v += t; /* The filter output */
+ Ho += dhb; /* IR step */
+ Xp += Inc; /* Input signal step. NO CHECK ON ARRAY BOUNDS */
+ }
+ return(v);
+}
+
--- /dev/null
+++ b/src/reverb.c
@@ -1,0 +1,291 @@
+
+/*
+ * August 24, 1998
+ * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+** Echo effect. based on:
+**
+** echoplex.c - echo generator
+**
+** Copyright (C) 1989 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation. This software is provided "as is" without express or
+** implied warranty.
+*/
+
+
+/*
+ * Changes to old "echo.c" now called "reverb.c":
+ *
+ * The effect name changes from "echo" to "reverb" (see Guitar FX FAQ) for
+ * the difference in its defintion.
+ * The idea of the echoplexer is modified and enhanceb by an automatic
+ * setting of each decay for realistic reverb.
+ * Some bugs are fixed concerning malloc and fade-outs.
+ * Added an output volume (gain-out) avoiding saturation or clipping.
+ *
+ *
+ * Reverb effect for dsp.
+ *
+ * Flow diagram scheme for n delays ( 1 <= n <= MAXREVERB )
+ *
+ * * gain-in +---+ * gain-out
+ * ibuff ----------->| |------------------------------------> obuff
+ * | | * decay 1
+ * | |<------------------------+
+ * | + | * decay 2 |
+ * | |<--------------------+ |
+ * | | * decay n | |
+ * | |<----------------+ | |
+ * +---+ | | |
+ * | _________ | | |
+ * | | | | | |
+ * +---->| delay n |---+ | |
+ * . |_________| | |
+ * . | |
+ * . _________ | |
+ * | | | | |
+ * +---->| delay 2 |-------+ |
+ * | |_________| |
+ * | |
+ * | _________ |
+ * | | | |
+ * +---->| delay 1 |-----------+
+ * |_________|
+ *
+ *
+ *
+ * Usage:
+ * reverb gain-out reverb-time delay-1 [ delay-2 ... delay-n ]
+ *
+ * Where:
+ * gain-out : 0.0 ... volume
+ * reverb-time : > 0.0 msec
+ * delay-1 ... delay-n : > 0.0 msec
+ *
+ * Note:
+ * gain-in is automatically adjusted avoiding saturation and clipping of
+ * the output. decay-1 to decay-n are computed such that at reverb-time
+ * the input will be 60 dB of the original input for the given delay-1
+ * to delay-n. delay-1 to delay-n specify the time when the first bounce
+ * of the input will appear. A proper setting for delay-1 to delay-n
+ * depends on the choosen reverb-time (see hint).
+ *
+ * Hint:
+ * a realstic reverb effect can be obtained using for a given reverb-time "t"
+ * delays in the range of "t/2 ... t/4". Each delay should not be an integer
+ * of any other.
+ *
+*/
+
+/*
+ * Sound Tools reverb effect file.
+ */
+
+#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
+#include <math.h>
+#include "st.h"
+
+#define REVERB_FADE_THRESH 10
+#define DELAY_BUFSIZ ( 50L * MAXRATE )
+#define MAXREVERBS 8
+
+/* Private data for SKEL file */
+typedef struct reverbstuff {
+ int counter;
+ int numdelays;
+ float *reverbbuf;
+ float in_gain, out_gain, time;
+ float delay[MAXREVERBS], decay[MAXREVERBS];
+ long samples[MAXREVERBS], maxsamples;
+ LONG pl, ppl, pppl;
+} *reverb_t;
+
+/* Private data for SKEL file */
+
+#ifndef abs
+#define abs(a) ((a) >= 0 ? (a) : -(a))
+#endif
+
+LONG reverb_clip24(l)
+LONG l;
+{
+ if (l >= ((LONG)1 << 24))
+ return ((LONG)1 << 24) - 1;
+ else if (l <= -((LONG)1 << 24))
+ return -((LONG)1 << 24) + 1;
+ else
+ return l;
+}
+
+/*
+ * Process options
+ */
+void reverb_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ reverb_t reverb = (reverb_t) effp->priv;
+ int i;
+
+ reverb->numdelays = 0;
+ reverb->maxsamples = 0;
+
+ if ( n < 3 )
+ fail("Usage: reverb gain-out reverb-time delay [ delay ... ]");
+
+ if ( n - 2 > MAXREVERBS )
+ fail("reverb: to many dalays, use less than %i delays",
+ MAXREVERBS);
+
+ i = 0;
+ sscanf(argv[i++], "%f", &reverb->out_gain);
+ sscanf(argv[i++], "%f", &reverb->time);
+ while (i < n) {
+ /* Linux bug and it's cleaner. */
+ sscanf(argv[i++], "%f", &reverb->delay[reverb->numdelays]);
+ reverb->numdelays++;
+ }
+}
+
+/*
+ * Prepare for processing.
+ */
+void reverb_start(effp)
+eff_t effp;
+{
+ reverb_t reverb = (reverb_t) effp->priv;
+ int i;
+
+ reverb->in_gain = 1.0;
+
+ if ( reverb->out_gain < 0.0 )
+ fail("reverb: gain-out must be positive");
+ if ( reverb->out_gain > 1.0 )
+ warn("reverb: warnig >>> gain-out can cause saturation of output <<<");
+ if ( reverb->time < 0.0 )
+ fail("reverb: reverb-time must be positive");
+ for(i = 0; i < reverb->numdelays; i++) {
+ reverb->samples[i] = reverb->delay[i] * effp->ininfo.rate / 1000.0;
+ if ( reverb->samples[i] < 1 )
+ fail("reverb: delay must be positive!\n");
+ if ( reverb->samples[i] > DELAY_BUFSIZ )
+ fail("reverb: delay must be less than %g seconds!\n",
+ DELAY_BUFSIZ / (float) effp->ininfo.rate );
+ /* Compute a realistic decay */
+ reverb->decay[i] = (float) pow(10.0,(-3.0 * reverb->delay[i] / reverb->time));
+ if ( reverb->samples[i] > reverb->maxsamples )
+ reverb->maxsamples = reverb->samples[i];
+ }
+ if (! (reverb->reverbbuf = (float *) malloc(sizeof (float) * reverb->maxsamples)))
+ fail("reverb: Cannot malloc %d bytes!\n",
+ sizeof(float) * reverb->maxsamples);
+ for ( i = 0; i < reverb->maxsamples; ++i )
+ reverb->reverbbuf[i] = 0.0;
+ reverb->pppl = reverb->ppl = reverb->pl = 0x7fffff; /* fade-outs */
+ reverb->counter = 0;
+ /* Compute the input volume carefully */
+ for ( i = 0; i < reverb->numdelays; i++ )
+ reverb->in_gain *=
+ ( 1.0 - ( reverb->decay[i] * reverb->decay[i] ));
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void reverb_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ reverb_t reverb = (reverb_t) effp->priv;
+ int len, done;
+ int i, j;
+
+ float d_in, d_out;
+ LONG out;
+
+ i = reverb->counter;
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* Store delays as 24-bit signed longs */
+ d_in = (float) *ibuf++ / 256;
+ d_in = d_in * reverb->in_gain;
+ /* Mix decay of delay and input as output */
+ for ( j = 0; j < reverb->numdelays; j++ )
+ d_in +=
+reverb->reverbbuf[(i + reverb->maxsamples - reverb->samples[j]) % reverb->maxsamples] * reverb->decay[j];
+ d_out = d_in * reverb->out_gain;
+ out = reverb_clip24((LONG) d_out);
+ *obuf++ = out * 256;
+ reverb->reverbbuf[i] = d_in;
+ i++; /* XXX need a % maxsamples here ? */
+ i %= reverb->maxsamples;
+ }
+ reverb->counter = i;
+ /* processed all samples */
+}
+
+/*
+ * Drain out reverb lines.
+ */
+void reverb_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ reverb_t reverb = (reverb_t) effp->priv;
+ float d_in, d_out;
+ LONG out, l;
+ int i, j, done;
+
+ i = reverb->counter;
+ done = 0;
+ /* drain out delay samples */
+ do {
+ d_in = 0;
+ d_out = 0;
+ for ( j = 0; j < reverb->numdelays; ++j )
+ d_in +=
+reverb->reverbbuf[(i + reverb->maxsamples - reverb->samples[j]) % reverb->maxsamples] * reverb->decay[j];
+ d_out = d_in * reverb->out_gain;
+ out = reverb_clip24((LONG) d_out);
+ obuf[done++] = out * 256;
+ reverb->reverbbuf[i] = d_in;
+ l = reverb_clip24((LONG) d_in);
+ reverb->pppl = reverb->ppl;
+ reverb->ppl = reverb->pl;
+ reverb->pl = l;
+ i++; /* need a % maxsamples here ? */
+ i %= reverb->maxsamples;
+ } while((done < *osamp) &&
+ ((abs(reverb->pl) + abs(reverb->ppl) + abs(reverb->pppl)) > REVERB_FADE_THRESH));
+ reverb->counter = i;
+ *osamp = done;
+}
+
+/*
+ * Clean up reverb effect.
+ */
+void reverb_stop(effp)
+eff_t effp;
+{
+ reverb_t reverb = (reverb_t) effp->priv;
+
+ free((char *) reverb->reverbbuf);
+ reverb->reverbbuf = (float *) -1; /* guaranteed core dump */
+}
+
--- /dev/null
+++ b/src/reverse.c
@@ -1,0 +1,137 @@
+
+/*
+ * June 1, 1992
+ * Copyright 1992 Guido van Rossum And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * "reverse" effect, uses a temporary file created by tmpfile().
+ */
+
+#include <math.h>
+#include "st.h"
+
+IMPORT FILE *tmpfile();
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+/* Private data */
+typedef struct reversestuff {
+ FILE *fp;
+ LONG pos;
+ int phase;
+} *reverse_t;
+
+#define WRITING 0
+#define READING 1
+
+/*
+ * Process options: none in our case.
+ */
+
+void reverse_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Reverse effect takes no options.");
+}
+
+/*
+ * Prepare processing: open temporary file.
+ */
+
+void reverse_start(effp)
+eff_t effp;
+{
+ reverse_t reverse = (reverse_t) effp->priv;
+ reverse->fp = tmpfile();
+ if (reverse->fp == NULL)
+ fail("Reverse effect can't create temporary file\n");
+ reverse->phase = WRITING;
+}
+
+/*
+ * Effect flow: a degenerate case: write input samples on temporary file,
+ * don't generate any output samples.
+ */
+
+void reverse_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ reverse_t reverse = (reverse_t) effp->priv;
+
+ if (reverse->phase != WRITING)
+ fail("Internal error: reverse_flow called in wrong phase");
+ if (fwrite((char *)ibuf, sizeof(LONG), *isamp, reverse->fp)
+ != *isamp)
+ fail("Reverse effect write error on temporary file\n");
+ *osamp = 0;
+}
+
+/*
+ * Effect drain: generate the actual samples in reverse order.
+ */
+
+void reverse_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+int *osamp;
+{
+ reverse_t reverse = (reverse_t) effp->priv;
+ int len, nbytes;
+ register int i, j;
+ LONG temp;
+
+ if (reverse->phase == WRITING) {
+ fflush(reverse->fp);
+ fseek(reverse->fp, 0L, SEEK_END);
+ reverse->pos = ftell(reverse->fp);
+ if (reverse->pos % sizeof(LONG) != 0)
+ fail("Reverse effect finds odd temporary file\n");
+ reverse->phase = READING;
+ }
+ len = *osamp;
+ nbytes = len * sizeof(LONG);
+ if (reverse->pos < nbytes) {
+ nbytes = reverse->pos;
+ len = nbytes / sizeof(LONG);
+ }
+ reverse->pos -= nbytes;
+ fseek(reverse->fp, reverse->pos, SEEK_SET);
+ if (fread((char *)obuf, sizeof(LONG), len, reverse->fp) != len)
+ fail("Reverse effect read error from temporary file\n");
+ for (i = 0, j = len-1; i < j; i++, j--) {
+ temp = obuf[i];
+ obuf[i] = obuf[j];
+ obuf[j] = temp;
+ }
+ *osamp = len;
+}
+
+/*
+ * Close and unlink the temporary file.
+ */
+void reverse_stop(effp)
+eff_t effp;
+{
+ reverse_t reverse = (reverse_t) effp->priv;
+
+ fclose(reverse->fp);
+}
+
--- /dev/null
+++ b/src/sf.c
@@ -1,0 +1,213 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools IRCAM SoundFile format handler.
+ *
+ * Derived from: Sound Tools skeleton handler file.
+ */
+
+#define IRCAM
+#include "st.h"
+#ifdef IRCAM
+#include "sfircam.h"
+#ifndef SIZEOF_BSD_HEADER
+#define SIZEOF_BSD_HEADER 1024
+#endif
+#else
+#include "sfheader.h"
+#endif
+#include <string.h>
+#include <stdlib.h>
+
+/* Private data for SF file */
+typedef struct sfstuff {
+ struct sfinfo info;
+} *sf_t;
+
+/*
+ * Read the codes from the sound file, allocate space for the comment and
+ * assign its pointer to the comment field in ft.
+ */
+void readcodes(ft, sfhead)
+ft_t ft;
+SFHEADER *sfhead;
+{
+ char *commentbuf = NULL, *sfcharp, *newline;
+ short bsize, finished = 0;
+ SFCODE *sfcodep;
+
+ sfcodep = (SFCODE *) &sfcodes(sfhead);
+ do {
+ sfcharp = (char *) sfcodep + sizeof(SFCODE);
+ if (ft->swap) {
+ sfcodep->bsize = swapl(sfcodep->bsize);
+ sfcodep->code = swapl(sfcodep->code);
+ }
+ bsize = sfcodep->bsize - sizeof(SFCODE);
+ switch(sfcodep->code) {
+ case SF_END:
+ finished = 1;
+ break;
+ case SF_COMMENT:
+ if((commentbuf = (char *) malloc(bsize + 1)) != NULL) {
+ memcpy(commentbuf, sfcharp, bsize);
+ report("IRCAM comment: %s", sfcharp);
+ commentbuf[bsize] = '\0';
+ if((newline = strchr(commentbuf, '\n')) != NULL)
+ *newline = '\0';
+ }
+ break;
+ }
+ sfcodep = (SFCODE *) (sfcharp + bsize);
+ } while(!finished);
+ if(commentbuf != NULL) /* handles out of memory condition as well */
+ ft->comment = commentbuf;
+}
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void sfstartread(ft)
+ft_t ft;
+{
+ sf_t sf = (sf_t) ft->priv;
+ SFHEADER sfhead;
+
+ if (fread(&sfhead, 1, sizeof(SFHEADER), ft->fp) != sizeof(SFHEADER))
+ fail("unexpected EOF in SF header");
+ memcpy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
+ if (ft->swap) {
+#ifdef IRCAM
+ sf->info.sf_srate = swapf(sf->info.sf_srate);
+#else
+ sf->info.sf_magic = swapl(sf->info.sf_magic);
+ sf->info.sf_srate = swapl(sf->info.sf_srate);
+#endif
+ sf->info.sf_packmode = swapl(sf->info.sf_packmode);
+ sf->info.sf_chans = swapl(sf->info.sf_chans);
+ }
+#ifdef IRCAM
+ if ((sfmagic1(&sfhead) != SF_MAGIC1) ||
+ (sfmagic2(&sfhead) != SF_MAGIC2))
+ fail(
+"SF %s file: can't read, it is byte-swapped or it is not an IRCAM SoundFile",
+ ft->filename);
+#else
+ if (sf->info.sf_magic != SF_MAGIC)
+ if (sf->info.sf_magic == swapl(SF_MAGIC))
+fail("SF %s file: can't read, it is probably byte-swapped");
+ else
+fail("SF %s file: can't read, it is not an IRCAM SoundFile");
+#endif
+
+
+ /*
+ * If your format specifies or your file header contains
+ * any of the following information.
+ */
+ ft->info.rate = sf->info.sf_srate;
+ switch(sf->info.sf_packmode) {
+ case SF_SHORT:
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ break;
+ case SF_FLOAT:
+ ft->info.size = FLOAT;
+ ft->info.style = SIGN2;
+ break;
+ default:
+ fail("Soundfile input: unknown format 0x%x\n",
+ sf->info.sf_packmode);
+ }
+ ft->info.channels = (int) sf->info.sf_chans;
+
+ /* Read codes and print as comments. */
+ readcodes(ft, &sfhead);
+}
+
+void sfstartwrite(ft)
+ft_t ft;
+{
+ sf_t sf = (sf_t) ft->priv;
+ SFHEADER sfhead;
+ SFCODE *sfcodep;
+ char *sfcharp;
+ int littlendian = 0;
+ char *endptr;
+
+#ifdef IRCAM
+ sf->info.magic_union._magic_bytes.sf_magic1 = SF_MAGIC1;
+ sf->info.magic_union._magic_bytes.sf_magic2 = SF_MAGIC2;
+ sf->info.magic_union._magic_bytes.sf_param = 0;
+ /* computer musicians can't code worth a damn */
+ /* you don't see this kind of junk in any other format */
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian == 1)
+ sf->info.magic_union._magic_bytes.sf_machine = SF_VAX;
+ else
+ sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
+#else
+ sf->info.sf_magic = SF_MAGIC;
+#endif
+ sf->info.sf_srate = ft->info.rate;
+#ifdef LATER
+ /*
+ * CSound sound-files have many formats.
+ * We stick with the IRCAM short-or-float scheme.
+ */
+ if (ft->info.size == WORD) {
+ sf->info.sf_packmode = SF_SHORT;
+ ft->info.style = SIGN2; /* Default to signed words */
+ } else if (ft->info.size == FLOAT)
+ sf->info.sf_packmode = SF_FLOAT;
+ else
+ fail("SoundFile %s: must set output as signed shorts or floats",
+ ft->filename);
+#else
+ if (ft->info.size == FLOAT) {
+ sf->info.sf_packmode = SF_FLOAT;
+ ft->info.size = FLOAT;
+ } else {
+ sf->info.sf_packmode = SF_SHORT;
+ ft->info.size = WORD;
+ ft->info.style = SIGN2; /* Default to signed words */
+ }
+#endif
+ sf->info.sf_chans = ft->info.channels;
+
+ /* Clean out structure so unused areas will remain constain */
+ /* between different coverts and not rely on memory contents */
+ memset (&sfhead, 0, sizeof(SFHEADER));
+ memcpy(&sfhead.sfinfo, &sf->info, sizeof(struct sfinfo));
+ sfcodep = (SFCODE *) &sfcodes(&sfhead);
+ sfcodep->code = SF_COMMENT;
+ sfcodep->bsize = strlen(ft->comment) + sizeof(SFCODE);
+ while (sfcodep->bsize % 4)
+ sfcodep->bsize++;
+ sfcharp = (char *) sfcodep;
+ strcpy(sfcharp + sizeof(SFCODE), ft->comment);
+ sfcodep = (SFCODE *) (sfcharp + sfcodep->bsize);
+ sfcodep->code = SF_END;
+ sfcodep->bsize = sizeof(SFCODE);
+ sfcharp = (char *) sfcodep + sizeof(SFCODE);
+ while(sfcharp < (char *) &sfhead + SIZEOF_BSD_HEADER)
+ *sfcharp++ = '\0';
+ (void) fwrite(&sfhead, 1, sizeof(SFHEADER), ft->fp);
+}
+
+/* Read and write are supplied by raw.c */
+
+
+
--- /dev/null
+++ b/src/sfircam.h
@@ -1,0 +1,218 @@
+/* SFHEADER.H */
+
+/* definitions and structures needed for manipulating soundfiles.
+ */
+
+#define SIZEOF_HEADER 1024
+#define SF_BUFSIZE (16*1024) /* used only in play */
+#define SF_MAXCHAN 4
+#define MAXCOMM 512
+#define MINCOMM 256
+
+#define SF_MAGIC1 0144
+#define SF_MAGIC2 0243
+
+/* Definition of SF_MACHINE and SF_MAGIC
+ *
+ * Note that SF_MAGIC always has SF_MAGIC1 as its first byte, SF_MAGIC2 as its
+ * second, SF_MACHINE as its third, and zero as its fourth. Separate define's
+ * are needed because byte order is different on different machines.
+ */
+#define SF_VAX 1
+#define SF_SUN 2
+#define SF_MIPS 3
+#define SF_NEXT 4
+#ifdef vax
+#define SF_MACHINE SF_VAX
+#define SF_MAGIC ((LONG)(SF_MAGIC1 | SF_MAGIC2 << 8 | SF_MACHINE << 16))
+#endif
+#ifdef sun
+#define SF_MACHINE SF_SUN
+#define SF_MAGIC ((LONG)(SF_MAGIC1 << 24 | SF_MAGIC2 << 16 | SF_MACHINE << 8))
+#endif
+#ifdef mips
+#define SF_MACHINE SF_MIPS
+#define SF_MAGIC ((LONG)(SF_MAGIC1 | SF_MAGIC2 << 8 | SF_MACHINE << 16))
+#endif
+#ifdef NeXT
+#define SF_MACHINE SF_NEXT
+#define SF_MAGIC ((LONG)(SF_MAGIC1 << 24 | SF_MAGIC2 << 16 | SF_MACHINE << 8))
+#endif
+
+
+/* Packing modes, as stored in the SFHEADER.sf_packmode field
+ *
+ * For each packing mode, the lower-order short is the number of bytes per
+ * sample, and for backward compatibility, SF_SHORT and SF_FLOAT have
+ * high-order short = 0 so overall they're the bytes per sample, but that's not
+ * true for all SF_'s. Thus while the "sfclass" macro still returns a unique
+ * ID for each packing mode, the new "sfsamplesize" macro should be used to get
+ * the bytes per sample.
+ *
+ * Note that SF_X == SFMT_X in most, but not all, cases, because MIT changed
+ * SFMT_FLOAT and we kept SF_FLOAT for compatibility with existing sound files.
+ *
+ * Possible values of sf_packmode:
+ */
+#define SF_CHAR ((LONG) sizeof(char))
+#define SF_ALAW ((LONG) sizeof(char) | 0x10000)
+#define SF_ULAW ((LONG) sizeof(char) | 0x20000)
+#define SF_SHORT ((LONG) sizeof(short))
+#define SF_LONG ((LONG) sizeof(LONG) | 0x40000)
+#define SF_FLOAT ((LONG) sizeof(float))
+
+/* For marking data after fixed section of soundfile header -- see man (3carl)
+ * sfcodes and defintions of SFCODE and related structures, below.
+ */
+#define SF_END 0 /* Meaning no more information */
+#define SF_MAXAMP 1 /* Meaning maxamp follows */
+#define SF_COMMENT 2 /* code for "comment line" */
+#define SF_PVDATA 3
+#define SF_AUDIOENCOD 4
+#define SF_CODMAX 4
+
+/*
+ * DEFINITION OF SFHEADER FORMAT
+ *
+ * The first four bytes are the magic information for the sound file. They
+ * can be accessed, via a union, either as a structure of four unsigned bytes
+ * sf_magic1, sf_magic2, sf_machine, sf_param, or as the single long sf_magic.
+ * sf_magic is for backward compatibility; it should be SF_MAGIC as defined
+ * above.
+ */
+typedef union sfheader {
+ struct sfinfo {
+ union magic_union {
+ struct {
+ unsigned char sf_magic1; /* byte 1 of magic */
+ unsigned char sf_magic2; /* 2 */
+ unsigned char sf_machine; /* 3 */
+ unsigned char sf_param; /* 4 */
+ } _magic_bytes;
+ LONG sf_magic; /* magic as a 4-byte long */
+ } magic_union;
+ float sf_srate;
+ LONG sf_chans;
+ LONG sf_packmode;
+ char sf_codes;
+ } sfinfo;
+ char filler[SIZEOF_HEADER];
+} SFHEADER;
+
+/*
+ * Definition of SFCODE and related data structs
+ *
+ * Two routines in libbicsf/sfcodes.c, getsfcode() and putsfcode()
+ * are used to insert additionnal information into a header
+ * or to retreive such information. See man sfcodes.
+ *
+ * 10/90 pw
+ * These routines are now part of libcarl/sfcodes.c
+ */
+
+typedef struct sfcode {
+ short code;
+ short bsize;
+} SFCODE;
+
+typedef struct Sfmaxamp {
+ float value[SF_MAXCHAN];
+ LONG samploc[SF_MAXCHAN];
+ LONG timetag;
+} SFMAXAMP;
+
+typedef struct sfcomment {
+ char comment[MAXCOMM];
+} SFCOMMENT;
+
+typedef struct { /* this code written by pvanal */
+ short frameSize;
+ short frameIncr;
+} SFPVDATA;
+
+typedef struct { /* ditto */
+ short encoding;
+ short grouping;
+} SFAUDIOENCOD;
+
+/*
+ * DEFINITION OF MACROS TO GET HEADER INFO
+ * x is a pointer to SFHEADER
+ *
+ * For backward compatibility in MIT Csound code, sfmagic(x) still provides
+ * access to the first long of SFHEADER x. It can be compared to SF_MAGIC,
+ * which is defined machine-dependently (above) to always be the right four
+ * bytes in the right order.
+ *
+ * sfclass(x) returns one of SF_SHORT, SF_FLOAT etc. defined above, while
+ * sfsamplesize(x) returns just the bytes per object, the lower-order short of
+ * sf_packmode.
+ */
+#define sfmagic(x) ((x)->sfinfo.magic_union.sf_magic)
+#define sfmagic1(x) ((x)->sfinfo.magic_union._magic_bytes.sf_magic1)
+#define sfmagic2(x) ((x)->sfinfo.magic_union._magic_bytes.sf_magic2)
+#define sfmachine(x) ((x)->sfinfo.magic_union._magic_bytes.sf_machine)
+#define sfparam(x) ((x)->sfinfo.magic_union._magic_bytes.sf_param)
+#define sfsrate(x) ((x)->sfinfo.sf_srate)
+#define sfchans(x) ((x)->sfinfo.sf_chans)
+#define sfclass(x) ((x)->sfinfo.sf_packmode)
+#define sfsamplesize(x) ((size_t) ((x)->sfinfo.sf_packmode & 0xFFFF))
+#define sfbsize(x) ((x)->st_size - sizeof(SFHEADER))
+#define sfcodes(x) ((x)->sfinfo.sf_codes)
+
+/*
+ * Macros for testing soundfiles
+ */
+/* True if soundfile and good arch */
+#define ismagic(x) ((sfmagic1(x) == SF_MAGIC1) && \
+ (sfmagic2(x) == SF_MAGIC2) && \
+ (sfmachine(x) == SF_MACHINE))
+
+/* True if soundfile */
+#define isforeignmagic(x) ((sfmagic1(x) == SF_MAGIC1) && \
+ (sfmagic2(x) == SF_MAGIC2))
+
+/* True if soundfile */
+#define issoundfile(x) ((sfmagic1(x) == SF_MAGIC1) && \
+ (sfmagic2(x) == SF_MAGIC2))
+
+/* True if soundfile and foreign arch */
+#define isforeignsoundfile(x) ((sfmagic1(x) == SF_MAGIC1) && \
+ (sfmagic2(x) == SF_MAGIC2) && \
+ (sfmachine(x) != SF_MACHINE))
+
+/* True if foreign arch */
+#define isforeign(x) (sfmachine(x) != SF_MACHINE)
+
+
+/*
+ * The macros for opening soundfiles have been rewritten as C routines.
+ * In order to preserve compatibility, we supply the following new macros
+ */
+
+#define readopensf(name,fd,sfh,sfst,prog,result) \
+ result = (fd = openrosf(name, &sfh, &sfst, prog)) < 0 ? fd : 0;
+
+#define freadopensf(name,fp,sfh,sfst,prog,result) \
+ result = fopenrosf(name, &fp, &sfh, &sfst, prog);
+
+#define wropensf(name,fd,sfh,prog,result) \
+ result = (fd = openwosf(name, &sfh, prog)) < 0 ? fd : 0;
+
+#define rdwropensf(name,fd,sfh,sfst,prog,result) \
+ result = (fd = openrwsf(name, &sfh, &sfst, prog)) < 0 ? fd : 0;
+
+
+/*
+ * Definition of macro to get MAXAMP and COMMENT info
+ *
+ * sfm is ptr to SFMAXAMP
+ * sfst is the address of a stat struct
+ */
+
+#define sfmaxamp(mptr,chan) (mptr)->value[chan]
+#define sfmaxamploc(mptr,chan) (mptr)->samploc[chan]
+#define sfmaxamptime(x) (x)->timetag
+#define ismaxampgood(x,s) (sfmaxamptime(x) >= (s)->st_mtime)
+#define sfcomm(x,n) (x)->comment[n]
+
--- /dev/null
+++ b/src/silence.c
@@ -1,0 +1,112 @@
+/*
+ * silence - effect to detect periods of silence in audio data and
+ * use this to clip data before and after.
+ *
+ * Written by Chris Bagwell (cbagwell@sprynet.com) - January 10, 1999
+ *
+ * Copyright 1999 Chris Bagwell And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Chris Bagwell And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct silencestuff {
+ int threshold;
+ int threshold_length;
+ int threshold_count;
+ int begin;
+ int begin_skip;
+ int begin_count;
+ int end;
+ int end_skip;
+ int end_count;
+} *silenc_t;
+
+/*
+ * Process options
+ *
+ * Don't do initialization now.
+ * The 'info' fields are not yet filled in.
+ */
+void silence_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Silence effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ * Do all initializations.
+ */
+silence_start(effp)
+eff_t effp;
+{
+ silence_t silence = (silence_t) effp->priv;
+
+ silence.threshold = 5;
+ silence.thres_length = 1000;
+ silence.thres_count = 0;
+
+ silence.begin = silence.end = 0;
+ silence.begin_skip = silence.end_skip = 0;
+ silence.begin_count = silence.end_count = 0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void silence_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ silence_t silence = (silence_t) effp->priv;
+ int len, done;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ if (silence.threshold_count >= silence.threshold_length) {
+
+
+ if no more samples
+ break
+ get a sample
+ l = sample converted to signed long
+ *buf++ = l;
+ }
+ *isamp =
+ *osamp =
+}
+
+/*
+ * Drain out remaining samples if the effect generates any.
+ */
+
+void skel_drain(effp, obuf, osamp)
+LONG *obuf;
+int *osamp;
+{
+ *osamp = 0;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * (free allocated memory, etc.)
+ */
+void skel_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+
--- /dev/null
+++ b/src/skel.c
@@ -1,0 +1,135 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools skeleton file format driver.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct skelstuff {
+ int rest; /* bytes remaining in current block */
+} *skel_t;
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+skelstartread(ft)
+ft_t ft;
+{
+ skel_t sk = (skel_t) ft->priv;
+
+ /* If you need to seek around the input file. */
+ if (! ft->seekable)
+ fail("SKEL input file must be a file, not a pipe");
+
+ /*
+ * If your format specifies or your file header contains
+ * any of the following information.
+ */
+ ft->info.rate =
+ ft->info.size = BYTE or WORD ...;
+ ft->info.style = UNSIGNED or SIGN2 ...;
+ ft->info.channels = 1 or 2 or 4;
+ ft->comment = any comment in file header.
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+skelread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ skel_t sk = (skel_t) ft->priv;
+ int abs;
+ float amp;
+ int done = 0;
+
+ char c;
+ unsigned char uc;
+ short s;
+ unsigned short us;
+ LONG l;
+ ULONG ul;
+ float f;
+ double d;
+
+ for(; done < len; done++) {
+ if no more samples
+ break
+ get a sample
+ l = sample converted to signed long
+ *buf++ = l;
+ }
+ return done;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+skelstopread(ft)
+ft_t ft;
+{
+}
+
+skelstartwrite(ft)
+ft_t ft;
+{
+ skel_t sk = (skel_t) ft->priv;
+
+ /* If you have to seek around the output file */
+ if (! ft->seekable)
+ fail("Output .skel file must be a file, not a pipe");
+
+ /* If your format specifies any of the following info. */
+ ft->info.rate =
+ ft->info.size = BYTE or WORD ...;
+ ft->info.style = UNSIGNED or SIGN2 ...;
+ ft->info.channels = 1 or 2 or 4;
+ /* Write file header, if any */
+ /* Write comment field, if any */
+
+}
+
+skelwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ skel_t sk = (skel_t) ft->priv;
+ register int datum;
+ int abs;
+ int done = 0;
+
+ while(len--)
+ putc((*buf++ >> 24) ^ 0x80, ft->fp);
+ /* If you cannot write out all of the supplied samples, */
+ /* fail("SKEL: Can't write all samples to %s", ft->filename); */
+
+}
+
+skelstopwrite(ft)
+ft_t ft;
+{
+ /* All samples are already written out. */
+ /* If file header needs fixing up, for example it needs the */
+ /* the number of samples in a field, seek back and write them here. */
+}
+
--- /dev/null
+++ b/src/skeleff.c
@@ -1,0 +1,104 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools skeleton effect file.
+ */
+
+#include <math.h>
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct skelstuff {
+ int rest; /* bytes remaining in current block */
+} *skel_t;
+
+/*
+ * Process options
+ *
+ * Don't do initialization now.
+ * The 'info' fields are not yet filled in.
+ */
+void skel_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ if (n)
+ fail("Copy effect takes no options.");
+}
+
+/*
+ * Prepare processing.
+ * Do all initializations.
+ */
+skel_start(effp)
+eff_t effp;
+{
+ /* nothing to do */
+ /* stuff data into delaying effects here */
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void skel_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ skel_t skel = (skel_t) effp->priv;
+ int len, done;
+
+ char c;
+ unsigned char uc;
+ short s;
+ unsigned short us;
+ LONG l;
+ ULONG ul;
+ float f;
+ double d;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ if no more samples
+ break
+ get a sample
+ l = sample converted to signed long
+ *buf++ = l;
+ }
+ *isamp =
+ *osamp =
+}
+
+/*
+ * Drain out remaining samples if the effect generates any.
+ */
+
+void skel_drain(effp, obuf, osamp)
+LONG *obuf;
+int *osamp;
+{
+ *osamp = 0;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * (free allocated memory, etc.)
+ */
+void skel_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
+
--- /dev/null
+++ b/src/smp.c
@@ -1,0 +1,363 @@
+/*
+ * June 30, 1992
+ * Copyright 1992 Leigh Smith And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Leigh Smith And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools SampleVision file format driver.
+ * Output is always in little-endian (80x86/VAX) order.
+ *
+ * Derived from: Sound Tools skeleton handler file.
+ *
+ * Add: Loop point verbose info. It's a start, anyway.
+ */
+
+#include "st.h"
+#include <string.h>
+
+#define NAMELEN 30 /* Size of Samplevision name */
+#define COMMENTLEN 60 /* Size of Samplevision comment, not shared */
+#define MIDI_UNITY 60 /* MIDI note number to play sample at unity */
+
+/* The header preceeding the sample data */
+struct smpheader {
+ char Id[18]; /* File identifier */
+ char version[4]; /* File version */
+ char comments[COMMENTLEN]; /* User comments */
+ char name[NAMELEN + 1]; /* Sample Name, left justified */
+};
+#define HEADERSIZE (sizeof(struct smpheader) - 1) /* -1 for name's \0 */
+
+/* Samplevision loop definition structure */
+struct loop {
+ ULONG start; /* Sample count into sample data, not byte count */
+ ULONG end; /* end point */
+ char type; /* 0 = loop off, 1 = forward, 2 = forw/back */
+ short count; /* No of times to loop */
+};
+
+/* Samplevision marker definition structure */
+struct marker {
+ char name[10]; /* Ascii Marker name */
+ ULONG position; /* Sample Number, not byte number */
+};
+
+/* The trailer following the sample data */
+struct smptrailer {
+ struct loop loops[8]; /* loops */
+ struct marker markers[8]; /* markers */
+ char MIDInote; /* for unity pitch playback */
+ ULONG rate; /* in hertz */
+ ULONG SMPTEoffset; /* in subframes - huh? */
+ ULONG CycleSize; /* sample count in one cycle of the */
+ /* sampled sound -1 if unknown */
+};
+
+/* Private data for SMP file */
+typedef struct smpstuff {
+ ULONG NoOfSamps; /* Sample data count in words */
+ /* comment memory resides in private data because it's small */
+ char comment[COMMENTLEN + NAMELEN + 3];
+} *smp_t;
+
+char *SVmagic = "SOUND SAMPLE DATA ", *SVvers = "2.1 ";
+
+/*
+ * Read the SampleVision trailer structure.
+ * Returns 1 if everything was read ok, 0 if there was an error.
+ */
+static int readtrailer(ft, trailer)
+ft_t ft;
+struct smptrailer *trailer;
+{
+ int i;
+
+ rlshort(ft); /* read reserved word */
+ for(i = 0; i < 8; i++) { /* read the 8 loops */
+ trailer->loops[i].start = rllong(ft);
+ ft->loops[i].start = trailer->loops[i].start;
+ trailer->loops[i].end = rllong(ft);
+ ft->loops[i].length =
+ trailer->loops[i].end - trailer->loops[i].start;
+ trailer->loops[i].type = getc(ft->fp);
+ ft->loops[i].type = trailer->loops[8].type;
+ trailer->loops[i].count = rlshort(ft);
+ ft->loops[8].count = trailer->loops[8].count;
+ }
+ for(i = 0; i < 8; i++) { /* read the 8 markers */
+ if (fread(trailer->markers[i].name, 1, 10, ft->fp) != 10)
+ return(0);
+ trailer->markers[i].position = rllong(ft);
+ }
+ trailer->MIDInote = getc(ft->fp);
+ trailer->rate = rllong(ft);
+ trailer->SMPTEoffset = rllong(ft);
+ trailer->CycleSize = rllong(ft);
+ return(1);
+}
+
+/*
+ * set the trailer data - loops and markers, to reasonably benign values
+ */
+void settrailer(ft, trailer, rate)
+ft_t ft;
+struct smptrailer *trailer;
+unsigned int rate;
+{
+ int i;
+
+ for(i = 0; i < 8; i++) { /* copy the 8 loops */
+ if (ft->loops[i].type != 0) {
+ trailer->loops[i].start = ft->loops[i].start;
+ /* to mark it as not set */
+ trailer->loops[i].end = ft->loops[i].start + ft->loops[i].length;
+ trailer->loops[i].type = ft->loops[i].type;
+ trailer->loops[i].count = ft->loops[i].count;
+ } else {
+ /* set first loop start as FFFFFFFF */
+ trailer->loops[i].start = ~0;
+ /* to mark it as not set */
+ trailer->loops[i].end = 0;
+ trailer->loops[i].type = 0;
+ trailer->loops[i].count = 0;
+ }
+ }
+ for(i = 0; i < 8; i++) { /* write the 8 markers */
+ strcpy(trailer->markers[i].name, " ");
+ trailer->markers[i].position = ~0;
+ }
+ trailer->MIDInote = MIDI_UNITY; /* Unity play back */
+ trailer->rate = rate;
+ trailer->SMPTEoffset = 0;
+ trailer->CycleSize = -1;
+}
+
+/*
+ * Write the SampleVision trailer structure.
+ * Returns 1 if everything was written ok, 0 if there was an error.
+ */
+static int writetrailer(ft, trailer)
+ft_t ft;
+struct smptrailer *trailer;
+{
+ int i;
+
+ wlshort(ft, 0); /* write the reserved word */
+ for(i = 0; i < 8; i++) { /* write the 8 loops */
+ wllong(ft, trailer->loops[i].start);
+ wllong(ft, trailer->loops[i].end);
+ putc(trailer->loops[i].type, ft->fp);
+ wlshort(ft, trailer->loops[i].count);
+ }
+ for(i = 0; i < 8; i++) { /* write the 8 markers */
+ if (fwrite(trailer->markers[i].name, 1, 10, ft->fp) != 10)
+ return(0);
+ wllong(ft, trailer->markers[i].position);
+ }
+ putc(trailer->MIDInote, ft->fp);
+ wllong(ft, trailer->rate);
+ wllong(ft, trailer->SMPTEoffset);
+ wllong(ft, trailer->CycleSize);
+ return(1);
+}
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void smpstartread(ft)
+ft_t ft;
+{
+ smp_t smp = (smp_t) ft->priv;
+ int littlendian = 0, i;
+ int namelen, commentlen;
+ LONG samplestart;
+ char *endptr;
+ struct smpheader header;
+ struct smptrailer trailer;
+
+ /* If you need to seek around the input file. */
+ if (! ft->seekable)
+ fail("SMP input file must be a file, not a pipe");
+
+ /* Read SampleVision header */
+ if (fread((char *) &header, 1, HEADERSIZE, ft->fp) != HEADERSIZE)
+ fail("unexpected EOF in SMP header");
+ if (strncmp(header.Id, SVmagic, 17) != 0)
+ fail("SMP header does not begin with magic word %s\n", SVmagic);
+ if (strncmp(header.version, SVvers, 4) != 0)
+ fail("SMP header is not version %s\n", SVvers);
+
+ /* Format the sample name and comments to a single comment */
+ /* string. We decrement the counters till we encounter non */
+ /* padding space chars, so the *lengths* are low by one */
+ for (namelen = NAMELEN-1;
+ namelen >= 0 && header.name[namelen] == ' '; namelen--)
+ ;
+ for (commentlen = COMMENTLEN-1;
+ commentlen >= 0 && header.comments[commentlen] == ' '; commentlen--)
+ ;
+ sprintf(smp->comment, "%.*s: %.*s", namelen+1, header.name,
+ commentlen+1, header.comments);
+ ft->comment = smp->comment;
+
+ report("SampleVision file name and comments: %s", ft->comment);
+ /* Extract out the sample size (always intel format) */
+ smp->NoOfSamps = rllong(ft);
+ /* mark the start of the sample data */
+ samplestart = ftell(ft->fp);
+
+ /* seek from the current position (the start of sample data) by */
+ /* NoOfSamps * 2 */
+ if (fseek(ft->fp, smp->NoOfSamps * 2L, 1) == -1)
+ fail("SMP unable to seek to trailer");
+ if (!readtrailer(ft, &trailer))
+ fail("unexpected EOF in SMP trailer");
+
+ /* seek back to the beginning of the data */
+ if (fseek(ft->fp, samplestart, 0) == -1)
+ fail("SMP unable to seek back to start of sample data");
+
+ ft->info.rate = (int) trailer.rate;
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ ft->info.channels = 1;
+
+ endptr = (char *) &littlendian;
+ *endptr = 1;
+ if (littlendian != 1)
+ ft->swap = 1;
+
+ if (verbose) {
+ fprintf(stderr, "SampleVision trailer:\n");
+ for(i = 0; i < 8; i++) if (1 || trailer.loops[i].count) {
+#ifdef __alpha__
+ fprintf(stderr, "Loop %d: start: %6d", i, trailer.loops[i].start);
+ fprintf(stderr, " end: %6d", trailer.loops[i].end);
+#else
+ fprintf(stderr, "Loop %d: start: %6ld", i, trailer.loops[i].start);
+ fprintf(stderr, " end: %6ld", trailer.loops[i].end);
+#endif
+ fprintf(stderr, " count: %6d", trailer.loops[i].count);
+ fprintf(stderr, " type: ");
+ switch(trailer.loops[i].type) {
+ case 0: fprintf(stderr, "off\n"); break;
+ case 1: fprintf(stderr, "forward\n"); break;
+ case 2: fprintf(stderr, "forward/backward\n"); break;
+ }
+ }
+ fprintf(stderr, "MIDI Note number: %d\n\n", trailer.MIDInote);
+ }
+ ft->instr.nloops = 0;
+ for(i = 0; i < 8; i++)
+ if (trailer.loops[i].type)
+ ft->instr.nloops++;
+ for(i = 0; i < ft->instr.nloops; i++) {
+ ft->loops[i].type = trailer.loops[i].type;
+ ft->loops[i].count = trailer.loops[i].count;
+ ft->loops[i].start = trailer.loops[i].start;
+ ft->loops[i].length = trailer.loops[i].end
+ - trailer.loops[i].start;
+ }
+ ft->instr.MIDIlow = ft->instr.MIDIhi =
+ ft->instr.MIDInote = trailer.MIDInote;
+ if (ft->instr.nloops > 0)
+ ft->instr.loopmode = LOOP_8;
+ else
+ ft->instr.loopmode = LOOP_NONE;
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+LONG smpread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ smp_t smp = (smp_t) ft->priv;
+ LONG datum;
+ int done = 0;
+
+ for(; done < len && smp->NoOfSamps; done++, smp->NoOfSamps--) {
+ datum = rshort(ft);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ }
+ return done;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void smpstopread(ft)
+ft_t ft;
+{
+}
+
+void smpstartwrite(ft)
+ft_t ft;
+{
+ smp_t smp = (smp_t) ft->priv;
+ struct smpheader header;
+
+ /* If you have to seek around the output file */
+ if (! ft->seekable)
+ fail("Output .smp file must be a file, not a pipe");
+
+ /* If your format specifies any of the following info. */
+ ft->info.size = WORD;
+ ft->info.style = SIGN2;
+ ft->info.channels = 1;
+
+ strcpy(header.Id, SVmagic);
+ strcpy(header.version, SVvers);
+ sprintf(header.comments, "%-*s", COMMENTLEN, "Converted using Sox.");
+ sprintf(header.name, "%-*.*s", NAMELEN, NAMELEN, ft->comment);
+
+ /* Write file header */
+ if(fwrite(&header, 1, HEADERSIZE, ft->fp) != HEADERSIZE)
+ fail("SMP: Can't write header completely");
+ wllong(ft, 0); /* write as zero length for now, update later */
+ smp->NoOfSamps = 0;
+}
+
+void smpwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ smp_t smp = (smp_t) ft->priv;
+ register int datum;
+
+ while(len--) {
+ datum = (int) RIGHT(*buf++, 16);
+ wlshort(ft, datum);
+ smp->NoOfSamps++;
+ }
+ /* If you cannot write out all of the supplied samples, */
+ /* fail("SMP: Can't write all samples to %s", ft->filename); */
+}
+
+void smpstopwrite(ft)
+ft_t ft;
+{
+ smp_t smp = (smp_t) ft->priv;
+ struct smptrailer trailer;
+
+ /* Assign the trailer data */
+ settrailer(ft, &trailer, ft->info.rate);
+ writetrailer(ft, &trailer);
+ if (fseek(ft->fp, 112, 0) == -1)
+ fail("SMP unable to seek back to save size");
+ wllong(ft, smp->NoOfSamps);
+}
--- /dev/null
+++ b/src/sndrtool.c
@@ -1,0 +1,159 @@
+/*
+ * Sounder/Sndtool format handler: W V Neisius, February 1992
+ *
+ * June 28, 93: force output to mono.
+ */
+
+#include <math.h>
+#include <string.h>
+#include "st.h"
+
+/* Private data used by writer */
+struct sndpriv {
+ ULONG nsamples;
+};
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+void sndtwriteheader(P2(ft_t ft,LONG nsamples));
+void rawwrite(P3(ft_t, LONG *, LONG));
+
+/*======================================================================*/
+/* SNDSTARTREAD */
+/*======================================================================*/
+
+void sndtstartread(ft)
+ft_t ft;
+{
+char buf[97];
+
+LONG rate;
+
+rate = 0;
+
+/* determine file type */
+ /* if first 5 bytes == SOUND then this is probably a sndtool sound */
+ /* if first word (16 bits) == 0
+ and second word is between 4000 & 25000 then this is sounder sound */
+ /* otherwise, its probably raw, not handled here */
+
+if (fread(buf, 1, 2, ft->fp) != 2)
+ fail("SND: unexpected EOF");
+if (strncmp(buf,"\0\0",2) == 0)
+ {
+ /* sounder */
+ rate = rlshort(ft);
+ if (rate < 4000 || rate > 25000 )
+ fail ("SND: sample rate out of range");
+ fseek(ft->fp,4,SEEK_CUR);
+ }
+else
+ {
+ /* sndtool ? */
+ fread(&buf[2],1,6,ft->fp);
+ if (strncmp(buf,"SOUND",5))
+ fail ("SND: unrecognized SND format");
+ fseek(ft->fp,12,SEEK_CUR);
+ rate = rlshort(ft);
+ fseek(ft->fp,6,SEEK_CUR);
+ if (fread(buf,1,96,ft->fp) != 96)
+ fail ("SND: unexpected EOF in SND header");
+ report ("%s",buf);
+ }
+
+ft->info.channels = 1;
+ft->info.rate = rate;
+ft->info.style = UNSIGNED;
+ft->info.size = BYTE;
+
+}
+
+/*======================================================================*/
+/* SNDTSTARTWRITE */
+/*======================================================================*/
+void sndtstartwrite(ft)
+ft_t ft;
+{
+struct sndpriv *p = (struct sndpriv *) ft->priv;
+
+/* write header */
+ft->info.channels = 1;
+ft->info.style = UNSIGNED;
+ft->info.size = BYTE;
+p->nsamples = 0;
+sndtwriteheader(ft, 0);
+
+}
+/*======================================================================*/
+/* SNDRSTARTWRITE */
+/*======================================================================*/
+void sndrstartwrite(ft)
+ft_t ft;
+{
+/* write header */
+ft->info.channels = 1;
+ft->info.style = UNSIGNED;
+ft->info.size = BYTE;
+
+/* sounder header */
+wlshort (ft,0); /* sample size code */
+wlshort (ft,(int) ft->info.rate); /* sample rate */
+wlshort (ft,10); /* volume */
+wlshort (ft,4); /* shift */
+}
+
+/*======================================================================*/
+/* SNDTWRITE */
+/*======================================================================*/
+
+void sndtwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ struct sndpriv *p = (struct sndpriv *) ft->priv;
+ p->nsamples += len;
+ rawwrite(ft, buf, len);
+}
+
+/*======================================================================*/
+/* SNDTSTOPWRITE */
+/*======================================================================*/
+
+void sndtstopwrite(ft)
+ft_t ft;
+{
+struct sndpriv *p = (struct sndpriv *) ft->priv;
+
+/* fixup file sizes in header */
+if (fseek(ft->fp, 0L, 0) != 0)
+ fail("can't rewind output file to rewrite SND header");
+sndtwriteheader(ft, p->nsamples);
+}
+
+/*======================================================================*/
+/* SNDTWRITEHEADER */
+/*======================================================================*/
+void sndtwriteheader(ft,nsamples)
+ft_t ft;
+LONG nsamples;
+{
+char name_buf[97];
+
+/* sndtool header */
+fputs ("SOUND",ft->fp); /* magic */
+fputc (0x1a,ft->fp);
+wlshort (ft,(LONG)0); /* hGSound */
+wllong (ft,nsamples);
+wllong (ft,(LONG)0);
+wllong (ft,nsamples);
+wlshort (ft,(int) ft->info.rate);
+wlshort (ft,0);
+wlshort (ft,10);
+wlshort (ft,4);
+sprintf (name_buf,"%s - File created by Sound Exchange",ft->filename);
+fwrite (name_buf, 1, 96, ft->fp);
+}
+
+
--- /dev/null
+++ b/src/sox.c
@@ -1,0 +1,907 @@
+/*
+ * Sox - The Swiss Army Knife of Audio Manipulation.
+ *
+ * This is the main function for the command line sox program.
+ *
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Change History:
+ *
+ * June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Added patch to get volume working again. Based on patch sent from
+ * Matija Nalis <mnalis@public.srce.hr>.
+ * Added command line switches to force format to ADPCM or GSM.
+ *
+ * September 12, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Reworked code that handled effects. Wasn't correctly draining
+ * stereo effects and a few other problems.
+ * Made command usage (-h) show supported effects and file formats.
+ * (this is partially from a patch by Leigh Smith
+ * leigh@psychokiller.dialix.oz.au).
+ *
+ */
+
+#include "st.h"
+#include "version.h"
+#include "patchlvl.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h> /* for malloc() */
+#include <errno.h>
+#include <sys/types.h> /* for fstat() */
+#include <sys/stat.h> /* for fstat() */
+
+#ifdef unix
+#include <unistd.h> /* for unlink() */
+#endif
+
+#ifdef HAS_GETOPT_H
+#include <getopt.h>
+#endif
+
+#ifdef VMS
+#include <perror.h>
+#define LASTCHAR ']'
+#else
+#define LASTCHAR '/'
+#endif
+
+/*
+ * SOX main program.
+ *
+ * Rewrite for new nicer option syntax. July 13, 1991.
+ * Rewrite for separate effects library. Sep. 15, 1991.
+ * Incorporate Jimen Ching's fixes for real library operation: Aug 3, 1994.
+ * Rewrite for multiple effects: Aug 24, 1994.
+ */
+
+#ifdef AMIGA
+/* This is the Amiga version string */
+char amiversion[AmiVerSize]=AmiVerChars;
+#endif /* AMIGA */
+
+int clipped = 0; /* Volume change clipping errors */
+
+static LONG ibufl[BUFSIZ/2]; /* Left/right interleave buffers */
+static LONG ibufr[BUFSIZ/2];
+static LONG obufl[BUFSIZ/2];
+static LONG obufr[BUFSIZ/2];
+
+void init();
+void doopts(P2(int, char **));
+void usage(P1(char *));
+int filetype(P1(int));
+void process();
+void statistics();
+LONG volumechange();
+void checkeffect(P1(eff_t));
+#ifdef NEED_GETOPT
+int getopt(P3(int,char **,char *));
+#endif
+int flow_effect(P1(int));
+int drain_effect(P1(int));
+
+struct soundstream informat, outformat;
+
+ft_t ft;
+
+#define MAXEFF 4
+struct effect eff;
+struct effect efftab[MAXEFF]; /* table of left/mono channel effects */
+struct effect efftabR[MAXEFF]; /* table of right channel effects */
+ /* efftab[0] is the input stream */
+int neffects; /* # of effects */
+char *ifile, *ofile, *itype, *otype;
+IMPORT char *optarg;
+IMPORT int optind;
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ myname = argv[0];
+ init();
+
+ ifile = ofile = NULL;
+
+ /* Get input format options */
+ ft = &informat;
+ doopts(argc, argv);
+ /* Get input file */
+ if (optind >= argc)
+ usage("No input file?");
+
+ ifile = argv[optind];
+ if (! strcmp(ifile, "-"))
+ ft->fp = stdin;
+ else if ((ft->fp = fopen(ifile, READBINARY)) == NULL)
+ fail("Can't open input file '%s': %s",
+ ifile, strerror(errno));
+ ft->filename = ifile;
+ optind++;
+
+ /* If more arguments are left then look for -e to see if */
+ /* no output file is used, then just do an effect */
+ if (optind < argc && strcmp(argv[optind], "-e"))
+ writing = 1;
+ else if (optind < argc) {
+ writing = 0;
+ optind++; /* Move passed -e */
+ }
+ else
+ writing = 1; /* No arguments left but let next check fail */
+
+ /* Get output format options */
+ ft = &outformat;
+ doopts(argc, argv);
+
+ if (writing) {
+ /* Get output file */
+ if (optind >= argc)
+ usage("No output file?");
+ ofile = argv[optind];
+ ft->filename = ofile;
+ /*
+ * There are two choices here:
+ * 1) stomp the old file - normal shell "> file" behavior
+ * 2) fail if the old file already exists - csh mode
+ */
+ if (! strcmp(ofile, "-"))
+ {
+ ft->fp = stdout;
+
+ /* stdout tends to be line-buffered. Override this */
+ /* to be Full Buffering. */
+ if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*BUFSIZ))
+ fail("Can't set write buffer");
+ }
+ else {
+
+ ft->fp = fopen(ofile, WRITEBINARY);
+
+ if (ft->fp == NULL)
+ fail("Can't open output file '%s': %s",
+ ofile, strerror(errno));
+
+ /* stdout tends to be line-buffered. Override this */
+ /* to be Full Buffering. */
+ if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*BUFSIZ))
+ fail("Can't set write buffer");
+
+ } /* end of else != stdout */
+
+ /* Move passed filename */
+ optind++;
+ } /* end if writing */
+
+ /* Get effect name */
+ if (optind < argc) {
+ eff.name = argv[optind];
+ optind++;
+ geteffect(&eff);
+ (* eff.h->getopts)(&eff, argc - optind, &argv[optind]);
+ } else {
+ eff.name = "null";
+ geteffect(&eff);
+ }
+
+ /* Check global arguments */
+ if (volume <= 0.0)
+ fail("Volume must be greater than 0.0");
+
+#if defined(DUMB_FILESYSETM)
+ informat.seekable = 0;
+ outformat.seekable = 0;
+#else
+ informat.seekable = (filetype(fileno(informat.fp)) == S_IFREG);
+ outformat.seekable = (filetype(fileno(outformat.fp)) == S_IFREG);
+#endif
+
+ /* If file types have not been set with -t, set from file names. */
+ if (! informat.filetype) {
+ if ((informat.filetype = strrchr(ifile, LASTCHAR)) != NULL)
+ informat.filetype++;
+ else
+ informat.filetype = ifile;
+ if ((informat.filetype = strrchr(informat.filetype, '.')) != NULL)
+ informat.filetype++;
+ else /* Default to "auto" */
+ informat.filetype = "auto";
+ }
+ if (writing && ! outformat.filetype) {
+ if ((outformat.filetype = strrchr(ofile, LASTCHAR)) != NULL)
+ outformat.filetype++;
+ else
+ outformat.filetype = ofile;
+ if ((outformat.filetype = strrchr(outformat.filetype, '.')) != NULL)
+ outformat.filetype++;
+ }
+ /* Default the input comment to the filename.
+ * The output comment will be assigned when the informat
+ * structure is copied to the outformat.
+ */
+ informat.comment = informat.filename;
+
+ process();
+ statistics();
+ return(0);
+}
+
+#ifdef HAS_GETOPT_H
+char *getoptstr = "+r:v:t:c:phsuUAagbwlfdDxV";
+#else
+char *getoptstr = "r:v:t:c:phsuUAagbwlfdDxV";
+#endif
+
+void doopts(argc, argv)
+int argc;
+char **argv;
+{
+ int c;
+ char *str;
+
+ while ((c = getopt(argc, argv, getoptstr)) != -1) {
+ switch(c) {
+ case 'p':
+ soxpreview++;
+ break;
+
+ case 'h':
+ usage((char *)0);
+ /* no return from above */
+
+ case 't':
+ if (! ft) usage("-t");
+ ft->filetype = optarg;
+ if (ft->filetype[0] == '.')
+ ft->filetype++;
+ break;
+
+ case 'r':
+ if (! ft) usage("-r");
+ str = optarg;
+#ifdef __alpha__
+ if ((! sscanf(str, "%u", &ft->info.rate)) ||
+ (ft->info.rate <= 0))
+#else
+ if ((! sscanf(str, "%lu", &ft->info.rate)) ||
+ (ft->info.rate <= 0))
+#endif
+ fail("-r must be given a positive integer");
+ break;
+ case 'v':
+ if (! ft) usage("-v");
+ str = optarg;
+ if ((! sscanf(str, "%e", &volume)) ||
+ (volume <= 0))
+ fail("Volume value '%s' is not a number",
+ optarg);
+ dovolume = 1;
+ break;
+
+ case 'c':
+ if (! ft) usage("-c");
+ str = optarg;
+ if (! sscanf(str, "%d", &ft->info.channels))
+ fail("-c must be given a number");
+ break;
+ case 'b':
+ if (! ft) usage("-b");
+ ft->info.size = BYTE;
+ break;
+ case 'w':
+ if (! ft) usage("-w");
+ ft->info.size = WORD;
+ break;
+ case 'l':
+ if (! ft) usage("-l");
+ ft->info.size = DWORD;
+ break;
+ case 'f':
+ if (! ft) usage("-f");
+ ft->info.size = FLOAT;
+ break;
+ case 'd':
+ if (! ft) usage("-d");
+ ft->info.size = DOUBLE;
+ break;
+ case 'D':
+ if (! ft) usage("-D");
+ ft->info.size = IEEE;
+ break;
+
+ case 's':
+ if (! ft) usage("-s");
+ ft->info.style = SIGN2;
+ break;
+ case 'u':
+ if (! ft) usage("-u");
+ ft->info.style = UNSIGNED;
+ break;
+ case 'U':
+ if (! ft) usage("-U");
+ ft->info.style = ULAW;
+ break;
+ case 'A':
+ if (! ft) usage("-A");
+ ft->info.style = ALAW;
+ break;
+ case 'a':
+ if (! ft) usage("-a");
+ ft->info.style = ADPCM;
+ break;
+ case 'g':
+ if (! ft) usage("-g");
+ ft->info.style = GSM;
+ break;
+
+ case 'x':
+ if (! ft) usage("-x");
+ ft->swap = 1;
+ break;
+
+ case 'V':
+ verbose = 1;
+ break;
+ }
+ }
+}
+
+void init() {
+
+ /* init files */
+ informat.info.rate = outformat.info.rate = 0;
+ informat.info.size = outformat.info.size = -1;
+ informat.info.style = outformat.info.style = -1;
+ informat.info.channels = outformat.info.channels = -1;
+ informat.comment = outformat.comment = NULL;
+ informat.swap = 0;
+ informat.filetype = outformat.filetype = (char *) 0;
+ informat.fp = stdin;
+ outformat.fp = stdout;
+ informat.filename = "input";
+ outformat.filename = "output";
+}
+
+/*
+ * Process input file -> effect table -> output file
+ * one buffer at a time
+ */
+
+void process() {
+ LONG i;
+ int e, f, havedata;
+
+ gettype(&informat);
+ if (writing)
+ gettype(&outformat);
+
+ /* Read and write starters can change their formats. */
+ (* informat.h->startread)(&informat);
+ checkformat(&informat);
+
+ if (dovolume)
+ report("Volume factor: %f\n", volume);
+
+ report("Input file: using sample rate %lu\n\tsize %s, style %s, %d %s",
+ informat.info.rate, sizes[informat.info.size],
+ styles[informat.info.style], informat.info.channels,
+ (informat.info.channels > 1) ? "channels" : "channel");
+ if (informat.comment)
+ report("Input file: comment \"%s\"\n", informat.comment);
+
+ /* need to check EFF_REPORT */
+ if (writing) {
+ copyformat(&informat, &outformat);
+ (* outformat.h->startwrite)(&outformat);
+ checkformat(&outformat);
+ cmpformats(&informat, &outformat);
+ report("Output file: using sample rate %lu\n\tsize %s, style %s, %d %s",
+ outformat.info.rate, sizes[outformat.info.size],
+ styles[outformat.info.style], outformat.info.channels,
+ (outformat.info.channels > 1) ? "channels" : "channel");
+ if (outformat.comment)
+ report("Output file: comment \"%s\"\n", outformat.comment);
+ }
+
+ /* Very Important:
+ * Effect fabrication and start is called AFTER files open.
+ * Effect may write out data beforehand, and
+ * some formats don't know their sample rate until now.
+ */
+
+ /* inform effect about signal information */
+ eff.ininfo = informat.info;
+ eff.outinfo = outformat.info;
+ for(i = 0; i < 8; i++) {
+ memcpy(&eff.loops[i], &informat.loops[i], sizeof(struct loopinfo));
+ }
+ eff.instr = informat.instr;
+
+ /* build efftab */
+ checkeffect(&eff);
+
+ /* Start all effects */
+ for(e = 1; e < neffects; e++) {
+ (* efftab[e].h->start)(&efftab[e]);
+ if (efftabR[e].name)
+ (* efftabR[e].h->start)(&efftabR[e]);
+ }
+
+ /* Reserve an output buffer for all effects */
+ for(e = 0; e < neffects; e++) {
+ efftab[e].obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
+ if (efftabR[e].name)
+ efftabR[e].obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
+ }
+
+ /* Read initial chunk of input data. */
+ efftab[0].olen = (*informat.h->read)(&informat,
+ efftab[0].obuf, (LONG) BUFSIZ);
+ efftab[0].odone = 0;
+
+ /* Change the volume of this initial input data if needed. */
+ if (dovolume)
+ for (i = 0; i < efftab[0].olen; i++)
+ efftab[0].obuf[i] = volumechange(efftab[0].obuf[i]);
+
+ /* Run input data through effects and get more until olen == 0 */
+ while (efftab[0].olen > 0) {
+
+ /* mark chain as empty */
+ for(e = 1; e < neffects; e++)
+ efftab[e].odone = efftab[e].olen = 0;
+
+ do {
+
+ /* run entire chain BACKWARDS: pull, don't push.*/
+ /* this is because buffering system isn't a nice queueing system */
+ for(e = neffects - 1; e > 0; e--)
+ if (flow_effect(e))
+ break;
+
+ /* If outputing and output data was generated then write it */
+ if (writing&&(efftab[neffects-1].olen>efftab[neffects-1].odone)) {
+ (* outformat.h->write)(&outformat, efftab[neffects-1].obuf,
+ (LONG) efftab[neffects-1].olen);
+ efftab[neffects-1].odone = efftab[neffects-1].olen;
+ }
+
+ /* if stuff still in pipeline, set up to flow effects again */
+ havedata = 0;
+ for(e = 0; e < neffects - 1; e++)
+ if (efftab[e].odone < efftab[e].olen) {
+ havedata = 1;
+ break;
+ }
+ } while (havedata);
+
+ /* Read another chunk of input data. */
+ efftab[0].olen = (*informat.h->read)(&informat,
+ efftab[0].obuf, (LONG) BUFSIZ);
+ efftab[0].odone = 0;
+
+ /* Change volume of these samples if needed. */
+ if (dovolume)
+ for (i = 0; i < efftab[0].olen; i++)
+ efftab[0].obuf[i] = volumechange(efftab[0].obuf[i]);
+ }
+
+ /* Drain the effects out first to last,
+ * pushing residue through subsequent effects */
+ /* oh, what a tangled web we weave */
+ for(f = 1; f < neffects; f++)
+ {
+ while (1) {
+
+ if (drain_effect(f) == 0)
+ break; /* out of while (1) */
+
+ if (writing&&efftab[neffects-1].olen > 0)
+ (* outformat.h->write)(&outformat, efftab[neffects-1].obuf,
+ (LONG) efftab[neffects-1].olen);
+
+ if (efftab[f].olen != BUFSIZ)
+ break;
+ }
+ }
+
+
+ /* Very Important:
+ * Effect stop is called BEFORE files close.
+ * Effect may write out more data after.
+ */
+
+ for (e = 1; e < neffects; e++) {
+ (* efftab[e].h->stop)(&efftab[e]);
+ if (efftabR[e].name)
+ (* efftabR[e].h->stop)(&efftabR[e]);
+ }
+
+ (* informat.h->stopread)(&informat);
+ fclose(informat.fp);
+
+ if (writing)
+ (* outformat.h->stopwrite)(&outformat);
+ if (writing)
+ fclose(outformat.fp);
+}
+
+int flow_effect(e)
+int e;
+{
+ LONG i, idone, odone, idonel, odonel, idoner, odoner;
+ LONG *ibuf, *obuf;
+
+ /* I have no input data ? */
+ if (efftab[e-1].odone == efftab[e-1].olen)
+ return 0;
+
+ if (! efftabR[e].name) {
+ /* No stereo data, or effect can handle stereo data so
+ * run effect over entire buffer.
+ */
+ idone = efftab[e-1].olen - efftab[e-1].odone;
+ odone = BUFSIZ;
+ (* efftab[e].h->flow)(&efftab[e],
+ &efftab[e-1].obuf[efftab[e-1].odone],
+ efftab[e].obuf, &idone, &odone);
+ efftab[e-1].odone += idone;
+ efftab[e].odone = 0;
+ efftab[e].olen = odone;
+ } else {
+
+ /* Put stereo data in two seperate buffers and run effect
+ * on each of them.
+ */
+ idone = efftab[e-1].olen - efftab[e-1].odone;
+ odone = BUFSIZ;
+ ibuf = &efftab[e-1].obuf[efftab[e-1].odone];
+ for(i = 0; i < idone; i += 2) {
+ ibufl[i/2] = *ibuf++;
+ ibufr[i/2] = *ibuf++;
+ }
+
+ /* left */
+ idonel = (idone + 1)/2; /* odd-length logic */
+ odonel = odone/2;
+ (* efftab[e].h->flow)(&efftab[e], ibufl, obufl, &idonel, &odonel);
+
+ /* right */
+ idoner = idone/2; /* odd-length logic */
+ odoner = odone/2;
+ (* efftabR[e].h->flow)(&efftabR[e], ibufr, obufr, &idoner, &odoner);
+
+ obuf = efftab[e].obuf;
+ /* This loop implies left and right effect will always output
+ * the same amount of data.
+ */
+ for(i = 0; i < odoner; i++) {
+ *obuf++ = obufl[i];
+ *obuf++ = obufr[i];
+ }
+ efftab[e-1].odone += idonel + idoner;
+ efftab[e].odone = 0;
+ efftab[e].olen = odonel + odoner;
+ }
+ if (idone == 0)
+ fail("Effect took no samples!");
+ return 1;
+}
+
+int drain_effect(e)
+int e;
+{
+ LONG i, olen, olenl, olenr;
+ LONG *obuf;
+
+ if (! efftabR[e].name) {
+ efftab[e].olen = BUFSIZ;
+ (* efftab[e].h->drain)(&efftab[e],efftab[e].obuf,
+ &efftab[e].olen);
+ }
+ else {
+ olen = BUFSIZ;
+
+ /* left */
+ olenl = olen/2;
+ (* efftab[e].h->drain)(&efftab[e], obufl, &olenl);
+
+ /* right */
+ olenr = olen/2;
+ (* efftab[e].h->drain)(&efftabR[e], obufr, &olenr);
+
+ obuf = efftab[e].obuf;
+ /* This loop implies left and right effect will always output
+ * the same amount of data.
+ */
+ for(i = 0; i < olenr; i++) {
+ *obuf++ = obufl[i];
+ *obuf++ = obufr[i];
+ }
+ efftab[e].olen = olenl + olenr;
+ }
+ return(efftab[e].olen);
+}
+
+#define setin(eff, effname) \
+ {eff.name = effname; \
+ eff.ininfo.rate = informat.info.rate; \
+ eff.ininfo.channels = informat.info.channels; \
+ eff.outinfo.rate = informat.info.rate; \
+ eff.outinfo.channels = informat.info.channels;}
+
+#define setout(eff, effname) \
+ {eff.name = effname; \
+ eff.ininfo.rate = outformat.info.rate; \
+ eff.ininfo.channels = outformat.info.channels; \
+ eff.outinfo.rate = outformat.info.rate; \
+ eff.outinfo.channels = outformat.info.channels;}
+
+/*
+ * If no effect given, decide what it should be.
+ * Smart ruleset for multiple effects in sequence.
+ * Puts user-specified effect in right place.
+ */
+void
+checkeffect(effp)
+eff_t effp;
+{
+ int i, j;
+ int needchan = 0, needrate = 0;
+
+ /* if given effect does these, we don't need to add them */
+ needrate = (informat.info.rate != outformat.info.rate) &&
+ ! (effp->h->flags & EFF_RATE);
+ needchan = (informat.info.channels != outformat.info.channels) &&
+ ! (effp->h->flags & EFF_MCHAN);
+
+ neffects = 1;
+ /* effect #0 is the input stream */
+ /* inform all effects about all relevant changes */
+ for(i = 0; i < MAXEFF; i++) {
+ efftab[i].name = efftabR[i].name = (char *) 0;
+ /* inform effect about signal information */
+ efftab[i].ininfo = informat.info;
+ efftabR[i].ininfo = informat.info;
+ efftab[i].outinfo = outformat.info;
+ efftabR[i].outinfo = outformat.info;
+ for(j = 0; j < 8; j++) {
+ memcpy(&efftab[i].loops[j],
+ &informat.loops[j], sizeof(struct loopinfo));
+ memcpy(&efftabR[i].loops[j],
+ &informat.loops[j], sizeof(struct loopinfo));
+ }
+ efftab[i].instr = informat.instr;
+ efftabR[i].instr = informat.instr;
+ }
+
+ /* If not writing output, then just add the user specified effect.
+ * This is to avoid channel and rate averaging since you don't have
+ * a real output format.
+ */
+ if (! writing) {
+ neffects = 2;
+ efftab[1].name = effp->name;
+ if ((informat.info.channels == 2) &&
+ (! (effp->h->flags & EFF_MCHAN)))
+ efftabR[1].name = effp->name;
+ }
+ else if (soxpreview) {
+ /* to go faster, i suppose rate could come first if downsampling */
+ if (needchan && (informat.info.channels > outformat.info.channels))
+ {
+ if (needrate) {
+ neffects = 4;
+ efftab[1].name = "avg";
+ efftab[2].name = "rate";
+ setout(efftab[3], effp->name);
+ } else {
+ neffects = 3;
+ efftab[1].name = "avg";
+ setout(efftab[2], effp->name);
+ }
+ } else if (needchan &&
+ (informat.info.channels < outformat.info.channels)) {
+ if (needrate) {
+ neffects = 4;
+ efftab[1].name = effp->name;
+ efftab[1].outinfo.rate = informat.info.rate;
+ efftab[1].outinfo.channels = informat.info.channels;
+ efftab[2].name = "rate";
+ efftab[3].name = "avg";
+ } else {
+ neffects = 3;
+ efftab[1].name = effp->name;
+ efftab[1].outinfo.channels = informat.info.channels;
+ efftab[2].name = "avg";
+ }
+ } else {
+ if (needrate) {
+ neffects = 3;
+ efftab[1].name = effp->name;
+ efftab[1].outinfo.rate = informat.info.rate;
+ efftab[2].name = "rate";
+ if (informat.info.channels == 2)
+ efftabR[2].name = "rate";
+ } else {
+ neffects = 2;
+ efftab[1].name = effp->name;
+ }
+ if ((informat.info.channels == 2) &&
+ (! (effp->h->flags & EFF_MCHAN)))
+ efftabR[1].name = effp->name;
+ }
+ } else { /* not preview mode */
+ /* [ sum to mono,] [ then rate,] then effect */
+ /* not the purest, but much faster */
+ if (needchan &&
+ (informat.info.channels > outformat.info.channels)) {
+ if (needrate && (informat.info.rate != outformat.info.rate)) {
+ neffects = 4;
+ efftab[1].name = "avg";
+ efftab[2].name = effp->name;
+ efftab[2].outinfo.rate = informat.info.rate;
+ efftab[2].outinfo.channels = informat.info.channels;
+ efftab[3].name = "rate";
+ } else {
+ neffects = 3;
+ efftab[1].name = "avg";
+ efftab[2].name = effp->name;
+ efftab[2].outinfo.rate = informat.info.rate;
+ efftab[2].outinfo.channels = informat.info.channels;
+ }
+ } else if (needchan &&
+ (informat.info.channels < outformat.info.channels)) {
+ if (needrate) {
+ neffects = 4;
+ efftab[1].name = effp->name;
+ if (! (effp->h->flags & EFF_MCHAN))
+ efftabR[1].name = effp->name;
+ efftab[1].outinfo.rate = informat.info.rate;
+ efftab[1].outinfo.channels = informat.info.channels;
+ efftab[2].name = "rate";
+ efftab[3].name = "avg";
+ } else {
+ neffects = 3;
+ efftab[1].name = effp->name;
+ if (! (effp->h->flags & EFF_MCHAN))
+ efftabR[1].name = effp->name;
+ efftab[1].outinfo.channels = informat.info.channels;
+ efftab[2].name = "avg";
+ }
+ } else {
+ if (needrate) {
+ neffects = 3;
+ efftab[1].name = effp->name;
+ efftab[1].outinfo.rate = informat.info.rate;
+ efftab[2].name = "rate";
+ if (informat.info.channels == 2)
+ efftabR[2].name = "rate";
+ } else {
+ neffects = 2;
+ efftab[1].name = effp->name;
+ }
+ if ((informat.info.channels == 2) &&
+ (! (effp->h->flags & EFF_MCHAN)))
+ efftabR[1].name = effp->name;
+ }
+ }
+
+ for(i = 1; i < neffects; i++) {
+ /* pointer comparison OK here */
+ /* shallow copy of initialized effect data */
+ /* XXX this assumes that effect_getopt() doesn't malloc() */
+ if (efftab[i].name == effp->name) {
+ memcpy(&efftab[i], &eff, sizeof(struct effect));
+ if (efftabR[i].name)
+ memcpy(&efftabR[i], &eff, sizeof(struct effect));
+ } else {
+ /* set up & give default opts for added effects */
+ geteffect(&efftab[i]);
+ (* efftab[i].h->getopts)(&efftab[i],0,(char *)0);
+ if (efftabR[i].name)
+ memcpy(&efftabR[i], &efftab[i],
+ sizeof(struct effect));
+ }
+ }
+
+ /* If a user doesn't specify an effect then a null entry could
+ * have been placed in the middle of the list above. Remove
+ * those entries here.
+ */
+ for(i = 1; i < neffects; i++)
+ if (! strcmp(efftab[i].name, "null")) {
+ for(; i < neffects; i++) {
+ efftab[i] = efftab[i+1];
+ efftabR[i] = efftabR[i+1];
+ }
+ neffects--;
+ }
+}
+
+/* Guido Van Rossum fix */
+void statistics() {
+ if (dovolume && clipped > 0)
+ report("Volume change clipped %d samples", clipped);
+}
+
+LONG volumechange(y)
+LONG y;
+{
+ double y1;
+
+ y1 = y * volume;
+ if (y1 < -2147483647.0) {
+ y1 = -2147483647.0;
+ clipped++;
+ }
+ else if (y1 > 2147483647.0) {
+ y1 = 2147483647.0;
+ clipped++;
+ }
+
+ return y1;
+}
+
+int filetype(fd)
+int fd;
+{
+ struct stat st;
+
+ fstat(fd, &st);
+
+ return st.st_mode & S_IFMT;
+}
+
+char *usagestr =
+"[ gopts ] [ fopts ] ifile [ fopts ] ofile [ effect [ effopts ] ]";
+
+void usage(opt)
+char *opt;
+{
+ int i;
+
+ fprintf(stderr, "%s: ", myname);
+ if (verbose || !opt)
+ fprintf(stderr, "%s\n\n", version());
+ fprintf(stderr, "Usage: %s\n\n", usagestr);
+ if (opt)
+ fprintf(stderr, "Failed at: %s\n", opt);
+ else {
+ fprintf(stderr,"gopts: -e -h -p -v volume -V\n\n");
+ fprintf(stderr,"fopts: -r rate -c channels -s/-u/-U/-A/-a/-g -b/-w/-l/-f/-d/-D -x\n\n");
+ fprintf(stderr, "effect: ");
+ for (i = 1; effects[i].name != NULL; i++) {
+ fprintf(stderr, "%s ", effects[i].name);
+ }
+ fprintf(stderr, "\n\neffopts: depends on effect\n\n");
+ fprintf(stderr, "Supported file formats: ");
+ for (i = 0; formats[i].names != NULL; i++) {
+ /* only print the first name */
+ fprintf(stderr, "%s ", formats[i].names[0]);
+ }
+ fputc('\n', stderr);
+ }
+ exit(1);
+}
+
+
+/* called from util.c:fail */
+void cleanup() {
+ /* Close the input file and outputfile before exiting*/
+ if (informat.fp)
+ fclose(informat.fp);
+ if (outformat.fp) {
+ fclose(outformat.fp);
+ /* remove the output file because we failed, if it's ours. */
+ /* Don't if its not a regular file. */
+ if (filetype(fileno(outformat.fp)) == S_IFREG)
+ REMOVE(outformat.filename);
+ }
+}
--- /dev/null
+++ b/src/st.h
@@ -1,0 +1,288 @@
+#ifndef ST_H
+#define ST_H
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#ifdef VAXC
+#define IMPORT globalref
+#define EXPORT globaldef
+/*
+ * use the VAX C optimized functions
+ */
+#define calloc VAXC$CALLOC_OPT
+#define cfree VAXC$CFREE_OPT
+#define free VAXC$FREE_OPT
+#define malloc VAXC$MALLOC_OPT
+#define realloc VAXC$REALLOC_OPT
+#else
+#define IMPORT extern
+#define EXPORT
+#endif
+
+
+/*
+ * Sound Tools sources header file.
+ */
+
+#include <stdio.h>
+
+#ifdef __alpha__
+#include <sys/types.h> /* To get defines for 32-bit integers */
+#define LONG int32_t
+#define ULONG u_int32_t
+#else
+#define LONG long
+#define ULONG unsigned long
+#endif
+
+#ifdef AMIGA
+#include "amiga.h"
+#endif /* AMIGA */
+
+/*
+ * Handler structure for each format.
+ */
+
+typedef struct format {
+ char **names; /* file type names */
+ int flags; /* details about file type */
+ void (*startread)();
+ LONG (*read)();
+ void (*stopread)();
+ void (*startwrite)();
+ void (*write)();
+ void (*stopwrite)();
+} format_t;
+
+IMPORT format_t formats[];
+
+/* Signal parameters */
+
+struct signalinfo {
+ LONG rate; /* sampling rate */
+ int size; /* word length of data */
+ int style; /* format of sample numbers */
+ int channels; /* number of sound channels */
+};
+
+/* Loop parameters */
+
+struct loopinfo {
+ int start; /* first sample */
+ int length; /* length */
+ int count; /* number of repeats, 0=forever */
+ int type; /* 0=no, 1=forward, 2=forward/back */
+};
+
+/* Instrument parameters */
+
+/* vague attempt at generic information for sampler-specific info */
+
+struct instrinfo {
+ char MIDInote; /* for unity pitch playback */
+ char MIDIlow, MIDIhi;/* MIDI pitch-bend range */
+ char loopmode; /* semantics of loop data */
+ char nloops; /* number of active loops */
+ unsigned char smpte[4]; /* SMPTE offset (hour:min:sec:frame) */
+ /* this is a film audio thing */
+};
+
+
+#define MIDI_UNITY 60 /* MIDI note number to play sample at unity */
+
+/* Loop modes, upper 4 bits mask the loop blass, lower 4 bits describe */
+/* the loop behaviour, ie. single shot, bidirectional etc. */
+#define LOOP_NONE 0
+#define LOOP_8 32 /* 8 loops: don't know ?? */
+#define LOOP_SUSTAIN_DECAY 64 /* AIFF style: one sustain & one decay loop */
+
+/*
+ * Format information for input and output files.
+ */
+
+#define PRIVSIZE 330
+
+#define NLOOPS 8
+
+struct soundstream {
+ struct signalinfo info; /* signal specifications */
+ struct instrinfo instr; /* instrument specification */
+ struct loopinfo loops[NLOOPS]; /* Looping specification */
+ char swap; /* do byte- or word-swap */
+ char seekable; /* can seek on this file */
+ char *filename; /* file name */
+ char *filetype; /* type of file */
+ char *comment; /* comment string */
+ FILE *fp; /* File stream pointer */
+ format_t *h; /* format struct for this file */
+ double priv[PRIVSIZE/8]; /* format's private data area */
+};
+
+IMPORT struct soundstream informat, outformat;
+typedef struct soundstream *ft_t;
+
+/* flags field */
+#define FILE_STEREO 1 /* does file format support stereo? */
+#define FILE_LOOPS 2 /* does file format support loops? */
+#define FILE_INSTR 4 /* does file format support instrument specificications? */
+
+/* Size field */
+#define BYTE 1
+#define WORD 2
+#define DWORD 4
+#define FLOAT 5
+#define DOUBLE 6
+#define IEEE 7 /* IEEE 80-bit floats. Is it necessary? */
+
+/* Style field */
+#define UNSIGNED 1 /* unsigned linear: Sound Blaster */
+#define SIGN2 2 /* signed linear 2's comp: Mac */
+#define ULAW 3 /* U-law signed logs: US telephony, SPARC */
+#define ALAW 4 /* A-law signed logs: non-US telephony */
+#define ADPCM 5 /* Compressed PCM */
+#define GSM 6 /* GSM 6.10 33-byte frame lossy compression */
+
+IMPORT char *sizes[], *styles[];
+
+/*
+ * Handler structure for each effect.
+ */
+
+typedef struct {
+ char *name; /* effect name */
+ int flags; /* this and that */
+ void (*getopts)(); /* process arguments */
+ void (*start)(); /* start off effect */
+ void (*flow)(); /* do a buffer */
+ void (*drain)(); /* drain out at end */
+ void (*stop)(); /* finish up effect */
+} effect_t;
+
+IMPORT effect_t effects[];
+
+#define EFF_CHAN 1 /* Effect can mix channels up/down */
+#define EFF_RATE 2 /* Effect can alter data rate */
+#define EFF_MCHAN 4 /* Effect can handle multi-channel */
+#define EFF_REPORT 8 /* Effect does nothing */
+
+struct effect {
+ char *name; /* effect name */
+ struct signalinfo ininfo; /* input signal specifications */
+ struct loopinfo loops[8]; /* input loops specifications */
+ struct instrinfo instr; /* input instrument specifications */
+ struct signalinfo outinfo; /* output signal specifications */
+ effect_t *h; /* effects driver */
+ LONG *obuf; /* output buffer */
+ LONG odone, olen; /* consumed, total length */
+ double priv[PRIVSIZE]; /* private area for effect */
+};
+
+typedef struct effect *eff_t;
+
+#if defined(__STDC__)
+#define P1(a) a
+#define P2(a,b) a, b
+#define P3(a,b,c) a, b, c
+#define P4(a,b,c,d) a, b, c, d
+#define P5(a,b,c,d,e) a, b, c, d, e
+#define P6(a,b,c,d,e,f) a, b, c, d, e, f
+#define P7(a,b,c,d,e,f,g) a, b, c, d, e, f, g
+#define P8(a,b,c,d,e,f,g,h) a, b, c, d, e, f, g, h
+#define P9(a,b,c,d,e,f,g,h,i) a, b, c, d, e, f, g, h, i
+#define P10(a,b,c,d,e,f,g,h,i,j) a, b, c, d, e, f, g, h, i, j
+#else
+#define P1(a)
+#define P2(a,b)
+#define P3(a,b,c)
+#define P4(a,b,c,d)
+#define P5(a,b,c,d,e)
+#define P6(a,b,c,d,e,f)
+#define P7(a,b,c,d,e,f,g)
+#define P8(a,b,c,d,e,f,g,h)
+#define P9(a,b,c,d,e,f,g,h,i)
+#define P10(a,b,c,d,e,f,g,h,i,j)
+#endif
+
+/* Utilities to read and write shorts and longs little-endian and big-endian */
+unsigned short rlshort(P1(ft_t ft)); /* short little-end */
+unsigned short rbshort(P1(ft_t ft)); /* short big-end */
+unsigned short wlshort(P2(ft_t ft, unsigned short us)); /* short little-end */
+unsigned short wbshort(P2(ft_t ft, unsigned short us)); /* short big-end */
+ULONG rllong(P1(ft_t ft)); /* long little-end */
+ULONG rblong(P1(ft_t ft)); /* long big-end */
+ULONG wllong(P2(ft_t ft, ULONG ul)); /* long little-end */
+ULONG wblong(P2(ft_t ft, ULONG ul)); /* long big-end */
+/* Read and write words and longs in "machine format". Swap if indicated. */
+unsigned short rshort(P1(ft_t ft));
+unsigned short wshort(P2(ft_t ft, unsigned short us));
+ULONG rlong(P1(ft_t ft));
+ULONG wlong(P2(ft_t ft, ULONG ul));
+float rfloat(P1(ft_t ft));
+void wfloat(P2(ft_t ft, double f));
+double rdouble(P1(ft_t ft));
+void wdouble(P2(ft_t ft, double d));
+
+/* Utilities to byte-swap values */
+unsigned short swapw(P1(unsigned short us)); /* Swap short */
+ULONG swapl(P1(ULONG ul)); /* Swap long */
+float swapf(P1(float f)); /* Swap float */
+double swapd(P1(double d)); /* Swap double */
+
+IMPORT void report(P2(char *, ...)), warn(P2(char *, ...)),
+ fail(P2(char *, ...));
+
+/* util.c */
+IMPORT void geteffect(P1(eff_t));
+IMPORT void gettype(P1(ft_t));
+IMPORT void checkformat(P1(ft_t));
+IMPORT void copyformat(P2(ft_t, ft_t));
+IMPORT void cmpformats(P2(ft_t, ft_t));
+
+typedef unsigned int u_i;
+typedef ULONG u_l;
+typedef unsigned short u_s;
+
+IMPORT float volume; /* expansion coefficient */
+IMPORT int dovolume;
+
+IMPORT float amplitude; /* Largest sample so far */
+
+IMPORT int writing; /* are we writing to a file? */
+
+/* export flags */
+IMPORT int verbose; /* be noisy on stderr */
+IMPORT int summary; /* just print summary of information */
+
+IMPORT char *myname;
+
+IMPORT int soxpreview; /* Preview mode: be fast and ugly */
+
+#define MAXRATE 50L * 1024 /* maximum sample rate */
+
+#define RIGHT(datum, bits) ((datum) >> bits)
+#define LEFT(datum, bits) ((datum) << bits)
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#ifdef VMS
+#define READBINARY "r", "mbf=16", "ctx=stm"
+#define WRITEBINARY "w", "ctx=stm"
+#else
+#define READBINARY "rb"
+#define WRITEBINARY "wb"
+#endif
+
+#define REMOVE unlink
+
+char *version(); /* return version number */
+
+#endif
--- /dev/null
+++ b/src/stat.c
@@ -1,0 +1,211 @@
+
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools statistics "effect" file.
+ *
+ * Build various statistics on file and print them.
+ * No output.
+ */
+
+#include "st.h"
+
+/* Private data for STAT effect */
+typedef struct statstuff {
+ LONG min, max, mean; /* amplitudes */
+ LONG dmin, dmax, dmean; /* deltas */
+ LONG last; /* previous sample */
+ int first;
+ int total;
+ int volume;
+ ULONG bin[4];
+} *stat_t;
+
+#define abs(val) (((val) < 0) ? -(val) : (val))
+
+/*
+ * Process options
+ */
+void stat_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ stat_t stat = (stat_t) effp->priv;
+
+ stat->volume = 0;
+ if (n)
+ {
+ if (!(strcmp(argv[0], "-v")))
+ stat->volume = 1;
+ else if (!(strcmp(argv[0], "debug")))
+ stat->volume = 2;
+ else
+ fail("Summary effect only allows debug or -v as options.");
+ }
+}
+
+/*
+ * Prepare processing.
+ */
+void stat_start(effp)
+eff_t effp;
+{
+ stat_t stat = (stat_t) effp->priv;
+ int i;
+
+ stat->min = stat->dmin = 0x7fffffffL;
+ stat->max = stat->dmax = 0x80000000L;
+ stat->first = 1;
+
+ for (i = 0; i < 4; i++)
+ stat->bin[i] = 0;
+
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void stat_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ stat_t stat = (stat_t) effp->priv;
+ int len, done;
+ LONG samp, delta;
+ short count;
+
+ count = 0;
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+ for(done = 0; done < len; done++) {
+ /* work in absolute levels for both sample and delta */
+ samp = *ibuf++;
+ *obuf++ = samp;
+
+ if (stat->volume == 2)
+ {
+#ifdef __alpha__
+ fprintf(stderr,"%8x ",samp);
+#else
+ fprintf(stderr,"%8lx ",samp);
+#endif
+ if (count++ == 5)
+ {
+ fprintf(stderr,"\n");
+ count = 0;
+ }
+ }
+
+ stat->bin[RIGHT(samp,30)+2]++;
+
+ samp = abs(samp);
+ if (samp < stat->min)
+ stat->min = samp;
+ if (samp > stat->max)
+ stat->max = samp;
+ if (stat->first) {
+ stat->first = 0;
+ stat->mean = samp;
+ stat->dmean = 0;
+ } else {
+ /* overflow avoidance */
+ if ((stat->mean > 0x20000000L) || (samp > 0x20000000L))
+ stat->mean = stat->mean/2 + samp/2;
+ else
+ stat->mean = (stat->mean + samp)/2;
+
+ delta = abs(samp - stat->last);
+ if (delta < stat->dmin)
+ stat->dmin = delta;
+ if (delta > stat->dmax)
+ stat->dmax = delta;
+ /* overflow avoidance */
+ if ((delta > 0x20000000L) || (stat->dmean > 0x20000000L))
+ stat->dmean = stat->dmean/2 + delta/2;
+ else
+ stat->dmean = (stat->dmean + delta)/2;
+ }
+ stat->last = samp;
+ }
+ /* Process all samples */
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void
+stat_stop(effp)
+eff_t effp;
+{
+ stat_t stat = (stat_t) effp->priv;
+ double amp, range;
+ float x;
+
+ stat->min = RIGHT(stat->min, 16);
+ stat->max = RIGHT(stat->max, 16);
+ stat->mean = RIGHT(stat->mean, 16);
+ stat->dmin = RIGHT(stat->dmin, 16);
+ stat->dmax = RIGHT(stat->dmax, 16);
+ stat->dmean = RIGHT(stat->dmean, 16);
+
+ range = 32767.0;
+
+ amp = - stat->min;
+ if (amp < stat->max)
+ amp = stat->max;
+ /* Just print the volume adjustment */
+ if (stat->volume == 1) {
+ fprintf(stderr, "%.3f\n", 32767.0/amp);
+ return;
+ }
+ else if (stat->volume == 2) {
+ fprintf(stderr, "\n");
+ }
+ /* print them out */
+ fprintf(stderr, "Maximum amplitude: %.3f\n", stat->max/range);
+ fprintf(stderr, "Minimum amplitude: %.3f\n", stat->min/range);
+ fprintf(stderr, "Mean amplitude: %.3f\n", stat->mean/range);
+
+ fprintf(stderr, "Maximum delta: %.3f\n", stat->dmax/range);
+ fprintf(stderr, "Minimum delta: %.3f\n", stat->dmin/range);
+ fprintf(stderr, "Mean delta: %.3f\n", stat->dmean/range);
+
+ fprintf(stderr, "Volume adjustment: %.3f\n", 32767.0/amp);
+
+ if (stat->bin[2] == 0 && stat->bin[3] == 0)
+ fprintf(stderr, "\nProbably text, not sound\n");
+ else {
+
+ x = (float)(stat->bin[0] + stat->bin[3]) / (float)(stat->bin[1] + stat->bin[2]);
+
+ if (x >= 3.0) /* use opposite style */
+ if (effp->ininfo.style == UNSIGNED)
+ printf ("\nTry: -t raw -b -s \n");
+ else
+ printf ("\nTry: -t raw -b -u \n");
+
+ else if (x <= 1.0/3.0); /* correctly decoded */
+
+ else if (x >= 0.5 && x <= 2.0) /* use ULAW */
+ if (effp->ininfo.style == ULAW)
+ printf ("\nTry: -t raw -b -u \n");
+ else
+ printf ("\nTry: -t raw -b -U \n");
+
+ else
+ fprintf (stderr, "\nCan't guess the type\n");
+ }
+
+}
+
--- /dev/null
+++ b/src/sunaudio.c
@@ -1,0 +1,478 @@
+#if defined(SUNAUDIO_PLAYER)
+/*
+ * Copyright 1997 Chris Bagwell And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Rick Richardson, Lance Norskog And Sundry Contributors are not
+ * responsible for the consequences of using this software.
+ */
+
+/* Direct to Sun Audio Driver
+ *
+ * Added by Chris Bagwell (cbagwell@sprynet.com) on 2/26/96
+ * Based on oss driver.
+ *
+ * Cleaned up changes of format somewhat in sunstartwrite on 03/31/98
+ *
+ */
+
+#include <sys/ioctl.h>
+#ifdef __SVR4
+#include <sys/audioio.h>
+#else
+#include <sun/audioio.h>
+#endif
+
+#include <malloc.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <signal.h>
+#include "st.h"
+#include "libst.h"
+
+static int got_int = 0;
+
+static int abuf_size = 0;
+static int abuf_cnt = 0;
+static char *audiobuf;
+
+/* This is how we know when to stop recording. User sends interrupt
+ * (eg. control-c) and then we mark a flag to show we are done.
+ * Must call "sigint(0)" during init so that the OS can be notified
+ * what to do.
+ */
+static void
+sigint(s)
+int s;
+{
+ fprintf(stderr,"Got SIGINT\n");
+ if (s) got_int = 1;
+ else signal(SIGINT, sigint);
+}
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void sunstartread(ft)
+ft_t ft;
+{
+ int samplesize, encoding;
+ audio_info_t audio_if;
+
+ /* Hard code for now. */
+ abuf_size = 1024;
+ if ((audiobuf = malloc (abuf_size)) == NULL) {
+ fail("unable to allocate input buffer of size %d", abuf_size);
+ }
+
+ if (ft->info.rate == 0.0) ft->info.rate = 8000;
+ if (ft->info.size == -1) ft->info.size = BYTE;
+ if (ft->info.style == -1) ft->info.style = ULAW;
+
+ if (ft->info.size == BYTE) {
+ samplesize = 8;
+ if (ft->info.style != ULAW &&
+ ft->info.style != ALAW &&
+ ft->info.style != SIGN2) {
+ fail("Sun Audio driver only supports ULAW, ALAW, and Signed Linear for bytes.");
+ }
+
+ }
+ else if (ft->info.size == WORD) {
+ samplesize = 16;
+ if (ft->info.style != SIGN2) {
+ fail("Sun Audio driver only supports Signed Linear for words.");
+ }
+ }
+ else {
+ fail("Sun Audio driver only supports bytes and words");
+ }
+
+ if (ft->info.channels == -1) ft->info.channels = 1;
+ else if (ft->info.channels > 1) {
+ report("Warning: some sun audio devices can not play stereo");
+ report("at all or sometime only with signed words. If the");
+ report("sound seems sluggish then this is probably the case.");
+ report("Try forcing output to signed words or use the avg");
+ report("filter to reduce the number of channels.");
+ ft->info.channels = 2;
+ }
+
+ /* Read in old values, change to what we need and then send back */
+ if (ioctl(fileno(ft->fp), AUDIO_GETINFO, &audio_if) < 0) {
+ fail("Unable to initialize /dev/audio");
+ }
+ audio_if.record.precision = samplesize;
+ audio_if.record.channels = ft->info.channels;
+ audio_if.record.sample_rate = ft->info.rate;
+ if (ft->info.style == ULAW)
+ encoding = AUDIO_ENCODING_ULAW;
+ else if (ft->info.style == ALAW)
+ encoding = AUDIO_ENCODING_ALAW;
+ else
+ encoding = AUDIO_ENCODING_LINEAR;
+ audio_if.record.encoding = encoding;
+
+ ioctl(fileno(ft->fp), AUDIO_SETINFO, &audio_if);
+ if (audio_if.record.precision != samplesize) {
+ fail("Unable to initialize sample size for /dev/audio");
+ }
+ if (audio_if.record.channels != ft->info.channels) {
+ fail("Unable to initialize number of channels for /dev/audio");
+ }
+ if (audio_if.record.sample_rate != ft->info.rate) {
+ fail("Unable to initialize rate for /dev/audio");
+ }
+ if (audio_if.record.encoding != encoding) {
+ fail("Unable to initialize style for /dev/audio");
+ }
+ sigint(0); /* Prepare to catch SIGINT */
+}
+
+int dspget(ft)
+ft_t ft;
+{
+ int rval;
+
+ if (abuf_cnt < 1) {
+ abuf_cnt = read (fileno(ft->fp), (char *)audiobuf, abuf_size);
+ if (abuf_cnt == 0) {
+ got_int = 1; /* Act like user said end record */
+ return(0);
+ }
+ }
+ rval = *(audiobuf + (abuf_size-abuf_cnt));
+ abuf_cnt--;
+ return(rval);
+}
+
+/* Read short. */
+unsigned short dsprshort(ft)
+ft_t ft;
+{
+ unsigned short rval;
+ if (abuf_cnt < 2) {
+ abuf_cnt = read (fileno(ft->fp), (char *)audiobuf, abuf_size);
+ if (abuf_cnt == 0) {
+ got_int = 1; /* act like user said end recording */
+ return(0);
+ }
+ }
+ rval = *((unsigned short *)(audiobuf + (abuf_size-abuf_cnt)));
+ abuf_cnt -= 2;
+ return(rval);
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG sunread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register int datum;
+ int done = 0;
+
+ if (got_int)
+ return(0); /* Return with length 0 read so program will end */
+
+ switch(ft->info.size) {
+ case BYTE:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ return done;
+ case UNSIGNED:
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* Convert to unsigned */
+ datum ^= 128;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 24);
+ done++;
+ }
+ return done;
+ case ULAW:
+ /* grab table from Posk stuff */
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ datum = st_ulaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case ALAW:
+ while(done < len) {
+ datum = dspget(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ datum = st_Alaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ }
+ case WORD:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ datum = dsprshort(ft);
+ if (got_int || feof(ft->fp))
+ {
+ fprintf(stderr,"Returning early\n");
+ return(done);
+ }
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case UNSIGNED:
+ while(done < len) {
+ datum = dsprshort(ft);
+ if (got_int || feof(ft->fp))
+ return(done);
+ /* Convert to unsigned */
+ datum ^= 0x8000;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
+ }
+ return done;
+ case ULAW:
+ fail("No U-Law support for shorts");
+ return done;
+ case ALAW:
+ fail("No A-Law support");
+ return done;
+ }
+ }
+ fail("Drop through in sunread!");
+
+ /* Return number of samples read */
+ return(done);
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void sunstopread(ft)
+ft_t ft;
+{
+}
+
+void sunstartwrite(ft)
+ft_t ft;
+{
+ int samplesize, encoding;
+ audio_info_t audio_if;
+
+ /* Hard code for now. */
+ abuf_size = 1024;
+ if ((audiobuf = malloc (abuf_size)) == NULL) {
+ fail("unable to allocate output buffer of size %d", abuf_size);
+ }
+
+ if (ft->info.rate == 0.0) ft->info.rate = 8000;
+ if (ft->info.size == -1) ft->info.size = BYTE;
+ if (ft->info.style == -1) ft->info.style = ULAW;
+
+ if (ft->info.size == BYTE) {
+ samplesize = 8;
+ if (ft->info.style != ULAW &&
+ ft->info.style != ALAW &&
+ ft->info.style != SIGN2) {
+ report("Sun Audio driver only supports ULAW, ALAW, and Signed Linear for bytes.");
+ report("Forcing to ULAW");
+ ft->info.style = ULAW;
+ }
+
+ }
+ else if (ft->info.size == WORD) {
+ samplesize = 16;
+ if (ft->info.style != SIGN2) {
+ report("Sun Audio driver only supports Signed Linear for words.");
+ report("Forcing to Signed Linear");
+ ft->info.style = SIGN2;
+ }
+ }
+ else {
+ report("Sun Audio driver only supports bytes and words");
+ ft->info.size = WORD;
+ samplesize = 16;
+ }
+
+ if (ft->info.channels == -1) ft->info.channels = 1;
+ else if (ft->info.channels > 1) ft->info.channels = 2;
+
+ /* Read in old values, change to what we need and then send back */
+ if (ioctl(fileno(ft->fp), AUDIO_GETINFO, &audio_if) < 0) {
+ fail("Unable to initialize /dev/audio");
+ }
+ audio_if.play.precision = samplesize;
+ audio_if.play.channels = ft->info.channels;
+ audio_if.play.sample_rate = ft->info.rate;
+ if (ft->info.style == ULAW)
+ encoding = AUDIO_ENCODING_ULAW;
+ else if (ft->info.style == ALAW)
+ encoding = AUDIO_ENCODING_ALAW;
+ else
+ encoding = AUDIO_ENCODING_LINEAR;
+ audio_if.play.encoding = encoding;
+
+ ioctl(fileno(ft->fp), AUDIO_SETINFO, &audio_if);
+ if (audio_if.play.precision != samplesize) {
+ fail("Unable to initialize sample size for /dev/audio");
+ }
+ if (audio_if.play.channels != ft->info.channels) {
+ fail("Unable to initialize number of channels for /dev/audio");
+ }
+ if (audio_if.play.sample_rate != ft->info.rate) {
+ fail("Unable to initialize rate for /dev/audio");
+ }
+ if (audio_if.play.encoding != encoding) {
+ fail("Unable to initialize style for /dev/audio");
+ }
+}
+
+void dspflush(ft)
+ft_t ft;
+{
+ if (write (fileno(ft->fp), audiobuf, abuf_cnt) != abuf_cnt) {
+ fail("Error writing to sound driver");
+ }
+ abuf_cnt = 0;
+}
+
+void dspput(ft,c)
+ft_t ft;
+int c;
+{
+ if (abuf_cnt > abuf_size-1) dspflush(ft);
+ *(audiobuf + abuf_cnt) = c;
+ abuf_cnt++;
+}
+
+/* Write short. */
+void
+dspshort(ft,ui)
+ft_t ft;
+unsigned short ui;
+{
+ if (abuf_cnt > abuf_size-2) dspflush(ft);
+ *((unsigned short *)(audiobuf + abuf_cnt)) = ui;
+ abuf_cnt += 2;
+}
+
+void sunwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ register int datum;
+ int done = 0;
+
+ switch(ft->info.size) {
+ case BYTE:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 24);
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ case UNSIGNED:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 24);
+ /* Convert to unsigned */
+ datum ^= 128;
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ case ULAW:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = (int) RIGHT(*buf++, 16);
+ /* round up to 12 bits of data */
+ datum += 0x8; /* + 0b1000 */
+ datum = st_linear_to_ulaw(datum);
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ case ALAW:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ /* round up to 12 bits of data */
+ datum += 0x8; /* + 0b1000 */
+ datum = st_linear_to_Alaw(datum);
+ dspput(ft,datum);
+ done++;
+ }
+ return;
+ }
+ case WORD:
+ switch(ft->info.style) {
+ case SIGN2:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ dspshort(ft,datum);
+ done++;
+ }
+ return;
+ case UNSIGNED:
+ while(done < len) {
+ /* scale signed up to long's range */
+ datum = RIGHT(*buf++, 16);
+ /* Convert to unsigned */
+ datum ^= 0x8000;
+ dspshort(ft,datum);
+ done++;
+ }
+ return;
+ case ULAW:
+ fail("No U-Law support for words");
+ return;
+ case ALAW:
+ fail("No A-Law support for words");
+ return;
+ }
+ }
+
+ fail("Drop through in sunwrite!");
+}
+
+void sunstopwrite(ft)
+ft_t ft;
+{
+ dspflush(ft);
+}
+#endif
--- /dev/null
+++ b/src/testall.bat
@@ -1,0 +1,52 @@
+@echo off
+
+rem First create a working copy of t.bat. Note optional cls and pause.
+
+echo @echo off >t.bat
+echo set format=%%1 >>t.bat
+echo shift >>t.bat
+echo set opts=%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 >>t.bat
+echo. >>t.bat
+echo cls >>t.bat
+echo echo Format: %%format%% Options: %%opts%% >>t.bat
+echo echo on >>t.bat
+echo .\sox monkey.voc %%opts%% %%tmp%%\monkey.%%format%% %%effect%% >>t.bat
+echo .\sox %%opts%% %%tmp%%\monkey.%%format%% %%tmp%%\monkey1.voc %%effect%% >>t.bat
+echo @echo off >>t.bat
+echo echo. >>t.bat
+echo xdir monkey.voc /c/b >>t.bat
+echo xdir %%tmp%%\monkey1.voc /c/b >>t.bat
+echo echo. >>t.bat
+echo echo The two lengths above should be the same, if the checksums differ >>t.bat
+echo echo investigate further skipping the internal checksum and rate bytes. >>t.bat
+echo set format=>>t.bat
+echo set opts=>>t.bat
+echo pause >>t.bat
+
+rem Now set up any global effects and call the batch file. Note that
+rem this needs extra work to cope with DOS's limitation of 3-character
+rem extensions on the filename.
+
+set effect=%1 %2 %3 %4 %5 %6 %7 %8 %9
+
+call t.bat 8svx
+call t.bat aiff
+call t.bat au
+call t.bat cdr
+call t.bat cvs
+call t.bat dat
+call t.bat vms
+call t.bat hcom -r 22050
+call t.bat maud
+call t.bat raw -r 8130 -t ub
+call t.bat sf
+call t.bat smp
+call t.bat sndr
+call t.bat sndt
+call t.bat txw
+call t.bat voc
+call t.bat wav
+call t.bat wve
+call t.bat wve
+
+del t.bat
--- /dev/null
+++ b/src/testall.sh
@@ -1,0 +1,29 @@
+effect="$*"
+t() {
+ format=$1
+ shift
+ opts="$*"
+
+ echo "Format: $format Options: $opts"
+ ./sox monkey.voc $opts /tmp/monkey.$format $effect
+ ./sox $opts /tmp/monkey.$format /tmp/monkey1.voc $effect
+}
+t 8svx
+t aiff
+t au
+t cdr
+t cvs
+t dat
+t vms
+t hcom -r 22050
+t maud
+t raw -r 8130 -t ub
+t sf
+t smp
+t sndr
+t sndt
+t txw
+t voc
+t wav
+t wve
+t wve
--- /dev/null
+++ b/src/tests.bat
@@ -1,0 +1,91 @@
+@echo off
+
+rem Test script for sox under DOS derived from tests.sh. This should
+rem run without core-dumping or printing any error messages.
+
+set file=monkey
+
+rem verbose options
+
+rem set noise=-V
+
+del out.raw
+del out2.raw
+del in.raw
+cls
+
+echo on
+.\sox %noise% %file%.voc ub.raw
+.\sox %noise% -t raw -r 8196 -u -b -c 1 ub.raw -r 8196 -s -b sb.raw
+.\sox %noise% -t raw -r 8196 -s -b -c 1 sb.raw -r 8196 -u -b ub2.raw
+.\sox %noise% -r 8196 -u -b -c 1 ub2.raw -r 8196 ub2.voc
+@echo off
+
+echo.
+xdir ub.raw /c/b
+xdir ub2.raw /c/b
+echo.
+echo The two checksums above should be the same.
+pause
+echo.
+echo.
+
+echo Skip checksum and rate byte. DOS isn't good at this, so just use a
+echo rough test.
+
+echo.
+xdir %file%.voc /c/b
+xdir ub2.voc /c/b
+echo.
+echo The two lengths above should be the same, if the checksums differ
+echo investigate further skipping the internal checksum and rate bytes.
+pause
+cls
+
+del ub.raw
+del sb.raw
+del ub2.raw
+del ub2.voc
+
+echo on
+.\sox %noise% %file%.au -u -r 8192 -u -b ub.raw
+.\sox %noise% -r 8192 -u -b ub.raw -U -b ub.au
+.\sox %noise% ub.au -u ub2.raw
+.\sox %noise% ub.au -w ub2.sf
+@echo off
+
+del ub.raw
+del ub.au
+del ub2.raw
+rem del ub.sf
+
+echo on
+.\sox %noise% ub2.sf ub2.aif
+.\sox %noise% ub2.aif ub3.sf
+@echo off
+
+echo Skip comment field containing different filenames. Again, DOS sucks.
+
+echo.
+xdir ub2.sf /c/b
+xdir ub3.sf /c/b
+echo.
+echo The two lengths above should be the same, if the checksums differ
+echo investigate further skipping the internal filename comments.
+pause
+cls
+
+del ub2.sf
+del ub2.aif
+del ub3.sf
+
+rem Cmp -l of stop.raw and stop2.raw will show that most of the
+rem bytes are 1 apart. This is quantization error.
+rem
+rem rm -f stop.raw stop2.raw stop2.au
+rem Bytes 23 - 26 are the revision level of VOC file utilities and checksum.
+rem We may use different ones than Sound Blaster utilities do.
+rem We use 0/1 for the major/minor, SB uses that on the 1.15 utility disk.
+
+set file=
+set noise=
--- /dev/null
+++ b/src/tests.sh
@@ -1,0 +1,36 @@
+#!/bin/sh
+# test files
+# SOX Test script. This should run without core-dumping or printing any
+# messages.
+file=monkey
+
+# verbose options
+#noise=-V
+
+rm -f out.raw out2.raw in.raw
+./sox $noise $file.voc ub.raw
+./sox $noise -t raw -r 8196 -u -b -c 1 ub.raw -r 8196 -s -b sb.raw
+./sox $noise -t raw -r 8196 -s -b -c 1 sb.raw -r 8196 -u -b ub2.raw
+./sox $noise -r 8196 -u -b -c 1 ub2.raw -r 8196 ub2.voc
+cmp -l ub.raw ub2.raw
+# skip checksum and rate byte
+cmp -l $file.voc ub2.voc | grep -v '^ 2[3456]' | grep -v '^ 31'
+rm -f ub.raw sb.raw ub2.raw ub2.voc
+./sox $noise $file.au -u -r 8192 -u -b ub.raw
+./sox $noise -r 8192 -u -b ub.raw -U -b ub.au
+./sox $noise ub.au -u ub2.raw
+./sox $noise ub.au -w ub2.sf
+rm -f ub.raw ub.au ub2.raw ub.sf
+./sox $noise ub2.sf ub2.aiff
+./sox $noise ub2.aiff ub3.sf
+# skip comment field containing differnt filenames
+cmp -l ub2.sf ub3.sf | grep -v '^ 2[3456789]'
+rm -f ub2.sf ub2.aiff ub3.sf
+#
+# Cmp -l of stop.raw and stop2.raw will show that most of the
+# bytes are 1 apart. This is quantization error.
+#
+# rm -f stop.raw stop2.raw stop2.au
+# Bytes 23 - 26 are the revision level of VOC file utilities and checksum.
+# We may use different ones than Sound Blaster utilities do.
+# We use 0/1 for the major/minor, SB uses that on the 1.15 utility disk.
--- /dev/null
+++ b/src/tx16w.c
@@ -1,0 +1,376 @@
+/* Yamaha TX-16W sampler file support
+ *
+ * May 20, 1993
+ * Copyright 1993 Rob Talley (rob@aii.com)
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice and the following copyright
+ * notice must be maintained intact. No warranty whatsoever is
+ * provided. This code is furnished AS-IS as a component of the
+ * larger work Copyright 1991 Lance Norskog and Sundry Contributors.
+ * Much appreciation to ross-c for his sampConv utility for SGI/IRIX
+ * from where these methods were derived.
+ *
+ * Jan 24, 1994
+ * Pat McElhatton, HP Media Technology Lab <patmc@apollo.hp.com>
+ * Handles reading of files which do not have the sample rate field
+ * set to one of the expected by looking at some other bytes in the
+ * attack/loop length fields, and defaulting to 33kHz if the sample
+ * rate is still unknown.
+ *
+ * January 12, 1995
+ * Copyright 1995 Mark Lakata (lakata@physics.berkeley.edu)
+ * Additions to tx16w.c SOX driver. This version writes as well as
+ * reads TX16W format.
+ *
+ * July 31, 1998
+ * Cleaned up by Leigh Smith (leigh@psychokiller.dialix.oz.au)
+ * for incorporation into the main sox distribution.
+ *
+ * September 24, 1998
+ * Forced output to mono signed words to match input. It was basically
+ * doing this anyways but now the user will see a display that its being
+ * overriding. cbagwell@sprynet.com
+ *
+ */
+
+#define TXMAXLEN 0x3FF80
+
+/*
+ * Sound Tools skeleton file format driver.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "st.h"
+
+/* Private data for TX16 file */
+typedef struct txwstuff {
+ LONG rest; /* bytes remaining in sample file */
+} *txw_t;
+
+IMPORT float volume, amplitude;
+IMPORT int summary, verbose;
+
+struct WaveHeader_ {
+ char filetype[6]; /* = "LM8953", */
+ unsigned char
+ nulls[10],
+ dummy_aeg[6], /* space for the AEG (never mind this) */
+ format, /* 0x49 = looped, 0xC9 = non-looped */
+ sample_rate, /* 1 = 33 kHz, 2 = 50 kHz, 3 = 16 kHz */
+ atc_length[3], /* I'll get to this... */
+ rpt_length[3],
+ unused[2]; /* set these to null, to be on the safe side */
+} ;
+
+static unsigned char magic1[4] = {0, 0x06, 0x10, 0xF6};
+static unsigned char magic2[4] = {0, 0x52, 0x00, 0x52};
+
+static LONG tx16w_len=0;
+static LONG writedone=0;
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void txwstartread(ft)
+ ft_t ft;
+{
+ int c;
+ char filetype[7];
+ char format;
+ char sample_rate;
+ LONG num_samp_bytes = 0;
+ char dummy;
+ char gunk[8];
+ int blewIt;
+
+ txw_t sk = (txw_t) ft->priv;
+ /* If you need to seek around the input file. */
+ if (! ft->seekable)
+ fail("txw input file must be a file, not a pipe");
+
+ /* This is dumb but portable, just count the bytes til EOF */
+ while ( getc(ft->fp) != EOF )
+ num_samp_bytes++;
+ num_samp_bytes -= 32; /* calculate num samples by sub header size */
+ fseek(ft->fp,0L,0); /* rewind file */
+ sk->rest = num_samp_bytes; /* set how many sample bytes to read */
+
+ /* first 6 bytes are file type ID LM8953 */
+ filetype[0] = getc(ft->fp);
+ filetype[1] = getc(ft->fp);
+ filetype[2] = getc(ft->fp);
+ filetype[3] = getc(ft->fp);
+ filetype[4] = getc(ft->fp);
+ filetype[5] = getc(ft->fp);
+ filetype[6] = '\0';
+ for( c = 16; c > 0 ; c-- ) /* Discard next 16 bytes */
+ dummy = getc(ft->fp); /* they have no meaning here */
+ format = getc(ft->fp);
+ sample_rate = getc(ft->fp);
+ /*
+ * save next 8 bytes - if sample rate is 0, then we need
+ * to look at gunk[2] and gunk[5] to get real rate
+ */
+ for( c = 0; c < 8; c++ )
+ gunk[c] = getc(ft->fp);
+ /*
+ * We should now be pointing at start of raw sample data in file
+ */
+
+ /* Check to make sure we got a good filetype ID from file */
+ report("Found header filetype %s",filetype);
+ if(strcmp(filetype,"LM8953"))
+ fail("Invalid filetype ID in input file header, != LM8953");
+ /*
+ * Set up the sample rate as indicated by the header
+ */
+
+ switch( sample_rate ) {
+ case 1:
+ ft->info.rate = 33000;
+ break;
+ case 2:
+ ft->info.rate = 50000;
+ break;
+ case 3:
+ ft->info.rate = 16000;
+ break;
+ default:
+ blewIt = 1;
+ switch( gunk[2] & 0xFE ) {
+ case 0x06:
+ if ( (gunk[5] & 0xFE) == 0x52 ) {
+ blewIt = 0;
+ ft->info.rate = 33000;
+ }
+ break;
+ case 0x10:
+ if ( (gunk[5] & 0xFE) == 0x00 ) {
+ blewIt = 0;
+ ft->info.rate = 50000;
+ }
+ break;
+ case 0xF6:
+ if ( (gunk[5] & 0xFE) == 0x52 ) {
+ blewIt = 0;
+ ft->info.rate = 16000;
+ }
+ break;
+ }
+ if ( blewIt ) {
+ report("Invalid sample rate identifier found %d", (int)sample_rate);
+ ft->info.rate = 33000;
+ }
+ }
+ report("Sample rate = %ld",ft->info.rate);
+
+ ft->info.channels = 1 ; /* not sure about stereo sample data yet ??? */
+ ft->info.size = WORD; /* this is close enough */
+ ft->info.style = SIGN2;
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed LONGs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG txwread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ txw_t sk = (txw_t) ft->priv;
+ int done = 0;
+ unsigned char uc1,uc2,uc3;
+ unsigned short s1,s2;
+
+ /*
+ * This gets called by the top level 'process' routine.
+ * We will essentially get called with a buffer pointer
+ * and a max length to read. Graciously, it is always
+ * an even amount so we don't have to worry about
+ * hanging onto the left over odd samples since there
+ * won't be any. Something to look out for though :-(
+ * We return the number of samples we read.
+ * We will get called over and over again until we return
+ * 0 bytes read.
+ */
+
+ /*
+ * This is ugly but it's readable!
+ * Read three bytes from stream, then decompose these into
+ * two unsigned short samples.
+ * TCC 3.0 appeared to do unwanted things, so we really specify
+ * exactly what we want to happen.
+ * Convert unsigned short to LONG then shift up the result
+ * so that the 12-bit sample lives in the most significant
+ * 12-bits of the LONG.
+ * This gets our two samples into the internal format which we
+ * deposit into the given buffer and adjust our counts respectivly.
+ */
+ for(done = 0; done < len; ) {
+ if(sk->rest <= 0) break; /* Finished reading from file? */
+ uc1 = (unsigned char)getc(ft->fp); /* read the three bytes */
+ uc2 = (unsigned char)getc(ft->fp);
+ uc3 = (unsigned char)getc(ft->fp);
+ sk->rest -= 3; /* adjust remaining for bytes we just read */
+ s1 = (unsigned short) (uc1 << 4) | (((uc2 >> 4) & 017));
+ s2 = (unsigned short) (uc3 << 4) | (( uc2 & 017 ));
+ *buf = (LONG) s1;
+ *buf = (*buf << 20);
+ buf++; /* sample one is done */
+ *buf = (LONG) s2;
+ *buf = (*buf << 20);
+ buf++; /* sample two is done */
+ done += 2; /* adjust converted & stored sample count */
+ }
+ return done;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void txwstopread(ft)
+ft_t ft;
+{
+}
+
+void txwstartwrite(ft)
+ft_t ft;
+{
+ struct WaveHeader_ WH;
+
+ report("tx16w selected output");
+
+ if (ft->info.channels != 1)
+ report("tx16w is overriding output format to 1 channel.");
+ ft->info.channels = 1 ; /* not sure about stereo sample data yet ??? */
+ if (ft->info.size != WORD || ft->info.style != SIGN2)
+ report("tx16w is overriding output format to size Signed Word format.");
+ ft->info.size = WORD; /* this is close enough */
+ ft->info.style = SIGN2;
+
+ /* If you have to seek around the output file */
+ if (! ft->seekable)
+ fail("Output .txw file must be a file, not a pipe");
+
+ /* dummy numbers, just for place holder, real header is written
+ at end of processing, since byte count is needed */
+
+ fwrite(&WH,1,32,ft->fp);
+ writedone = 32;
+}
+
+void txwwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ int i;
+ unsigned int w1,w2;
+
+ tx16w_len += len;
+ if (tx16w_len > TXMAXLEN) return;
+
+ for (i=0;i<len;i+=2) {
+ w1 = *buf++ >> 20;
+ if (i+1==len)
+ w2 = 0;
+ else {
+ w2 = *buf++ >> 20;
+ }
+ putc((w1 >> 4) & 0xFF,ft->fp);
+ putc((((w1 & 0x0F) << 4) | (w2 & 0x0F)) & 0xFF,ft->fp);
+ putc((w2 >> 4) & 0xFF,ft->fp);
+ writedone += 3;
+ }
+}
+
+void txwstopwrite(ft)
+ft_t ft;
+{
+ struct WaveHeader_ WH;
+ int AttackLength, LoopLength, i;
+
+ /* All samples are already written out. */
+ /* If file header needs fixing up, for example it needs the */
+ /* the number of samples in a field, seek back and write them here. */
+
+ /* If your format specifies any of the following info. */
+ /*
+ ft->info.rate =
+ ft->info.size = BYTE or WORD ...;
+ ft->info.style = UNSIGNED or SIGN2 ...;
+ ft->info.channels = 1 or 2 or 4;
+ */
+
+ report("tx16w:output finished");
+
+ strncpy(WH.filetype,"LM8953",6);
+ for (i=0;i<10;i++) WH.nulls[i]=0;
+ for (i=0;i<6;i++) WH.dummy_aeg[i]=0;
+ for (i=0;i<2;i++) WH.unused[i]=0;
+ for (i=0;i<2;i++) WH.dummy_aeg[i] = 0;
+ for (i=2;i<6;i++) WH.dummy_aeg[i] = 0x7F;
+
+ WH.format = 0xC9; /* loop off */
+
+ /* the actual sample rate is not that important ! */
+ if (ft->info.rate < 24000) WH.sample_rate = 3;
+ else if (ft->info.rate < 41000) WH.sample_rate = 1;
+ else WH.sample_rate = 2;
+
+ if (tx16w_len >= TXMAXLEN) {
+ fprintf(stderr,"Sound too large for TX16W. Truncating, Loop Off\n");
+ AttackLength = TXMAXLEN/2;
+ LoopLength = TXMAXLEN/2;
+ }
+ else if (tx16w_len >=TXMAXLEN/2) {
+ AttackLength = TXMAXLEN/2;
+ LoopLength = tx16w_len - TXMAXLEN/2;
+ if (LoopLength < 0x40) {
+ LoopLength +=0x40;
+ AttackLength -= 0x40;
+ }
+ }
+ else if (tx16w_len >= 0x80) {
+ AttackLength = tx16w_len -0x40;
+ LoopLength = 0x40;
+ }
+ else {
+ AttackLength = 0x40;
+ LoopLength = 0x40;
+ for(i=tx16w_len;i<0x80;i++) {
+ putc(0,ft->fp);
+ putc(0,ft->fp);
+ putc(0,ft->fp);
+ writedone += 3;
+ }
+ }
+
+ /* Fill up to 256 byte blocks; the TX16W seems to like that */
+
+ while ((writedone % 0x100) != 0) {
+ putc(0,ft->fp);
+ writedone++;
+ }
+
+ WH.atc_length[0] = 0xFF & AttackLength;
+ WH.atc_length[1] = 0xFF & (AttackLength >> 8);
+ WH.atc_length[2] = (0x01 & (AttackLength >> 16)) +
+ magic1[WH.sample_rate];
+
+ WH.rpt_length[0] = 0xFF & LoopLength;
+ WH.rpt_length[1] = 0xFF & (LoopLength >> 8);
+ WH.rpt_length[2] = (0x01 & (LoopLength >> 16)) +
+ magic2[WH.sample_rate];
+
+ rewind(ft->fp);
+ fwrite(&WH,1,32,ft->fp);
+}
--- /dev/null
+++ b/src/util.c
@@ -1,0 +1,274 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#include "st.h"
+#include "version.h"
+#include "patchlvl.h"
+#include <string.h>
+#include <ctype.h>
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/*
+ * util.c.
+ * Incorporate Jimen Ching's fixes for real library operation: Aug 3, 1994.
+ * Redo all work from scratch, unfortunately.
+ * Separate out all common variables used by effects & handlers,
+ * and utility routines for other main programs to use.
+ */
+
+
+EXPORT float volume = 1.0; /* expansion coefficient */
+EXPORT int dovolume = 0;
+
+EXPORT float amplitude = 1.0; /* Largest sample so far */
+
+EXPORT int writing = 0; /* are we writing to a file? */
+
+/* export flags */
+EXPORT int verbose = 0; /* be noisy on stderr */
+EXPORT int summary = 0; /* just print summary of information */
+
+EXPORT char *myname;
+
+EXPORT int soxpreview = 0; /* preview mode */
+
+
+void
+#if defined(__STDC__)
+report(char *fmt, ...)
+#else
+report(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#if !defined(__STDC__)
+ char *fmt;
+#endif
+
+ if (! verbose)
+ return;
+ fprintf(stderr, "%s: ", myname);
+#if !defined(__STDC__)
+ va_start(args);
+ fmt = va_arg(args, char *);
+#else
+ va_start(args, fmt);
+#endif
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+}
+
+
+void
+#if defined(__STDC__)
+warn(char *fmt, ...)
+#else
+warn(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#if !defined(__STDC__)
+ char *fmt;
+#endif
+
+ fprintf(stderr, "%s: ", myname);
+#if !defined(__STDC__)
+ va_start(args);
+ fmt = va_arg(args, char *);
+#else
+ va_start(args, fmt);
+#endif
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+}
+
+void
+#if defined(__STDC__)
+fail(char *fmt, ...)
+#else
+fail(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#if !defined(__STDC__)
+ char *fmt;
+#endif
+ extern void cleanup();
+
+ fprintf(stderr, "%s: ", myname);
+
+#if !defined(__STDC__)
+ va_start(args);
+ fmt = va_arg(args, char *);
+#else
+ va_start(args, fmt);
+#endif
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ cleanup();
+ exit(2);
+}
+
+
+int strcmpcase(s1, s2)
+char *s1, *s2;
+{
+ while(*s1 && *s2 && (tolower(*s1) == tolower(*s2)))
+ s1++, s2++;
+ return *s1 - *s2;
+}
+
+/*
+ * Check that we have a known format suffix string.
+ */
+void
+gettype(formp)
+ft_t formp;
+{
+ char **list;
+ int i;
+
+ if (! formp->filetype)
+fail("Must give file type for %s file, either as suffix or with -t option",
+formp->filename);
+ for(i = 0; formats[i].names; i++) {
+ for(list = formats[i].names; *list; list++) {
+ char *s1 = *list, *s2 = formp->filetype;
+ if (! strcmpcase(s1, s2))
+ break; /* not a match */
+ }
+ if (! *list)
+ continue;
+ /* Found it! */
+ formp->h = &formats[i];
+ return;
+ }
+ if (! strcmpcase(formp->filetype, "snd")) {
+ verbose = 1;
+ report("File type '%s' is used to name several different formats.", formp->filetype);
+ report("If the file came from a Macintosh, it is probably");
+ report("a .ub file with a sample rate of 11025 (or possibly 5012 or 22050).");
+ report("Use the sequence '-t .ub -r 11025 file.snd'");
+ report("If it came from a PC, it's probably a Soundtool file.");
+ report("Use the sequence '-t .sndt file.snd'");
+ report("If it came from a NeXT, it's probably a .au file.");
+ fail("Use the sequence '-t .au file.snd'\n");
+ }
+ fail("File type '%s' of %s file is not known!",
+ formp->filetype, formp->filename);
+}
+
+/*
+ * Check that we have a known effect name.
+ */
+void
+geteffect(effp)
+eff_t effp;
+{
+ int i;
+
+ for(i = 0; effects[i].name; i++) {
+ char *s1 = effects[i].name, *s2 = effp->name;
+ while(*s1 && *s2 && (tolower(*s1) == tolower(*s2)))
+ s1++, s2++;
+ if (*s1 || *s2)
+ continue; /* not a match */
+ /* Found it! */
+ effp->h = &effects[i];
+ return;
+ }
+ /* Guido Van Rossum fix */
+ fprintf(stderr, "%s: Known effects: ",myname);
+ for (i = 1; effects[i].name; i++)
+ fprintf(stderr, "%s ", effects[i].name);
+ fprintf(stderr, "\n");
+ fail("Effect '%s' is not known!", effp->name);
+}
+
+/*
+ * File format routines
+ */
+
+void copyformat(ft, ft2)
+ft_t ft, ft2;
+{
+ int noise = 0, i;
+ double factor;
+
+ if (ft2->info.rate == 0) {
+ ft2->info.rate = ft->info.rate;
+ noise = 1;
+ }
+ if (ft2->info.size == -1) {
+ ft2->info.size = ft->info.size;
+ noise = 1;
+ }
+ if (ft2->info.style == -1) {
+ ft2->info.style = ft->info.style;
+ noise = 1;
+ }
+ if (ft2->info.channels == -1) {
+ ft2->info.channels = ft->info.channels;
+ noise = 1;
+ }
+ if (ft2->comment == NULL) {
+ ft2->comment = ft->comment;
+ noise = 1;
+ }
+ /*
+ * copy loop info, resizing appropriately
+ * it's in samples, so # channels don't matter
+ */
+ factor = (double) ft2->info.rate / (double) ft->info.rate;
+ for(i = 0; i < NLOOPS; i++) {
+ ft2->loops[i].start = ft->loops[i].start * factor;
+ ft2->loops[i].length = ft->loops[i].length * factor;
+ ft2->loops[i].count = ft->loops[i].count;
+ ft2->loops[i].type = ft->loops[i].type;
+ }
+ /* leave SMPTE # alone since it's absolute */
+ ft2->instr = ft->instr;
+}
+
+void cmpformats(ft, ft2)
+ft_t ft, ft2;
+{
+}
+
+/* check that all settings have been given */
+void checkformat(ft)
+ft_t ft;
+{
+ if (ft->info.rate == 0)
+ fail("Sampling rate for %s file was not given\n", ft->filename);
+ if ((ft->info.rate < 100) || (ft->info.rate > 50000L))
+ fail("Sampling rate %lu for %s file is bogus\n",
+ ft->info.rate, ft->filename);
+ if (ft->info.size == -1)
+ fail("Data size was not given for %s file\nUse one of -b/-w/-l/-f/-d/-D", ft->filename);
+ if (ft->info.style == -1 && ft->info.size != FLOAT)
+ fail("Data style was not given for %s file\nUse one of -s/-u/-U/-A", ft->filename);
+ /* it's so common, might as well default */
+ if (ft->info.channels == -1)
+ ft->info.channels = 1;
+ /* fail("Number of output channels was not given for %s file",
+ ft->filename); */
+}
+
--- /dev/null
+++ b/src/vibro.c
@@ -1,0 +1,134 @@
+/*
+ * Sound Tools Vibro effect file.
+ *
+ * Modeled on world-famous Fender(TM) Amp Vibro knobs.
+ *
+ * Algorithm: generate a sine wave ranging from
+ * 0 + depth to 1.0, where signal goes from -1.0 to 1.0.
+ * Multiply signal with sine wave. I think.
+ *
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * April 28, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ *
+ * Rearranged some functions so that they are declared before they are
+ * used. Clears up some compiler warnings. Because this functions passed
+ * foats, it helped out some dump compilers pass stuff on the stack
+ * correctly.
+ *
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include "st.h"
+
+/* Private data for Vibro effect */
+typedef struct vibrostuff {
+ float speed;
+ float depth;
+ short *sinetab; /* sine wave to apply */
+ int mult; /* multiplier */
+ unsigned length; /* length of table */
+ int counter; /* current counter */
+} *vibro_t;
+
+/*
+ * Process options
+ */
+void vibro_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ vibro_t vibro = (vibro_t) effp->priv;
+
+ vibro->depth = 0.5;
+ if ((n == 0) || !sscanf(argv[0], "%f", &vibro->speed) ||
+ ((n == 2) && !sscanf(argv[1], "%f", &vibro->depth)))
+ fail("Usage: vibro speed [ depth ]");
+ if ((vibro->speed <= 0.001) || (vibro->speed > 30.0) ||
+ (vibro->depth < 0.0) || (vibro->depth > 1.0))
+ fail("Vibro: speed must be < 30.0, 0.0 < depth < 1.0");
+}
+
+/* This was very painful. We need a sine library. */
+
+void sine(buf, len, depth)
+short *buf;
+int len;
+float depth;
+{
+ int i;
+ int scale = depth * 128;
+ int base = (1.0 - depth) * 128;
+ double val;
+
+ for (i = 0; i < len; i++) {
+ val = sin((float)i/(float)len * 2.0 * M_PI);
+ buf[i] = (val + 1.0) * scale + base * 2;
+ }
+}
+
+/*
+ * Prepare processing.
+ */
+void vibro_start(effp)
+eff_t effp;
+{
+ vibro_t vibro = (vibro_t) effp->priv;
+
+ vibro->length = effp->ininfo.rate / vibro->speed;
+ if (! (vibro->sinetab = (short*) malloc(vibro->length * sizeof(short))))
+ fail("Vibro: Cannot malloc %d bytes",
+ vibro->length * sizeof(short));
+
+ sine(vibro->sinetab, vibro->length, vibro->depth);
+ vibro->counter = 0;
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+void vibro_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+int *isamp, *osamp;
+{
+ vibro_t vibro = (vibro_t) effp->priv;
+ register int counter, tablen;
+ int len, done;
+ short *sinetab;
+ LONG l;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+
+ sinetab = vibro->sinetab;
+ counter = vibro->counter;
+ tablen = vibro->length;
+ for(done = 0; done < len; done++) {
+ l = *ibuf++;
+ /* 24x8 gives 32-bit result */
+ *obuf++ = ((l / 256) * sinetab[counter++ % tablen]);
+ }
+ vibro->counter = counter;
+ /* processed all samples */
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void vibro_stop(effp)
+eff_t effp;
+{
+ /* nothing to do */
+}
+
--- /dev/null
+++ b/src/voc.c
@@ -1,0 +1,568 @@
+/*
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * September 8, 1993
+ * Copyright 1993 T. Allen Grider - for changes to support block type 9
+ * and word sized samples. Same caveats and disclaimer as above.
+ *
+ * February 22, 1996
+ * by Chris Bagwell (cbagwell@sprynet.com)
+ * Added support for block type 8 (extended) which allows for 8-bit stereo
+ * files. Added support for saving stereo files and 16-bit files.
+ * Added VOC format info from audio format FAQ so I don't have to keep
+ * looking around for it.
+ */
+
+/*
+ * Sound Tools Sound Blaster VOC handler sources.
+ */
+
+/*------------------------------------------------------------------------
+The following is taken from the Audio File Formats FAQ dated 2-Jan-1995
+and submitted by Guido van Rossum <guido@cwi.nl>.
+--------------------------------------------------------------------------
+Creative Voice (VOC) file format
+--------------------------------
+
+From: galt@dsd.es.com
+
+(byte numbers are hex!)
+
+ HEADER (bytes 00-19)
+ Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
+
+- ---------------------------------------------------------------
+
+HEADER:
+-------
+ byte # Description
+ ------ ------------------------------------------
+ 00-12 "Creative Voice File"
+ 13 1A (eof to abort printing of file)
+ 14-15 Offset of first datablock in .voc file (std 1A 00
+ in Intel Notation)
+ 16-17 Version number (minor,major) (VOC-HDR puts 0A 01)
+ 18-19 2's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
+
+- ---------------------------------------------------------------
+
+DATA BLOCK:
+-----------
+
+ Data Block: TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
+ NOTE: Terminator Block is an exception -- it has only the TYPE byte.
+
+ TYPE Description Size (3-byte int) Info
+ ---- ----------- ----------------- -----------------------
+ 00 Terminator (NONE) (NONE)
+ 01 Sound data 2+length of data *
+ 02 Sound continue length of data Voice Data
+ 03 Silence 3 **
+ 04 Marker 2 Marker# (2 bytes)
+ 05 ASCII length of string null terminated string
+ 06 Repeat 2 Count# (2 bytes)
+ 07 End repeat 0 (NONE)
+ 08 Extended 4 ***
+
+ *Sound Info Format: **Silence Info Format:
+ --------------------- ----------------------------
+ 00 Sample Rate 00-01 Length of silence - 1
+ 01 Compression Type 02 Sample Rate
+ 02+ Voice Data
+
+ ***Extended Info Format:
+ ---------------------
+ 00-01 Time Constant: Mono: 65536 - (256000000/sample_rate)
+ Stereo: 65536 - (25600000/(2*sample_rate))
+ 02 Pack
+ 03 Mode: 0 = mono
+ 1 = stereo
+
+
+ Marker# -- Driver keeps the most recent marker in a status byte
+ Count# -- Number of repetitions + 1
+ Count# may be 1 to FFFE for 0 - FFFD repetitions
+ or FFFF for endless repetitions
+ Sample Rate -- SR byte = 256-(1000000/sample_rate)
+ Length of silence -- in units of sampling cycle
+ Compression Type -- of voice data
+ 8-bits = 0
+ 4-bits = 1
+ 2.6-bits = 2
+ 2-bits = 3
+ Multi DAC = 3+(# of channels) [interesting--
+ this isn't in the developer's manual]
+
+Detailed description of new data blocks (VOC files version 1.20 and above):
+
+ (Source is fax from Barry Boone at Creative Labs, 405/742-6622)
+
+BLOCK 8 - digitized sound attribute extension, must preceed block 1.
+ Used to define stereo, 8 bit audio
+ BYTE bBlockID; // = 8
+ BYTE nBlockLen[3]; // 3 byte length
+ WORD wTimeConstant; // time constant = same as block 1
+ BYTE bPackMethod; // same as in block 1
+ BYTE bVoiceMode; // 0-mono, 1-stereo
+
+ Data is stored left, right
+
+BLOCK 9 - data block that supersedes blocks 1 and 8.
+ Used for stereo, 16 bit.
+
+ BYTE bBlockID; // = 9
+ BYTE nBlockLen[3]; // length 12 plus length of sound
+ DWORD dwSamplesPerSec; // samples per second, not time const.
+ BYTE bBitsPerSample; // e.g., 8 or 16
+ BYTE bChannels; // 1 for mono, 2 for stereo
+ WORD wFormat; // see below
+ BYTE reserved[4]; // pad to make block w/o data
+ // have a size of 16 bytes
+
+ Valid values of wFormat are:
+
+ 0x0000 8-bit unsigned PCM
+ 0x0001 Creative 8-bit to 4-bit ADPCM
+ 0x0002 Creative 8-bit to 3-bit ADPCM
+ 0x0003 Creative 8-bit to 2-bit ADPCM
+ 0x0004 16-bit signed PCM
+ 0x0006 CCITT a-Law
+ 0x0007 CCITT u-Law
+ 0x02000 Creative 16-bit to 4-bit ADPCM
+
+ Data is stored left, right
+
+------------------------------------------------------------------------*/
+
+#include "st.h"
+#include <string.h>
+
+/* Private data for VOC file */
+typedef struct vocstuff {
+ LONG rest; /* bytes remaining in current block */
+ LONG rate; /* rate code (byte) of this chunk */
+ int silent; /* sound or silence? */
+ LONG srate; /* rate code (byte) of silence */
+ LONG blockseek; /* start of current output block */
+ LONG samples; /* number of samples output */
+ int size; /* word length of data */
+ int channels; /* number of sound channels */
+ int extended; /* Has an extended block been read? */
+} *vs_t;
+
+#define VOC_TERM 0
+#define VOC_DATA 1
+#define VOC_CONT 2
+#define VOC_SILENCE 3
+#define VOC_MARKER 4
+#define VOC_TEXT 5
+#define VOC_LOOP 6
+#define VOC_LOOPEND 7
+#define VOC_EXTENDED 8
+#define VOC_DATA_16 9
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+void getblock();
+void blockstart(P1(ft_t));
+void blockstop(P1(ft_t));
+
+void vocstartread(ft)
+ft_t ft;
+{
+ char header[20];
+ vs_t v = (vs_t) ft->priv;
+ int sbseek;
+
+ if (! ft->seekable)
+ fail("VOC input file must be a file, not a pipe");
+ if (fread(header, 1, 20, ft->fp) != 20)
+ fail("unexpected EOF in VOC header");
+ if (strncmp(header, "Creative Voice File\032", 19))
+ fail("VOC file header incorrect");
+
+ sbseek = rlshort(ft);
+ fseek(ft->fp, sbseek, 0);
+
+ v->rate = -1;
+ v->rest = 0;
+ v->extended = 0;
+ getblock(ft);
+ if (v->rate == -1)
+ fail("Input .voc file had no sound!");
+
+ ft->info.size = v->size;
+ ft->info.style = UNSIGNED;
+ if (v->size == WORD)
+ ft->info.style = SIGN2;
+ if (ft->info.channels == -1)
+ ft->info.channels = v->channels;
+}
+
+LONG vocread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ vs_t v = (vs_t) ft->priv;
+ int done = 0;
+
+ if (v->rest == 0)
+ getblock(ft);
+ if (v->rest == 0)
+ return 0;
+
+ if (v->silent) {
+ /* Fill in silence */
+ for(;v->rest && (done < len); v->rest--, done++)
+ *buf++ = 0x80000000L;
+ } else {
+ for(;v->rest && (done < len); v->rest--, done++) {
+ LONG l1, l2;
+ switch(v->size)
+ {
+ case BYTE:
+ if ((l1 = getc(ft->fp)) == EOF) {
+ fail("VOC input: short file"); /* */
+ v->rest = 0;
+ return 0;
+ }
+ l1 ^= 0x80; /* convert to signed */
+ *buf++ = LEFT(l1, 24);
+ break;
+ case WORD:
+ l1 = getc(ft->fp);
+ l2 = getc(ft->fp);
+ if (l1 == EOF || l2 == EOF)
+ {
+ fail("VOC input: short file");
+ v->rest = 0;
+ return 0;
+ }
+ l1 = (l2 << 8) | l1; /* already sign2 */
+ *buf++ = LEFT(l1, 16);
+ v->rest--;
+ break;
+ }
+ }
+ }
+ return done;
+}
+
+/* nothing to do */
+void vocstopread(ft)
+ft_t ft;
+{
+}
+
+/* When saving samples in VOC format the following outline is followed:
+ * If an 8-bit mono sample then use a VOC_DATA header.
+ * If an 8-bit stereo sample then use a VOC_EXTENDED header followed
+ * by a VOC_DATA header.
+ * If a 16-bit sample (either stereo or mono) then save with a
+ * VOC_DATA_16 header.
+ *
+ * This approach will cause the output to be an its most basic format
+ * which will work with the oldest software (eg. an 8-bit mono sample
+ * will be able to be played with a really old SB VOC player.)
+ */
+void vocstartwrite(ft)
+ft_t ft;
+{
+ vs_t v = (vs_t) ft->priv;
+
+ if (! ft->seekable)
+ fail("Output .voc file must be a file, not a pipe");
+
+ v->samples = 0;
+
+ /* File format name and a ^Z (aborts printing under DOS) */
+ (void) fwrite("Creative Voice File\032\032", 1, 20, ft->fp);
+ wlshort(ft, 26); /* size of header */
+ wlshort(ft, 0x10a); /* major/minor version number */
+ wlshort(ft, 0x1129); /* checksum of version number */
+
+ if (ft->info.size == BYTE)
+ ft->info.style = UNSIGNED;
+ else
+ ft->info.style = SIGN2;
+ if (ft->info.channels == -1)
+ ft->info.channels = 1;
+}
+
+void vocwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ vs_t v = (vs_t) ft->priv;
+ unsigned char uc;
+ int sw;
+
+ if (v->samples == 0) {
+ /* No silence packing yet. */
+ v->silent = 0;
+ blockstart(ft);
+ }
+ v->samples += len;
+ while(len--) {
+ if (ft->info.size == BYTE) {
+ uc = RIGHT(*buf++, 24);
+ uc ^= 0x80;
+ putc(uc, ft->fp);
+ } else {
+ sw = (int) RIGHT(*buf++, 16);
+ wlshort(ft,sw);
+ }
+ }
+}
+
+void vocstopwrite(ft)
+ft_t ft;
+{
+ blockstop(ft);
+}
+
+/* Voc-file handlers */
+
+/* Read next block header, save info, leave position at start of data */
+void
+getblock(ft)
+ft_t ft;
+{
+ vs_t v = (vs_t) ft->priv;
+ unsigned char uc, block;
+ ULONG sblen;
+ LONG new_rate;
+ int i;
+
+ v->silent = 0;
+ while (v->rest == 0) {
+ if (feof(ft->fp))
+ return;
+ block = getc(ft->fp);
+ if (block == VOC_TERM)
+ return;
+ if (feof(ft->fp))
+ return;
+ uc = getc(ft->fp);
+ sblen = uc;
+ uc = getc(ft->fp);
+ sblen |= ((LONG) uc) << 8;
+ uc = getc(ft->fp);
+ sblen |= ((LONG) uc) << 16;
+ switch(block) {
+ case VOC_DATA:
+ uc = getc(ft->fp);
+ /* When DATA block preceeded by an EXTENDED */
+ /* block, the DATA blocks rate value is invalid */
+ if (!v->extended) {
+ if (uc == 0)
+ fail("File %s: Sample rate is zero?");
+ if ((v->rate != -1) && (uc != v->rate))
+ fail("File %s: sample rate codes differ: %d != %d",
+ ft->filename,v->rate, uc);
+ v->rate = uc;
+ ft->info.rate = 1000000.0/(256 - v->rate);
+ v->channels = 1;
+ }
+ uc = getc(ft->fp);
+ if (uc != 0)
+ fail("File %s: only interpret 8-bit data!",
+ ft->filename);
+ v->extended = 0;
+ v->rest = sblen - 2;
+ v->size = BYTE;
+ return;
+ case VOC_DATA_16:
+ new_rate = rllong(ft);
+ if (new_rate == 0)
+ fail("File %s: Sample rate is zero?",ft->filename);
+ if ((v->rate != -1) && (new_rate != v->rate))
+ fail("File %s: sample rate codes differ: %d != %d",
+ ft->filename, v->rate, new_rate);
+ v->rate = new_rate;
+ ft->info.rate = new_rate;
+ uc = getc(ft->fp);
+ switch (uc)
+ {
+ case 8: v->size = BYTE; break;
+ case 16: v->size = WORD; break;
+ default: fail("Don't understand size %d", uc);
+ }
+ v->channels = getc(ft->fp);
+ getc(ft->fp); /* unknown1 */
+ getc(ft->fp); /* notused */
+ getc(ft->fp); /* notused */
+ getc(ft->fp); /* notused */
+ getc(ft->fp); /* notused */
+ getc(ft->fp); /* notused */
+ v->rest = sblen - 12;
+ return;
+ case VOC_CONT:
+ v->rest = sblen;
+ return;
+ case VOC_SILENCE:
+ {
+ unsigned short period;
+
+ period = rlshort(ft);
+ uc = getc(ft->fp);
+ if (uc == 0)
+ fail("File %s: Silence sample rate is zero");
+ /*
+ * Some silence-packed files have gratuitously
+ * different sample rate codes in silence.
+ * Adjust period.
+ */
+ if ((v->rate != -1) && (uc != v->rate))
+ period = (period * (256 - uc))/(256 - v->rate);
+ else
+ v->rate = uc;
+ v->rest = period;
+ v->silent = 1;
+ return;
+ }
+ case VOC_MARKER:
+ uc = getc(ft->fp);
+ uc = getc(ft->fp);
+ /* Falling! Falling! */
+ case VOC_TEXT:
+ {
+ int i;
+ /* Could add to comment in SF? */
+ for(i = 0; i < sblen; i++)
+ getc(ft->fp);
+ }
+ continue; /* get next block */
+ case VOC_LOOP:
+ case VOC_LOOPEND:
+ report("File %s: skipping repeat loop");
+ for(i = 0; i < sblen; i++)
+ getc(ft->fp);
+ break;
+ case VOC_EXTENDED:
+ /* An Extended block is followed by a data block */
+ /* Set this byte so we know to use the rate */
+ /* value from the extended block and not the */
+ /* data block. */
+ v->extended = 1;
+ new_rate = rlshort(ft);
+ if (new_rate == 0)
+ fail("File %s: Sample rate is zero?");
+ if ((v->rate != -1) && (new_rate != v->rate))
+ fail("File %s: sample rate codes differ: %d != %d",
+ ft->filename, v->rate, new_rate);
+ v->rate = new_rate;
+ uc = getc(ft->fp);
+ if (uc != 0)
+ fail("File %s: only interpret 8-bit data!",
+ ft->filename);
+ uc = getc(ft->fp);
+ if (uc)
+ ft->info.channels = 2; /* Stereo */
+ /* Needed number of channels before finishing
+ compute for rate */
+ ft->info.rate = (256000000L/(65536L - v->rate))/ft->info.channels;
+ /* An extended block must be followed by a data */
+ /* block to be valid so loop back to top so it */
+ /* can be grabed. */
+ continue;
+ default:
+ report("File %s: skipping unknown block code %d",
+ ft->filename, block);
+ for(i = 0; i < sblen; i++)
+ getc(ft->fp);
+ }
+ }
+}
+
+/* Start an output block. */
+void blockstart(ft)
+ft_t ft;
+{
+ vs_t v = (vs_t) ft->priv;
+
+ v->blockseek = ftell(ft->fp);
+ if (v->silent) {
+ putc(VOC_SILENCE, ft->fp); /* Silence block code */
+ putc(0, ft->fp); /* Period length */
+ putc(0, ft->fp); /* Period length */
+ putc((int) v->rate, ft->fp); /* Rate code */
+ } else {
+ if (ft->info.size == BYTE) {
+ /* 8-bit sample section. By always setting the correct */
+ /* rate value in the DATA block (even when its preceeded */
+ /* by an EXTENDED block) old software can still play stereo */
+ /* files in mono by just skipping over the EXTENDED block. */
+ /* Prehaps the rate should be doubled though to make up for */
+ /* double amount of samples for a given time???? */
+ if (ft->info.channels > 1) {
+ putc(VOC_EXTENDED, ft->fp); /* Voice Extended block code */
+ putc(4, ft->fp); /* block length = 4 */
+ putc(0, ft->fp); /* block length = 4 */
+ putc(0, ft->fp); /* block length = 4 */
+ v->rate = 65536L - (256000000.0/(2*(float)ft->info.rate));
+ wlshort(ft,v->rate); /* Rate code */
+ putc(0, ft->fp); /* File is not packed */
+ putc(1, ft->fp); /* samples are in stereo */
+ }
+ putc(VOC_DATA, ft->fp); /* Voice Data block code */
+ putc(0, ft->fp); /* block length (for now) */
+ putc(0, ft->fp); /* block length (for now) */
+ putc(0, ft->fp); /* block length (for now) */
+ v->rate = 256 - (1000000.0/(float)ft->info.rate);
+ putc((int) v->rate, ft->fp);/* Rate code */
+ putc(0, ft->fp); /* 8-bit raw data */
+ } else {
+ putc(VOC_DATA_16, ft->fp); /* Voice Data block code */
+ putc(0, ft->fp); /* block length (for now) */
+ putc(0, ft->fp); /* block length (for now) */
+ putc(0, ft->fp); /* block length (for now) */
+ v->rate = ft->info.rate;
+ wllong(ft, v->rate); /* Rate code */
+ putc(16, ft->fp); /* Sample Size */
+ putc(ft->info.channels, ft->fp); /* Sample Size */
+ putc(0, ft->fp); /* Unknown */
+ putc(0, ft->fp); /* Unused */
+ putc(0, ft->fp); /* Unused */
+ putc(0, ft->fp); /* Unused */
+ putc(0, ft->fp); /* Unused */
+ putc(0, ft->fp); /* Unused */
+ }
+ }
+}
+
+/* End the current data or silence block. */
+void blockstop(ft)
+ft_t ft;
+{
+ vs_t v = (vs_t) ft->priv;
+ LONG datum;
+
+ putc(0, ft->fp); /* End of file block code */
+ fseek(ft->fp, v->blockseek, 0); /* seek back to block length */
+ fseek(ft->fp, 1, 1); /* seek forward one */
+ if (v->silent) {
+ datum = (v->samples) & 0xff;
+ putc((int)datum, ft->fp); /* low byte of length */
+ datum = (v->samples >> 8) & 0xff;
+ putc((int)datum, ft->fp); /* high byte of length */
+ } else {
+ if (ft->info.size == BYTE) {
+ if (ft->info.channels > 1) {
+ fseek(ft->fp, 8, 1); /* forward 7 + 1 for new block header */
+ }
+ }
+ v->samples += 2; /* adjustment: SBDK pp. 3-5 */
+ datum = (v->samples) & 0xff;
+ putc((int)datum, ft->fp); /* low byte of length */
+ datum = (v->samples >> 8) & 0xff;
+ putc((int)datum, ft->fp); /* middle byte of length */
+ datum = (v->samples >> 16) & 0xff;
+ putc((int)datum, ft->fp); /* high byte of length */
+ }
+}
+
--- /dev/null
+++ b/src/wav.c
@@ -1,0 +1,986 @@
+/*
+ * Microsoft's WAVE sound format driver
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Change History:
+ *
+ * September 11, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Fixed length bug for IMA and MS ADPCM files.
+ *
+ * June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Fixed some compiler warnings as reported by Kjetil Torgrim Homme
+ * <kjetilho@ifi.uio.no>.
+ * Fixed bug that caused crashes when reading mono MS ADPCM files. Patch
+ * was sent from Michael Brown (mjb@pootle.demon.co.uk).
+ *
+ * March 15, 1998 - Chris Bagwell (cbagwell@sprynet.com)
+ * Added support for Microsoft's ADPCM and IMA (or better known as
+ * DVI) ADPCM format for wav files. Info on these formats
+ * was taken from the xanim project, written by
+ * Mark Podlipec (podlipec@ici.net). For those pieces of code,
+ * the following copyrights notice applies:
+ *
+ * XAnim Copyright (C) 1990-1997 by Mark Podlipec.
+ * All rights reserved.
+ *
+ * This software may be freely copied, modified and redistributed without
+ * fee for non-commerical purposes provided that this copyright notice is
+ * preserved intact on all copies and modified copies.
+ *
+ * There is no warranty or other guarantee of fitness of this software.
+ * It is provided solely "as is". The author(s) disclaim(s) all
+ * responsibility and liability with respect to this software's usage
+ * or its effect upon hardware or computer systems.
+ *
+ * NOTE: Previous maintainers weren't very good at providing contact
+ * information.
+ *
+ * Copyright 1992 Rick Richardson
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ *
+ * Fixed by various contributors previous to 1998:
+ * 1) Little-endian handling
+ * 2) Skip other kinds of file data
+ * 3) Handle 16-bit formats correctly
+ * 4) Not go into infinite loop
+ *
+ * User options should override file header - we assumed user knows what
+ * they are doing if they specify options.
+ * Enhancements and clean up by Graeme W. Gill, 93/5/17
+ */
+
+#include <string.h> /* Included for strncmp */
+#include <stdlib.h> /* Included for malloc and free */
+#include "st.h"
+#include "wav.h"
+
+/* Private data for .wav file */
+typedef struct wavstuff {
+ LONG numSamples;
+ int second_header; /* non-zero on second header write */
+ unsigned short formatTag; /* What type of encoding file is using */
+
+ /* The following are only needed for ADPCM wav files */
+ unsigned short samplesPerBlock;
+ unsigned short bytesPerBlock;
+ unsigned short blockAlign;
+ short *samples[2]; /* Left and Right sample buffers */
+ short *samplePtr[2]; /* Pointers to current samples */
+ unsigned short blockSamplesRemaining;/* Samples remaining in each channel */
+ unsigned char *packet; /* Temporary buffer for packets */
+} *wav_t;
+
+static char *wav_format_str();
+
+LONG rawread(P3(ft_t, LONG *, LONG));
+void rawwrite(P3(ft_t, LONG *, LONG));
+void wavwritehdr(P1(ft_t));
+
+
+/*
+ *
+ * Lookup tables for MS ADPCM format
+ *
+ */
+
+static LONG gaiP4[] = { 230, 230, 230, 230, 307, 409, 512, 614,
+ 768, 614, 512, 409, 307, 230, 230, 230 };
+
+/* TODO : The first 7 coef's are are always hardcode and must
+ appear in the actual WAVE file. They should be read in
+ in case a sound program added extras to the list. */
+
+static LONG gaiCoef1[] = { 256, 512, 0, 192, 240, 460, 392 };
+static LONG gaiCoef2[] = { 0, -256, 0, 64, 0,-208, -232};
+
+/*
+ *
+ * Lookup tables for IMA ADPCM format
+ *
+ */
+static int imaIndexAdjustTable[16] = {
+ -1, -1, -1, -1, /* +0 - +3, decrease the step size */
+ 2, 4, 6, 8, /* +4 - +7, increase the step size */
+ -1, -1, -1, -1, /* -0 - -3, decrease the step size */
+ 2, 4, 6, 8, /* -4 - -7, increase the step size */
+};
+
+static int imaStepSizeTable[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34,
+ 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
+ 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494,
+ 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
+ 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
+ 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
+ 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,
+ 27086, 29794, 32767
+};
+
+/****************************************************************************/
+/* IMA ADPCM Support Functions Section */
+/****************************************************************************/
+
+/*
+ *
+ * MsAdpcmDecode - Decode a given sample and update state tables
+ *
+ */
+
+short ImaAdpcmDecode(deltaCode, state)
+unsigned char deltaCode;
+ImaState_t *state;
+{
+ /* Get the current step size */
+ int step;
+ int difference;
+
+ step = imaStepSizeTable[state->index];
+
+ /* Construct the difference by scaling the current step size */
+ /* This is approximately: difference = (deltaCode+.5)*step/4 */
+ difference = step>>3;
+ if ( deltaCode & 1 ) difference += step>>2;
+ if ( deltaCode & 2 ) difference += step>>1;
+ if ( deltaCode & 4 ) difference += step;
+
+ if ( deltaCode & 8 ) difference = -difference;
+
+ /* Build the new sample */
+ state->previousValue += difference;
+
+ if (state->previousValue > 32767) state->previousValue = 32767;
+ else if (state->previousValue < -32768) state->previousValue = -32768;
+
+ /* Update the step for the next sample */
+ state->index += imaIndexAdjustTable[deltaCode];
+ if (state->index < 0) state->index = 0;
+ else if (state->index > 88) state->index = 88;
+
+ return state->previousValue;
+
+}
+
+/*
+ *
+ * ImaAdpcmNextBlock - Grab and decode complete block of samples
+ *
+ */
+unsigned short ImaAdpcmNextBlock(ft)
+ft_t ft;
+{
+ wav_t wav = (wav_t) ft->priv;
+
+ /* Pull in the packet and check the header */
+ unsigned short bytesRead;
+ unsigned char *bytePtr;
+
+ ImaState_t state[2]; /* One decompressor state for each channel */
+ int ch;
+ unsigned short remaining;
+ unsigned short samplesThisBlock;
+
+ int i;
+ unsigned char b;
+
+ bytesRead = fread(wav->packet,1,wav->blockAlign,ft->fp);
+ if (bytesRead < wav->blockAlign)
+ {
+ /* If it looks like a valid header is around then try and */
+ /* work with partial blocks. Specs say it should be null */
+ /* padded but I guess this is better then trailing quite. */
+ if (bytesRead >= (4 * ft->info.channels))
+ {
+ samplesThisBlock = (wav->blockAlign - (3 * ft->info.channels));
+ }
+ else
+ {
+ warn ("Premature EOF on .wav input file");
+ return 0;
+ }
+ }
+ else
+ samplesThisBlock = wav->samplesPerBlock;
+
+ bytePtr = wav->packet;
+
+ /* Read the four-byte header for each channel */
+
+ /* Reset the decompressor */
+ for(ch=0;ch < ft->info.channels; ch++) {
+
+ /* Got this from xanim */
+
+ state[ch].previousValue = ((int)bytePtr[1]<<8) +
+ (int)bytePtr[0];
+ if (state[ch].previousValue & 0x8000)
+ state[ch].previousValue -= 0x10000;
+
+ if (bytePtr[2] > 88)
+ {
+ warn("IMA ADPCM Format Error (bad index value) in wav file");
+ state[ch].index = 88;
+ }
+ else
+ state[ch].index = bytePtr[2];
+
+ if (bytePtr[3])
+ warn("IMA ADPCM Format Error (synchronization error) in wav file");
+
+ bytePtr+=4; /* Skip this header */
+
+ wav->samplePtr[ch] = wav->samples[ch];
+ /* Decode one sample for the header */
+ *(wav->samplePtr[ch]++) = state[ch].previousValue;
+ }
+
+ /* Decompress nybbles. Remainging is bytes in block minus header */
+ /* Subtract the one sample taken from header */
+ remaining = samplesThisBlock-1;
+
+ while (remaining) {
+ /* Always decode 8 samples */
+ remaining -= 8;
+ /* Decode 8 left samples */
+ for (i=0;i<4;i++) {
+ b = *bytePtr++;
+ *(wav->samplePtr[0]++) = ImaAdpcmDecode(b & 0x0f,&state[0]);
+ *(wav->samplePtr[0]++) = ImaAdpcmDecode((b>>4) & 0x0f,&state[0]);
+ }
+ if (ft->info.channels < 2)
+ continue; /* If mono, skip rest of loop */
+ /* Decode 8 right samples */
+ for (i=0;i<4;i++) {
+ b = *bytePtr++;
+ *(wav->samplePtr[1]++) = ImaAdpcmDecode(b & 0x0f,&state[1]);
+ *(wav->samplePtr[1]++) = ImaAdpcmDecode((b>>4) & 0x0f,&state[1]);
+ }
+ }
+ /* For a full block, the following should be true: */
+ /* wav->samplesPerBlock = blockAlign - 8byte header + 1 sample in header */
+ return wav->samplesPerBlock;
+}
+
+/****************************************************************************/
+/* MS ADPCM Support Functions Section */
+/****************************************************************************/
+
+/*
+ *
+ * MsAdpcmDecode - Decode a given sample and update state tables
+ *
+ */
+
+LONG MsAdpcmDecode(deltaCode, state)
+LONG deltaCode;
+MsState_t *state;
+{
+ LONG predict;
+ LONG sample;
+ LONG idelta;
+
+ /** Compute next Adaptive Scale Factor (ASF) **/
+ idelta = state->index;
+ state->index = (gaiP4[deltaCode] * idelta) >> 8;
+ if (state->index < 16) state->index = 16;
+ if (deltaCode & 0x08) deltaCode = deltaCode - 0x10;
+
+ /** Predict next sample **/
+ predict = ((state->sample1 * gaiCoef1[state->bpred]) + (state->sample2 * gaiCoef2[state->bpred])) >> 8;
+ /** reconstruct original PCM **/
+ sample = (deltaCode * idelta) + predict;
+
+ if (sample > 32767) sample = 32767;
+ else if (sample < -32768) sample = -32768;
+
+ state->sample2 = state->sample1;
+ state->sample1 = sample;
+
+ return (sample);
+}
+
+
+/*
+ *
+ * MsAdpcmNextBlock - Grab and decode complete block of samples
+ *
+ */
+unsigned short MsAdpcmNextBlock(ft)
+ft_t ft;
+{
+ wav_t wav = (wav_t) ft->priv;
+
+ unsigned short bytesRead;
+ unsigned char *bytePtr;
+
+ MsState_t state[2]; /* One decompressor state for each channel */
+ unsigned short samplesThisBlock;
+ unsigned short remaining;
+
+ unsigned char b;
+
+ /* Pull in the packet and check the header */
+ bytesRead = fread(wav->packet,1,wav->blockAlign,ft->fp);
+ if (bytesRead < wav->blockAlign)
+ {
+ /* If it looks like a valid header is around then try and */
+ /* work with partial blocks. Specs say it should be null */
+ /* padded but I guess this is better then trailing quite. */
+ if (bytesRead >= (7 * ft->info.channels))
+ {
+ samplesThisBlock = (wav->blockAlign - (6 * ft->info.channels));
+ }
+ else
+ {
+ warn ("Premature EOF on .wav input file");
+ return 0;
+ }
+ }
+ else
+ samplesThisBlock = wav->samplesPerBlock;
+
+ bytePtr = wav->packet;
+
+ /* Read the four-byte header for each channel */
+
+ /* Reset the decompressor */
+ state[0].bpred = *bytePtr++; /* Left */
+ if (ft->info.channels > 1)
+ state[1].bpred = *bytePtr++; /* Right */
+ else
+ state[1].bpred = 0;
+
+ /* 7 should be variable from AVI/WAV header */
+ if (state[0].bpred >= 7)
+ {
+ warn("MSADPCM bpred %x and should be less than 7\n",state[0].bpred);
+ return(0);
+ }
+ if (state[1].bpred >= 7)
+ {
+ warn("MSADPCM bpred %x and should be less than 7\n",state[1].bpred);
+ return(0);
+ }
+
+ state[0].index = *bytePtr++; state[0].index |= (*bytePtr++)<<8;
+ if (state[0].index & 0x8000) state[0].index -= 0x10000;
+ if (ft->info.channels > 1)
+ {
+ state[1].index = *bytePtr++; state[1].index |= (*bytePtr++)<<8;
+ if (state[1].index & 0x8000) state[1].index -= 0x10000;
+ }
+
+ state[0].sample1 = *bytePtr++; state[0].sample1 |= (*bytePtr++)<<8;
+ if (state[0].sample1 & 0x8000) state[0].sample1 -= 0x10000;
+ if (ft->info.channels > 1)
+ {
+ state[1].sample1 = *bytePtr++; state[1].sample1 |= (*bytePtr++)<<8;
+ if (state[1].sample1 & 0x8000) state[1].sample1 -= 0x10000;
+ }
+
+ state[0].sample2 = *bytePtr++; state[0].sample2 |= (*bytePtr++)<<8;
+ if (state[0].sample2 & 0x8000) state[0].sample2 -= 0x10000;
+ if (ft->info.channels > 1)
+ {
+ state[1].sample2 = *bytePtr++; state[1].sample2 |= (*bytePtr++)<<8;
+ if (state[1].sample2 & 0x8000) state[1].sample2 -= 0x10000;
+ }
+
+ wav->samplePtr[0] = wav->samples[0];
+ wav->samplePtr[1] = wav->samples[1];
+
+ /* Decode two samples for the header */
+ *(wav->samplePtr[0]++) = state[0].sample2;
+ *(wav->samplePtr[0]++) = state[0].sample1;
+ if (ft->info.channels > 1)
+ {
+ *(wav->samplePtr[1]++) = state[1].sample2;
+ *(wav->samplePtr[1]++) = state[1].sample1;
+ }
+
+ /* Decompress nybbles. Minus 2 included in header */
+ remaining = samplesThisBlock-2;
+
+ while (remaining) {
+ b = *bytePtr++;
+ *(wav->samplePtr[0]++) = MsAdpcmDecode((b>>4) & 0x0f, &state[0]);
+ remaining--;
+ if (ft->info.channels == 1)
+ {
+ *(wav->samplePtr[0]++) = MsAdpcmDecode(b & 0x0f, &state[0]);
+ remaining--;
+ }
+ else
+ {
+ *(wav->samplePtr[1]++) = MsAdpcmDecode(b & 0x0f, &state[1]);
+ }
+ }
+ return samplesThisBlock;
+}
+
+/****************************************************************************/
+/* General Sox WAV file code */
+/****************************************************************************/
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void wavstartread(ft)
+ft_t ft;
+{
+ wav_t wav = (wav_t) ft->priv;
+ char magic[4];
+ ULONG len;
+ int littlendian = 1;
+ char *endptr;
+
+ /* wave file characteristics */
+ unsigned short wChannels; /* number of channels */
+ ULONG wSamplesPerSecond; /* samples per second per channel */
+ ULONG wAvgBytesPerSec; /* estimate of bytes per second needed */
+ unsigned short wBitsPerSample; /* bits per sample */
+ unsigned short wExtSize = 0; /* extended field for ADPCM */
+ unsigned short wNumCoefs = 0; /* Related to IMA ADPCM */
+
+ ULONG data_length; /* length of sound data in bytes */
+ ULONG bytespersample; /* bytes per sample (per channel */
+
+ endptr = (char *) &littlendian;
+ if (!*endptr) ft->swap = 1;
+
+ /* If you need to seek around the input file. */
+ if (0 && ! ft->seekable)
+ fail("WAVE input file must be a file, not a pipe");
+
+ if ( fread(magic, 1, 4, ft->fp) != 4 || strncmp("RIFF", magic, 4))
+ fail("WAVE: RIFF header not found");
+
+ len = rllong(ft);
+
+ if ( fread(magic, 1, 4, ft->fp) != 4 || strncmp("WAVE", magic, 4))
+ fail("WAVE header not found");
+
+ /* Now look for the format chunk */
+ for (;;)
+ {
+ if ( fread(magic, 1, 4, ft->fp) != 4 )
+ fail("WAVE file missing fmt spec");
+ len = rllong(ft);
+ if (strncmp("fmt ", magic, 4) == 0)
+ break; /* Found the format chunk */
+
+ /* skip to next chunk */
+ while (len > 0 && !feof(ft->fp))
+ {
+ getc(ft->fp);
+ len--;
+ }
+ }
+
+ if ( len < 16 )
+ fail("WAVE file fmt chunk is too short");
+
+ wav->formatTag = rlshort(ft);
+ len -= 2;
+ switch (wav->formatTag)
+ {
+ case WAVE_FORMAT_UNKNOWN:
+ fail("WAVE file is in unsupported Microsoft Official Unknown format.");
+
+ case WAVE_FORMAT_PCM:
+ /* Default (-1) depends on sample size. Set that later on. */
+ if (ft->info.style != -1 && ft->info.style != UNSIGNED &&
+ ft->info.style != SIGN2)
+ warn("User options overriding style read in .wav header");
+ break;
+
+ case WAVE_FORMAT_ADPCM:
+ case WAVE_FORMAT_IMA_ADPCM:
+ if (ft->info.style == -1 || ft->info.style == ADPCM)
+ ft->info.style = ADPCM;
+ else
+ warn("User options overriding style read in .wav header");
+ break;
+
+ case WAVE_FORMAT_ALAW:
+ if (ft->info.style == -1 || ft->info.style == ALAW)
+ ft->info.style = ALAW;
+ else
+ warn("User options overriding style read in .wav header");
+ break;
+
+ case WAVE_FORMAT_MULAW:
+ if (ft->info.style == -1 || ft->info.style == ULAW)
+ ft->info.style = ULAW;
+ else
+ warn("User options overriding style read in .wav header");
+ break;
+
+ case WAVE_FORMAT_OKI_ADPCM:
+ fail("Sorry, this WAV file is in OKI ADPCM format.");
+ case WAVE_FORMAT_DIGISTD:
+ fail("Sorry, this WAV file is in Digistd format.");
+ case WAVE_FORMAT_DIGIFIX:
+ fail("Sorry, this WAV file is in Digifix format.");
+ case IBM_FORMAT_MULAW:
+ fail("Sorry, this WAV file is in IBM U-law format.");
+ case IBM_FORMAT_ALAW:
+ fail("Sorry, this WAV file is in IBM A-law format.");
+ case IBM_FORMAT_ADPCM:
+ fail("Sorry, this WAV file is in IBM ADPCM format.");
+ default: fail("WAV file has unknown format type");
+ }
+
+ wChannels = rlshort(ft);
+ len -= 2;
+ /* User options take precedence */
+ if (ft->info.channels == -1 || ft->info.channels == wChannels)
+ ft->info.channels = wChannels;
+ else
+ warn("User options overriding channels read in .wav header");
+
+ wSamplesPerSecond = rllong(ft);
+ len -= 4;
+ if (ft->info.rate == 0 || ft->info.rate == wSamplesPerSecond)
+ ft->info.rate = wSamplesPerSecond;
+ else
+ warn("User options overriding rate read in .wav header");
+
+ wAvgBytesPerSec = rllong(ft); /* Average bytes/second */
+ wav->blockAlign = rlshort(ft); /* Block align */
+ len -= 6;
+
+ /* bits per sample per channel */
+ wBitsPerSample = rlshort(ft);
+ len -= 2;
+
+ /* ADPCM formats have extended fmt chunk. Check for those cases. */
+ if (wav->formatTag == WAVE_FORMAT_ADPCM)
+ {
+ if (wBitsPerSample != 4)
+ fail("Can only handle 4-bit MS ADPCM in wav files");
+
+ wExtSize = rlshort(ft);
+ wav->samplesPerBlock = rlshort(ft);
+ wav->bytesPerBlock = (wav->samplesPerBlock + 7)/2 * ft->info.channels;
+ wNumCoefs = rlshort(ft);
+ wav->packet = (unsigned char *)malloc(wav->blockAlign);
+ len -= 6;
+
+ wav->samples[1] = wav->samples[0] = 0;
+ /* Use ft->info.channels after this becuase wChannels is now bad */
+ while (wChannels-- > 0)
+ wav->samples[wChannels] = (short *)malloc(wav->samplesPerBlock*sizeof(short));
+ /* Here we are setting the bytespersample AFTER de-compression */
+ bytespersample = WORD;
+ }
+ else if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)
+ {
+ if (wBitsPerSample != 4)
+ fail("Can only handle 4-bit IMA ADPCM in wav files");
+
+ wExtSize = rlshort(ft);
+ wav->samplesPerBlock = rlshort(ft);
+ wav->bytesPerBlock = (wav->samplesPerBlock + 7)/2 * ft->info.channels;
+ wav->packet = (unsigned char *)malloc(wav->blockAlign);
+ len -= 4;
+
+ wav->samples[1] = wav->samples[0] = 0;
+ /* Use ft->info.channels after this becuase wChannels is now bad */
+ while (wChannels-- > 0)
+ wav->samples[wChannels] = (short *)malloc(wav->samplesPerBlock*sizeof(short));
+ /* Here we are setting the bytespersample AFTER de-compression */
+ bytespersample = WORD;
+ }
+ else
+ {
+ bytespersample = (wBitsPerSample + 7)/8;
+ }
+
+ switch (bytespersample)
+ {
+
+ case BYTE:
+ /* User options take precedence */
+ if (ft->info.size == -1 || ft->info.size == BYTE)
+ ft->info.size = BYTE;
+ else
+ warn("User options overriding size read in .wav header");
+
+ /* Now we have enough information to set default styles. */
+ if (ft->info.style == -1)
+ ft->info.style = UNSIGNED;
+ break;
+
+ case WORD:
+ if (ft->info.size == -1 || ft->info.size == WORD)
+ ft->info.size = WORD;
+ else
+ warn("User options overriding size read in .wav header");
+
+ /* Now we have enough information to set default styles. */
+ if (ft->info.style == -1)
+ ft->info.style = SIGN2;
+ break;
+
+ case DWORD:
+ if (ft->info.size == -1 || ft->info.size == DWORD)
+ ft->info.size = DWORD;
+ else
+ warn("User options overriding size read in .wav header");
+
+ /* Now we have enough information to set default styles. */
+ if (ft->info.style == -1)
+ ft->info.style = SIGN2;
+ break;
+
+ default:
+ fail("Sorry, don't understand .wav size");
+ }
+
+ /* Skip past the rest of any left over fmt chunk */
+ while (len > 0 && !feof(ft->fp))
+ {
+ getc(ft->fp);
+ len--;
+ }
+
+ /* Now look for the wave data chunk */
+ for (;;)
+ {
+ if ( fread(magic, 1, 4, ft->fp) != 4 )
+ fail("WAVE file has missing data chunk");
+ len = rllong(ft);
+ if (strncmp("data", magic, 4) == 0)
+ break; /* Found the data chunk */
+
+ while (len > 0 && !feof(ft->fp)) /* skip to next chunk */
+ {
+ getc(ft->fp);
+ len--;
+ }
+ }
+
+ data_length = len;
+ if (wav->formatTag == WAVE_FORMAT_ADPCM)
+ {
+ /* Compute easiest part of number of samples. For every block, there
+ are samplesPerBlock samples to read. */
+ wav->numSamples = (((data_length / wav->blockAlign) * wav->samplesPerBlock) * ft->info.channels);
+ /* Next, for any partial blocks, substract overhead from it and it
+ will leave # of samples to read. */
+ wav->numSamples += ((data_length - ((data_length/wav->blockAlign)
+ *wav->blockAlign))
+ - (6 * ft->info.channels)) * ft->info.channels;
+ wav->blockSamplesRemaining = 0; /* Samples left in buffer */
+ }
+ else if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)
+ {
+ /* Compute easiest part of number of samples. For every block, there
+ are samplesPerBlock samples to read. */
+ wav->numSamples = (((data_length / wav->blockAlign) * wav->samplesPerBlock) * ft->info.channels);
+ /* Next, for any partial blocks, substract overhead from it and it
+ will leave # of samples to read. */
+ wav->numSamples += ((data_length - ((data_length/wav->blockAlign)
+ *wav->blockAlign))
+ - (3 * ft->info.channels)) * ft->info.channels;
+ wav->blockSamplesRemaining = 0; /* Samples left in buffer */
+ }
+ else
+ wav->numSamples = data_length/ft->info.size; /* total samples */
+
+ report("Reading Wave file: %s format, %d channel%s, %d samp/sec",
+ wav_format_str(wav->formatTag), ft->info.channels,
+ wChannels == 1 ? "" : "s", wSamplesPerSecond);
+ report(" %d byte/sec, %d block align, %d bits/samp, %u data bytes",
+ wAvgBytesPerSec, wav->blockAlign, wBitsPerSample, data_length);
+
+ /* Can also report exteded fmt information */
+ if (wav->formatTag == WAVE_FORMAT_ADPCM)
+ report(" %d Extsize, %d Samps/block, %d bytes/block %d Num Coefs\n",wExtSize,wav->samplesPerBlock,wav->bytesPerBlock,wNumCoefs);
+ else if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)
+ report(" %d Extsize, %d Samps/block, %d bytes/block\n",wExtSize,wav->samplesPerBlock,wav->bytesPerBlock);
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG wavread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ wav_t wav = (wav_t) ft->priv;
+ LONG done;
+
+ if (len > wav->numSamples) len = wav->numSamples;
+
+ /* If file is in ADPCM style then read in multiple blocks else */
+ /* read as much as possible and return quickly. */
+ if (ft->info.style == ADPCM)
+ {
+ done = 0;
+ while (done < len) { /* Still want data? */
+ /* See if need to read more from disk */
+ if (wav->blockSamplesRemaining == 0) {
+ if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)
+ wav->blockSamplesRemaining = ImaAdpcmNextBlock(ft);
+ else
+ wav->blockSamplesRemaining = MsAdpcmNextBlock(ft);
+ if (wav->blockSamplesRemaining == 0)
+ {
+ /* Don't try to read any more samples */
+ wav->numSamples = 0;
+ return done;
+ }
+ wav->samplePtr[0] = wav->samples[0];
+ wav->samplePtr[1] = wav->samples[1];
+ }
+
+ switch(ft->info.channels) { /* Copy data into buf */
+ case 1: /* Mono: Just copy left channel data */
+ while ((wav->blockSamplesRemaining > 0) && (done < len))
+ {
+ /* Output is already signed */
+ *buf++ = LEFT(*(wav->samplePtr[0]++), 16);
+ done++;
+ wav->blockSamplesRemaining--;
+ }
+ break;
+ case 2: /* Stereo: Interleave samples */
+ while ((wav->blockSamplesRemaining > 0) && (done < len))
+ {
+ /* Output is already signed */
+ *buf++ = LEFT(*(wav->samplePtr[0]++),16); /* Left */
+ *buf++ = LEFT(*(wav->samplePtr[1]++),16); /* Right */
+ done += 2;
+ wav->blockSamplesRemaining--;
+ }
+ break;
+ default:
+ fail ("Can only handle stereo or mono files");
+ }
+ }
+ }
+ else /* else not ADPCM style */
+ {
+ done = rawread(ft, buf, len);
+ /* If software thinks there are more samples but I/O */
+ /* says otherwise, let the user no about this. */
+ if (done == 0 && wav->numSamples != 0)
+ warn("Premature EOF on .wav input file");
+ }
+ wav->numSamples -= done;
+ return done;
+}
+
+/*
+ * Do anything required when you stop reading samples.
+ * Don't close input file!
+ */
+void wavstopread(ft)
+ft_t ft;
+{
+ wav_t wav = (wav_t) ft->priv;
+
+ if (wav->packet) free(wav->packet);
+ if (wav->samples[0]) free(wav->samples[0]);
+ if (wav->samples[1]) free(wav->samples[1]);
+}
+
+void wavstartwrite(ft)
+ft_t ft;
+{
+ wav_t wav = (wav_t) ft->priv;
+ int littlendian = 1;
+ char *endptr;
+
+ endptr = (char *) &littlendian;
+ if (!*endptr) ft->swap = 1;
+
+ wav->numSamples = 0;
+ wav->second_header = 0;
+ if (! ft->seekable)
+ warn("Length in output .wav header will wrong since can't seek to fix it");
+ wavwritehdr(ft);
+}
+
+void wavwritehdr(ft)
+ft_t ft;
+{
+ wav_t wav = (wav_t) ft->priv;
+
+ /* wave file characteristics */
+ unsigned short wFormatTag = 0; /* data format */
+ unsigned short wChannels; /* number of channels */
+ ULONG wSamplesPerSecond; /* samples per second per channel */
+ ULONG wAvgBytesPerSec; /* estimate of bytes per second needed */
+ unsigned short wBlockAlign; /* byte alignment of a basic sample block */
+ unsigned short wBitsPerSample; /* bits per sample */
+ ULONG data_length; /* length of sound data in bytes */
+ ULONG bytespersample; /* bytes per sample (per channel) */
+
+ switch (ft->info.size)
+ {
+ case BYTE:
+ wBitsPerSample = 8;
+ break;
+ case WORD:
+ wBitsPerSample = 16;
+ break;
+ case DWORD:
+ wBitsPerSample = 32;
+ break;
+ default:
+ wBitsPerSample = 32;
+ break;
+ }
+
+ switch (ft->info.style)
+ {
+ case UNSIGNED:
+ wFormatTag = WAVE_FORMAT_PCM;
+ if (wBitsPerSample != 8 && !wav->second_header)
+ warn("Warning - writing bad .wav file using unsigned data and %d bits/sample",wBitsPerSample);
+ break;
+ case SIGN2:
+ wFormatTag = WAVE_FORMAT_PCM;
+ if (wBitsPerSample == 8 && !wav->second_header)
+ warn("Warning - writing bad .wav file using signed data and %d bits/sample",wBitsPerSample);
+ break;
+ case ALAW:
+ wFormatTag = WAVE_FORMAT_ALAW;
+ if (wBitsPerSample != 8 && !wav->second_header)
+ warn("Warning - writing bad .wav file using A-law data and %d bits/sample",wBitsPerSample);
+ break;
+ case ULAW:
+ wFormatTag = WAVE_FORMAT_MULAW;
+ if (wBitsPerSample != 8 && !wav->second_header)
+ warn("Warning - writing bad .wav file using U-law data and %d bits/sample",wBitsPerSample);
+ break;
+ case ADPCM:
+ wFormatTag = WAVE_FORMAT_PCM;
+ warn("Can not support writing ADPCM style. Overriding to Signed Words\n");
+ ft->info.style = SIGN2;
+ wBitsPerSample = 16;
+ /* wFormatTag = WAVE_FORMAT_IMA_ADPCM;
+ wBitsPerSample = 4;
+ if (wBitsPerSample != 4 && !wav->second_header)
+ warn("Warning - writing bad .wav file using IMA ADPCM and %d bits/sample",wBitsPerSample);
+ break; */
+ }
+
+
+ wSamplesPerSecond = ft->info.rate;
+ bytespersample = (wBitsPerSample + 7)/8;
+ wAvgBytesPerSec = ft->info.rate * ft->info.channels * bytespersample;
+ wChannels = ft->info.channels;
+ wBlockAlign = ft->info.channels * bytespersample;
+ if (!wav->second_header) /* use max length value first time */
+ data_length = 0x7fffffffL - (8+16+12);
+ else /* fixup with real length */
+ {
+ if (ft->info.style == ADPCM)
+ data_length = wav->numSamples / 2;
+ else
+ data_length = bytespersample * wav->numSamples;
+ }
+
+ /* figured out header info, so write it */
+ fputs("RIFF", ft->fp);
+ wllong(ft, data_length + 8+16+12); /* Waveform chunk size: FIXUP(4) */
+ fputs("WAVE", ft->fp);
+ fputs("fmt ", ft->fp);
+ wllong(ft, (LONG)16); /* fmt chunk size */
+ wlshort(ft, wFormatTag);
+ wlshort(ft, wChannels);
+ wllong(ft, wSamplesPerSecond);
+ wllong(ft, wAvgBytesPerSec);
+ wlshort(ft, wBlockAlign);
+ wlshort(ft, wBitsPerSample);
+
+ fputs("data", ft->fp);
+ wllong(ft, data_length); /* data chunk size: FIXUP(40) */
+
+ if (!wav->second_header) {
+ report("Writing Wave file: %s format, %d channel%s, %d samp/sec",
+ wav_format_str(wFormatTag), wChannels,
+ wChannels == 1 ? "" : "s", wSamplesPerSecond);
+ report(" %d byte/sec, %d block align, %d bits/samp",
+ wAvgBytesPerSec, wBlockAlign, wBitsPerSample);
+ } else
+ report("Finished writing Wave file, %u data bytes\n",data_length);
+}
+
+void wavwrite(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ wav_t wav = (wav_t) ft->priv;
+
+ wav->numSamples += len;
+ rawwrite(ft, buf, len);
+}
+
+void
+wavstopwrite(ft)
+ft_t ft;
+{
+ /* All samples are already written out. */
+ /* If file header needs fixing up, for example it needs the */
+ /* the number of samples in a field, seek back and write them here. */
+ if (!ft->seekable)
+ return;
+ if (fseek(ft->fp, 0L, 0) != 0)
+ fail("Sorry, can't rewind output file to rewrite .wav header.");
+ ((wav_t) ft->priv)->second_header = 1;
+ wavwritehdr(ft);
+}
+
+/*
+ * Return a string corresponding to the wave format type.
+ */
+static char *
+wav_format_str(wFormatTag)
+unsigned wFormatTag;
+{
+ switch (wFormatTag)
+ {
+ case WAVE_FORMAT_UNKNOWN:
+ return "Microsoft Official Unknown";
+ case WAVE_FORMAT_PCM:
+ return "Microsoft PCM";
+ case WAVE_FORMAT_ADPCM:
+ return "Microsoft ADPCM";
+ case WAVE_FORMAT_ALAW:
+ return "Microsoft A-law";
+ case WAVE_FORMAT_MULAW:
+ return "Microsoft U-law";
+ case WAVE_FORMAT_OKI_ADPCM:
+ return "OKI ADPCM format.";
+ case WAVE_FORMAT_IMA_ADPCM:
+ return "IMA ADPCM";
+ case WAVE_FORMAT_DIGISTD:
+ return "Digistd format.";
+ case WAVE_FORMAT_DIGIFIX:
+ return "Digifix format.";
+ case IBM_FORMAT_MULAW:
+ return "IBM U-law format.";
+ case IBM_FORMAT_ALAW:
+ return "IBM A-law";
+ case IBM_FORMAT_ADPCM:
+ return "IBM ADPCM";
+ default:
+ return "Unknown";
+ }
+}
--- /dev/null
+++ b/src/wav.h
@@ -1,0 +1,34 @@
+/* wav.h - various structures and defines used by WAV converter. */
+
+#ifndef WAV_H_INCLUDED
+#define WAV_H_INCLUDED
+
+/* purloined from public Microsoft RIFF docs */
+
+#define WAVE_FORMAT_UNKNOWN (0x0000)
+#define WAVE_FORMAT_PCM (0x0001)
+#define WAVE_FORMAT_ADPCM (0x0002)
+#define WAVE_FORMAT_ALAW (0x0006)
+#define WAVE_FORMAT_MULAW (0x0007)
+#define WAVE_FORMAT_OKI_ADPCM (0x0010)
+#define WAVE_FORMAT_IMA_ADPCM (0x0011)
+#define WAVE_FORMAT_DIGISTD (0x0015)
+#define WAVE_FORMAT_DIGIFIX (0x0016)
+#define IBM_FORMAT_MULAW (0x0101)
+#define IBM_FORMAT_ALAW (0x0102)
+#define IBM_FORMAT_ADPCM (0x0103)
+
+typedef struct MsState {
+ LONG index; /* Index into step size table */
+ ULONG bpred; /* Most recent sample value */
+ LONG sample1;
+ LONG sample2;
+} MsState_t;
+
+typedef struct ImaState {
+ int index; /* Index into step size table */
+ int previousValue; /* Most recent sample value */
+} ImaState_t;
+
+
+#endif /* WAV_H_INCLUDED */
--- /dev/null
+++ b/src/wve.c
@@ -1,0 +1,158 @@
+/*
+ * Psion wve format, based on the au format file. Hacked by
+ * Richard Caley (R.Caley@ed.ac.uk)
+ */
+
+#include "st.h"
+#include "g72x.h"
+
+/* Magic numbers used in Psion audio files */
+#define PSION_MAGIC "ALawSoundFile**"
+#define PSION_VERSION ((short)3856)
+#define PSION_INV_VERSION ((short)4111)
+#define PSION_HDRSIZE 32
+
+struct wvepriv
+ {
+ unsigned int length;
+ short padding;
+ short repeats;
+ };
+
+void wvewriteheader(P1(ft_t ft));
+LONG rawread(P3(ft_t, LONG *, LONG));
+void rawwrite(P3(ft_t, LONG *, LONG));
+
+void wvestartread(ft)
+ft_t ft;
+{
+ struct wvepriv *p = (struct wvepriv *) ft->priv;
+ char magic[16];
+ short version;
+
+
+ /* Sanity check */
+ if (sizeof(struct wvepriv) > PRIVSIZE)
+ fail(
+"struct wvepriv is too big (%d); change PRIVSIZE in st.h and recompile sox",
+ sizeof(struct wvepriv));
+
+ /* Check the magic word */
+ fread(magic, 16, 1, ft->fp);
+ if (strcmp(magic, PSION_MAGIC)==0) {
+ report("Found Psion magic word");
+ }
+ else
+ fail("Psion header doesn't start with magic word\nTry the '.al' file type with '-t al -r 8000 filename'");
+
+ version=rshort(ft);
+
+ /* Check for what type endian machine its read on */
+ if (version == PSION_INV_VERSION)
+ {
+ ft->swap = 1;
+ report("Found inverted PSION magic word");
+ }
+ else if (version == PSION_VERSION)
+ {
+ ft->swap = 0;
+ report("Found PSION magic word");
+ }
+ else
+ fail("Wrong version in Psion header");
+
+ p->length=rlong(ft);
+
+ p->padding=rshort(ft);
+
+ p->repeats=rshort(ft);
+
+ (void)rshort(ft);
+ (void)rshort(ft);
+ (void)rshort(ft);
+
+ ft->info.style = ALAW;
+ ft->info.size = BYTE;
+
+ ft->info.rate = 8000;
+
+ ft->info.channels = 1;
+}
+
+/* When writing, the header is supposed to contain the number of
+ data bytes written, unless it is written to a pipe.
+ Since we don't know how many bytes will follow until we're done,
+ we first write the header with an unspecified number of bytes,
+ and at the end we rewind the file and write the header again
+ with the right size. This only works if the file is seekable;
+ if it is not, the unspecified size remains in the header
+ (this is illegal). */
+
+void wvestartwrite(ft)
+ft_t ft;
+{
+ struct wvepriv *p = (struct wvepriv *) ft->priv;
+
+ p->length = 0;
+ if (p->repeats == 0)
+ p->repeats = 1;
+
+ ft->info.style = ALAW;
+ ft->info.size = BYTE;
+ ft->info.rate = 8000;
+
+ wvewriteheader(ft);
+}
+
+LONG wveread(ft, buf, samp)
+ft_t ft;
+LONG *buf, samp;
+{
+ return rawread(ft, buf, samp);
+}
+
+void wvewrite(ft, buf, samp)
+ft_t ft;
+LONG *buf, samp;
+{
+ struct wvepriv *p = (struct wvepriv *) ft->priv;
+ p->length += samp * ft->info.size;
+ rawwrite(ft, buf, samp);
+}
+
+void
+wvestopwrite(ft)
+ft_t ft;
+{
+ if (!ft->seekable)
+ return;
+ if (fseek(ft->fp, 0L, 0) != 0)
+ fail("Can't rewind output file to rewrite Psion header.");
+ wvewriteheader(ft);
+}
+
+void wvewriteheader(ft)
+ft_t ft;
+{
+
+ char magic[16];
+ short version;
+ short zero;
+ struct wvepriv *p = (struct wvepriv *) ft->priv;
+
+ strcpy(magic,PSION_MAGIC);
+ version=PSION_VERSION;
+ zero=0;
+
+ fwrite(magic, sizeof(magic), 1, ft->fp);
+
+ wshort(ft, version);
+ wblong(ft, p->length);
+ wshort(ft, p->padding);
+ wshort(ft, p->repeats);
+
+ wshort(ft, zero);
+ wshort(ft, zero);
+ wshort(ft, zero);
+}
+
--- /dev/null
+++ b/tests.com
@@ -1,0 +1,41 @@
+$ FVER = 'F$VERIFY(0)'
+$ !
+$ ! test files
+$ ! SOX Test script. This should run without access violating or printing
+$ ! any messages.
+$ !
+$ ! VMS translation of tests.shr
+$ !
+$ ! Modification History
+$ ! 14 Dec 1992, K. S. Kubo, Created
+$ !
+$ ! NOTES:
+$ ! Does not support the voc test w/o checksum and rate byte.
+$ !
+$ FILE = "monkey"
+$ PROC_PATH = F$Environment("PROCEDURE")
+$ SOX = "$ " + F$Parse(PROC_PATH,,,"DEVICE") + -
+ F$Parse(PROC_PATH,,,"DIRECTORY") + "SOX"
+$ !
+$ ! verbose option -- uncomment the following line
+$ ! SOX = SOX + " ""-V"""
+$ !
+$ ON ERROR THEN GOTO COM_EXIT
+$ ON SEVERE THEN GOTO COM_EXIT
+$ ON WARNING THEN CONTINUE
+$ DELETE/NOLOG ub.raw;*, sb.raw;*, ub2.raw;*, ub2.voc;*, ub.au;*, ub2.sf;*
+$ SOX 'FILE'.voc ub.raw
+$ SOX -t raw -r 8196 -u -b -c 1 ub.raw -r 8196 -s -b sb.raw
+$ SOX -t raw -r 8196 -s -b -c 1 sb.raw -r 8196 -u -b ub2.raw
+$ SOX -r 8196 -u -b -c 1 ub2.raw -r 8196 ub2.voc
+$ DIFF/MODE=HEX ub.raw ub2.raw
+$ DELETE/NOLOG ub.raw;*, sb.raw;*, ub2.raw;*, ub2.voc;*
+$ SOX 'FILE'.au -u -r 8192 -u -b ub.raw
+$ SOX -r 8192 -u -b ub.raw -U -b ub.au
+$ SOX ub.au -u ub2.raw
+$ SOX ub.au -w ub2.sf
+$ DELETE/NOLOG ub.raw;*, ub.au;*, ub2.raw;*, ub2.sf;*
+$ !
+$ COM_EXIT:
+$ FVER = F$VERIFY('FVER')
+$ EXIT
--- /dev/null
+++ b/version.h
@@ -1,0 +1,1 @@
+#define VERSION 12
--- /dev/null
+++ b/vms.lis
@@ -1,0 +1,65 @@
+VAX/VMS port of SOX, release 5, patchlevel 7
+
+As an important side note, the DECsound tool only recognizes DDIF and Sun .au
+format sounds (Sun .au sounds *must* be uLaw, 8000Hz sampling rate to be
+readable).
+
+The portmeister makes no representations about the suitability of this
+software for any purpose. This software is provided "as is" without
+warranties expressed or implied.
+
+New files:
+
+ sox.opt - linker options file
+ descrip.mms - MMS description file
+ sound2au.com - VMS DCL command file to translate a sound to a Sun .au
+ by way of sound2sun
+ sound2sun.c - program to convert sampled audio files to uLAW format
+ (by Rich Gopstein and Harris Corporation)
+ sound2sun.opt - options file for sound2sun
+ tests.com - VMS DCL command file equivalent of tests.sh
+
+Modified files:
+
+ st.h -
+ added VMS definitions for READBINARY and WRITEBINARY
+ changed "#ifdef SYSV" to "#if defined(SYSV) || defined(VMS)"
+ to pick up definitions of index, rindex, and bcopy
+ added definitions of macros IMPORT and EXPORT (used on VMS
+ for variable scope) -- collateral damage affects variables
+ formats, informat, outformat, sizes, styles, effects
+ wav.c -
+ changed extern to IMPORT for volume, amplitude, summary, and
+ verbose
+ voc.c -
+ changed extern to IMPORT for summary and verbose
+ sox.c -
+ replaced "extern errno" with "#include <errno.h>"
+ replaced "extern sys_errlist[]| with "#include <perror.h>"
+ added EXPORT to verbose, summary, volume, amplitdue,
+ informat, outformat, and writing
+ removed unneeded extern declaration of formats[] (already
+ defined in st.h)
+ sndrtool.c -
+ replaced "extern errno" with "#include <errno.h>"
+ replaced "extern sys_errlist[]| with "#include <perror.h>"
+ skel.c -
+ changed extern to IMPORT for volume, amplitude, summary, and
+ verbose
+ sf.c -
+ changed extern to IMPORT for summary and verbose
+ sbdsp.c -
+ changed extern to IMPORT for volume, amplitude, summary, and
+ verbose
+ raw.c -
+ changed extern to IMPORT for summary and verbose
+ misc.c -
+ moved "#include st.h" to top of file
+ added EXPORT to sizes[] and styles[]
+ handlers.c -
+ added EXPORT to effects[] and formats[]
+ echo.c -
+ changed extern to IMPORT for writing
+ 8svx.c -
+ replaced "extern errno" with "#include <errno.h>"
+ replaced "extern sys_errlist[]| with "#include <perror.h>"