home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-14 | 99.8 KB | 3,343 lines |
- Newsgroups: comp.sources.unix
- From: guido.van.rossum@cwi.nl (Guido van Rossum)
- Subject: v26i162: radio - UDP broadcast/receive utilities for audio data, V2.0.2, Part01/02
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: guido.van.rossum@cwi.nl (Guido van Rossum)
- Posting-Number: Volume 26, Issue 162
- Archive-Name: radio2.0.2/part01
-
- This is Radio version 2.0, patchlevel 2 (a.k.a. 2.0.2).
-
- If you have a local area network full of workstations with audio
- capabilities and at least one FM/AM radio or other audio source, you can
- broadcast the audio over the network, and let other users listen to it.
-
- This software works for Sun Sparcs running SunOS 4.0 or 4.1, for SGI Indigo
- or Personal IRIS 4D/30 or 4D/35 workstations running SGI IRIX 4.0 or 3.3.2,
- and for NeXT workstations (running version 2.1). At CWI, versions of it
- have been in continuous use on a mix of Sun and SGI system types for almost
- two years; version 1.0 (patchlevel 4) was last tested on a NeXT. (I've
- heard that the program doesn't work on NeXT 3.1; if you fix it please send
- me the changes!)
-
- Man pages for "radio" and "broadcast" are provided.
-
- The implementation continuously transmits UDP broadcast packets of 1400
- bytes each (i.e. less than six per second), which contain the data in U-LAW
- format (8000 samples/second, 1 byte/sample, logarithmically encoded). On a
- typical ethernet, this uses about 1 percent of the net available bandwith.
- Some loss of UDP packets is tolerated by the receiving program (this is
- heard as short interruptions of the sound). Every now and then, a short
- "station call" packet is transmitted as well, for the benefit of advanced
- listening programs.
-
- It is possible to use multiple transmission stations (each identified by a
- different UDP port), and to transmit to multiple connected subnets
- simultaneously (as long as the gateways let UDP broadcast packets through).
- For reasons you don't want to know, you can only have one broadcasting and
- one radio process per host, except on the SGI there may be multiple radio
- processes.
-
- If you have Motif, you may be interested in the "tuner" program X(version
- 1.3) by Jack Jansen. This is a window-based interface that shows the
- different broadcasting stations at your site and lets you tune your radio
- process to the station of your choice. It will be posted to comp.sources.x
- around the same time as radio 2.0; you can also ftp it from site ftp.cwi.nl
- [192.16.184.180], file /pub/tuner1.3.tar.Z.
-
- If you missed a part of the posting of radio, you can ftp the whole
- source from ftp.cwi.nl [192.16.184.180], file /pub/radio2.0.tar.Z.
-
- Guido van Rossum
- CWI, dept. CST
- Kruislaan 413
- X1098 SJ Amsterdam
- The Netherlands
-
- E-mail (Internet) : Guido.van.Rossum@cwi.nl (guido@cwi.nl)
-
- The "libst" U-LAW conversion library is written and copyrighted by Jef
- Poskanzer.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: MANIFEST Makefile README adpcm.c adpcm.h broadcast.man
- # libst.c libst.h nielsen.py patchlevel.h playulaw.c radio.h
- # radio.man recordlinear.c recordulaw.c sndulaw.c socklib.c
- # stations.pl stations.py ttytuner.py ulawadpcm.c
- # Wrapped by vixie@gw.home.vix.com on Thu Apr 15 18:45:43 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(840 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1
- X Makefile 1
- X README 1
- X adpcm.c 1
- X adpcm.h 1
- X broadcast.c 2
- X broadcast.man 1
- X checkradio.py 2
- X libst.c 1
- X libst.h 1
- X nielsen.py 1
- X patchlevel.h 1
- X playulaw.c 1
- X radio.c 2
- X radio.h 1
- X radio.man 1
- X recordlinear.c 1
- X recordulaw.c 1
- X sndulaw.c 1
- X socklib.c 1
- X stations.pl 1
- X stations.py 1
- X ttytuner.py 1
- X ulawadpcm.c 1
- END_OF_FILE
- if test 840 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(2817 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# /***********************************************************
- X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- X# Netherlands.
- X#
- X# All Rights Reserved
- X#
- X# Permission to use, copy, modify, and distribute this software and its
- X# documentation for any purpose and without fee is hereby granted,
- X# provided that the above copyright notice appear in all copies and that
- X# both that copyright notice and this permission notice appear in
- X# supporting documentation, and that the names of Stichting Mathematisch
- X# Centrum or CWI not be used in advertising or publicity pertaining to
- X# distribution of the software without specific, written prior permission.
- X#
- X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X#
- X# ******************************************************************/
- X
- X
- default:
- X @echo 'You must use "make sun4.0", "make sun4.1",'
- X @echo '"make next" or "make sgi"'
- X exit 1
- X
- all: radio broadcast
- X
- X# Platform-specific entries
- X
- sun4.0: # For SunOS 4.x
- X make all LIBS=-lX11
- X
- sun4.1: # For SunOS 4.1 with audio library (/usr/demo/SOUND)
- X make all LIBS='-lX11 /usr/demo/SOUND/libaudio.a' \
- X CFLAGS='-DREMHDR -I/usr/demo/SOUND'
- X
- sun4.1.2: # For SunOS 4.1 with multicast & audio library (/usr/demo/SOUND)
- X make all LIBS='-lX11 /usr/demo/SOUND/libaudio.a' \
- X CFLAGS='-DHAVE_MCAST -DREMHDR -I/usr/demo/SOUND -DDEFMCAST=\"radio.multicast\"'
- X
- sgi: # For SGI IRIX 4.0
- X make all recordulaw recordlinear playulaw LIBS='-lX11 -laudio'
- X
- next: # NeXT 2.1
- X make all sndulaw
- X
- X# Common programs:
- X
- ROBJ= radio.o socklib.o ulawadpcm.o adpcm.o libst.o
- BOBJ= broadcast.o socklib.o adpcm.o ulawadpcm.o libst.o
- X
- radio: $(ROBJ)
- X $(CC) $(ROBJ) $(LIBS) -o radio
- X
- broadcast: $(BOBJ)
- X $(CC) $(BOBJ) $(LIBS) -o broadcast
- X
- X# NeXT-only programs:
- X
- sndulaw: sndulaw.o
- X $(CC) sndulaw.o -o sndulaw
- X
- X# SGI-only programs:
- X
- recordulaw: recordulaw.o libst.o
- X $(CC) recordulaw.o -laudio -o recordulaw
- X
- recordlinear: recordlinear.o
- X $(CC) recordlinear.o -laudio -o recordlinear
- X
- playulaw: playulaw.o
- X $(CC) playulaw.o -laudio -o playulaw
- X
- X# Service entries:
- X
- clean:
- X -rm -f core *.o *~ @* '#'* ,* *.pyc *.BAK Part??
- X
- clobber: clean
- X -rm -f radio broadcast recordulaw recordlinear playulaw sndulaw
- X
- X# Dependencies:
- X
- broadcast.o: radio.h adpcm.h
- radio.o: radio.h adpcm.h libst.h
- ulawadpcm.o: adpcm.h libst.h
- playulaw.o: libst.h
- END_OF_FILE
- if test 2817 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(15880 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- Welcome to the wonderful world of Local Area Network radio!
- X===========================================================
- X
- This is Radio version 2.0, patchlevel 2 (a.k.a. 2.0.2).
- X
- If you have a local area network full of workstations with audio
- capabilities and at least one FM/AM radio or other audio source, you
- can broadcast the audio over the network, and let other users listen
- to it.
- X
- This software works for Sun Sparcs running SunOS 4.0 or 4.1, for SGI
- Indigo or Personal IRIS 4D/30 or 4D/35 workstations running SGI IRIX
- X4.0 or 3.3.2, and for NeXT workstations (running version 2.1). At
- CWI, versions of it have been in continuous use on a mix of Sun and
- SGI system types for almost two years; version 1.0 (patchlevel 4) was
- last tested on a NeXT. (I've heard that the program doesn't work on
- NeXT 3.1; if you fix it please send me the changes!)
- X
- Man pages for "radio" and "broadcast" are provided.
- X
- The implementation continuously transmits UDP broadcast packets of
- X1400 bytes each (i.e. less than six per second), which contain the
- data in U-LAW format (8000 samples/second, 1 byte/sample,
- logarithmically encoded). On a typical ethernet, this uses about 1
- percent of the net available bandwith. Some loss of UDP packets is
- tolerated by the receiving program (this is heard as short
- interruptions of the sound). Every now and then, a short "station
- call" packet is transmitted as well, for the benefit of advanced
- listening programs.
- X
- It is possible to use multiple transmission stations (each identified
- by a different UDP port), and to transmit to multiple connected
- subnets simultaneously (as long as the gateways let UDP broadcast
- packets through). For reasons you don't want to know, you can only
- have one broadcasting and one radio process per host, except on
- the SGI there may be multiple radio processes.
- X
- If you have Motif, you may be interested in the "tuner" program
- X(version 1.3) by Jack Jansen. This is a window-based interface that
- shows the different broadcasting stations at your site and lets you
- tune your radio process to the station of your choice. It will be
- posted to comp.sources.x around the same time as radio 2.0; you can
- also ftp it from site ftp.cwi.nl [192.16.184.180], file
- X/pub/tuner1.3.tar.Z.
- X
- If you missed a part of the posting of radio, you can ftp the whole
- source from ftp.cwi.nl [192.16.184.180], file /pub/radio2.0.tar.Z.
- X
- This software is copyrighted. See the notice at the end of this file.
- X
- X
- Changes in 2.0 patchlevel 2
- X---------------------------
- X
- Broadcast can now also read 16-bit linear samples from standard input,
- as this is more appropriate for ADPCM encoding (see below). Use the
- X-l option. There is a program, recordlinear, which outputs such
- samples, for the SGI only.
- X
- On the SGI, radio's cleanup handler (invoked when it receives a TERM
- or INTR signal) resets the output volume only if it was set with the
- X-v option. It resets nothing at all if the program was currently
- paused by a tuner.
- X
- There is now a default multicast address, from the unofficial range.
- X(This only has meaning for SGI users and for users of a hacked SunOS
- version which supports multicast.)
- X
- Data packets now have a 2-byte header, which is compatible with IVS,
- INRIA's video and audio conferencing system, and allows us to support
- different encoding schemes. (The control packet format is unchanged,
- compatibility with IVS is not a point here.) Currently supported
- encodings are:
- X
- X- PCM_64 (pulse-code modulation; in fact, plain u-law as before);
- X
- X- ADPCM_32 (Adaptive Delta PCM, which takes only 32 kbit/sec with only
- X a slight loss in quality);
- X
- X- ADPCM_32_W_STATE, which is the same as ADPCM_32 but adds three bytes
- X of state for the encoder to reduce noise (this format is not
- X understood by IVS).
- X
- The default encoding used by broadcast is PCM_64; use the "-a" option
- to use ADPCM_32_W_STATE, or "-A" for ADPCM_32. The radio program
- recognizes the encoding from the data packet header and so it does not
- need an option to select the encoding.
- X
- Changes by Alexander Dupuy <dupuy@tiemann.cs.columbia.edu> (thank you
- Alexander!):
- X
- Makefile: added a sunos4.1.2 target for our hacked version of 4.1.2 with
- X multicasts (a better name would be sun4.1-multi, since multicasting
- X is not standard in 4.1.2 (maybe in Solaris 2.0?).
- X
- broadcast.c: add a -m (multicast ttl) option, which sets the multicast ttl to
- X control the range over which multicast packets are forwarded.
- X this is necessary if you want multi-subnet multicasts.
- X
- broadcast.c: use $HOME/.CD and $HOME/.CDlog as default playfiles - this is a
- X bit more portable, as most sites will try to make sure that
- X users' home directories are accessible via the same path name on
- X all machines. It still fails (for .CDlog) when that is not true.
- X
- broadcast.c: if compiled with DEFMCAST defined as a valid multicast address
- radio.c: and HAVE_MCAST defined, broadcast and radio programs will default
- X to the multicast address DEFMCAST instead of broadcast.
- X
- broadcast.c: increase the maximum size of control packets to 512 bytes, to
- radio.c: support longer song titles (including artist and track title)
- X which WorkMan typically generates. Note that radio is also
- X changed to use a larger control packet size, since it uses the
- X length of incoming packets to determine whether they are control
- X or data (this is arguably a bug).
- X
- radio.c: attempt hostname lookup on -m (multicast) address argument, since it
- X is possible to put multicast addresses in /etc/hosts, NIS, and even,
- X with a bit of work, DNS.
- X
- broadcast.man: updated to reflect user-visible changes to the broadcast and
- radio.man: radio programs.
- X
- X
- Changes in 2.0 patchlevel 1
- X---------------------------
- X
- On the sun and sgi, radio tries to open a connection to the X server
- X(specified by the $DISPLAY environment variable) and every now and
- then makes a small request to exercise the connection. This ensures
- that if the user logs out, radio will quit. If no connection to the X
- server can be made, these checks are not made and a warning is printed
- that reminds the user to kill radio when logging out.
- X
- The usage message is more informative.
- X
- The new option '-t' (tee) sends output to both stdout and the audio
- device. Thanks to Scott Hazen Mueller for suggesting this.
- X
- The experimental option '-m mcastgrp' (for SGI only) specifies a
- multicast group. By multicasting instead of broadcasting, you can
- reduce the load on hosts that aren't listening (see the man page).
- X
- X
- Changes since version 1.0 patchlevel 4
- X--------------------------------------
- X
- X(Skip to the next section if you aren't already using version 1.0 of
- radio.)
- X
- The source structure has been changed -- all files are in one
- directory now.
- X
- More Python programs have been provided, and the existing ones have
- been improved. (Translations to C will be accepted and may end up in
- a future distribution -- here's your chance to gain world popularity!)
- X
- Building for the Sun now requires an explicit choice between sun4.0
- and sun4.1 -- "make sun" no longer works.
- X
- The radio program can now be "paused" by a separate tuner program.
- This means you don't have to kill the radio process if you want a few
- minutes of silence.
- X
- The broadcast program now broadcasts "station call" messages to a
- fixed port twice a minute, as a service to more sophisticated tuner
- programs. The Python program "stations.py" can be used to display
- these station calls (in a primitive manner).
- X
- The broadcast program now implements silence suppression: if the input
- is silent longer than 20 seconds it stops transmitting packets,
- keeping network overhead low. (You may have to tweak the level -- our
- typical "silent" input is rather noisy, so we set the livel rather
- high.)
- X
- Many minor changes and bugfixes.
- X
- X
- Building and installing
- X-----------------------
- X
- XFor SunOS 4.1 or higher (assuming the audio library is in
- X/usr/demo/SOUND), type "make sun4.1". For SGI IRIX, type "make sgi".
- XFor the NeXT, type "make next". This should produce binaries for
- X"radio" and "broadcast". For the SGI it also produces binaries
- X"recordulaw" and "playulaw"; for the NeXT, it also builds "sndulaw".
- Read the Makefile for details -- it's pretty trivial.
- X
- X(For SunOS 4.0, you may try "make sun4.0" instead. This does not make
- the assumption that the audio library is in /usr/demo/SOUND. Edit the
- Makefile if necessary to accomodate other locations.)
- X
- XFor SGI IRIX, the Makefile builds the "recordulaw" and "playulaw"
- programs. "recordulaw" uses the IRIX audio library to sample the
- audio input and convert it to U-LAW format. "playulaw" does the
- reverse (it is not actually used but provided as a convenience). The
- audio library is available on IRIS 4.0 and on IRIS 3.3.2 or higher.
- X
- Install the "radio" program on a convenient public place (where
- potential listeners can find it, e.g., /usr/local/bin); install
- X"broadcast" on a convenient place for yourself (assuming you're the
- one doing transmissions). The "recordulaw" or "sndulaw" programs, if
- needed, should be installed together with "broadcast". On an SGI
- system you may install "playulaw" if you like.
- X
- X
- Usage -- transmissions
- X----------------------
- X
- X(See the man page for broadcast for more details.)
- X
- To start transmissions on Sun Sparcs, run this command (probably in
- the background, once you've debugged your audio setup):
- X
- X broadcast -p port </dev/audio
- X
- You must connect a mono audio source to the machine using a standard
- cable provided by Sun. Control the input gain with [x_]gaintool
- X(e.g., /usr/demo/SOUND/x_gaintool).
- X
- X
- This command start transmissions on SGI IRIX:
- X
- X recordulaw | broadcast -p port
- X
- Connect a stereo audio source to the machine using a standard walkman
- jack. If you're using an early personal Iris, check that you have
- audio hardware and software installed -- the output from hinv will
- tell you this.
- X
- X
- On the NeXT you start transmissions as follows:
- X
- X sndulaw | broadcast -p port
- X
- This takes input from the microphone; you may also connect an audio
- source to the microphone input (probably needs some attenuation to get
- the impedance right).
- X
- X
- By default this broadcasts on the local ethernet. You can specify one
- or more -b options to broadcast, passing it explicit IP broadcast
- addresses (last byte 0 or 255, depending on local convention). You can
- specify your local IP net or another net; the latter only works if
- your gateways pass UDP broadcasts through (at CWI it works).
- X
- Note: each transmitter must choose a unique port number. The default
- is 54321; other suitable ports are 54322, 54323, and so on.
- X
- X
- Usage -- reception
- X------------------
- X
- X(See the man page for radio for more details.)
- X
- To listen to transmissions on either system:
- X
- X radio -p port
- X
- This sends the data directly to the audio output device (speaker or
- headphones). It is also possible to get the ULAW audio data on
- standard output with the -f option ("filter").
- X
- The -v option sets the output volume (on a scale from 0 to 100). To
- change the volume later on a Sun Sparc, use [x_]gaintool (at CWI:
- X/usr/demo/SOUND/x_gaintool). On an SGI, use "apanel".
- X
- X
- Bells 'n whistles
- X-----------------
- X
- Some Python programs are distributed together with radio. Python is
- an object-oriented prototyping language that I developed partly
- because I wanted to write system hacks without having to resort to C
- or Perl. Free source and documentation for the Python interpreter is
- available by anonymous ftp from various file servers, in particular
- ftp.cwi.nl (in the Netherlands) and wuarchive.wustl.edu (in the US).
- X
- The Python program "ttytuner.py" (by Jack Jansen) can be used to
- control the port that radio listens to. Note that this allows anybody
- on the world to control your radio, in principle. If you don't want
- this, you can pass the -s flag (secure), which turns off the control
- port altogether. By convention, the tuner program assumes that every
- user who performs transmissions has two files "CD" and "CDlog" in
- their home directory giving program information (this is actually a
- bad idea, since it requires that the listener and the broadcaster
- share the same file name space for user's home directories, but it
- saves a lot of complication in the broadcast program). Jack has also
- written a window-oriented tuner (using Motif) -- write to jack@cwi.nl
- for source.
- X
- The Python program "checkradio.py" (after an idea of Behr de Ruiter)
- continually checks and displays what one or more stations are
- transmitting. Arguments are port numbers (default is the default port
- to which radio is listening). When the "-t" option is given, it
- prints the reports on stdandard output. Without this option, it must
- be running on an SGI machine and uses only one port number argument.
- This goes in the background and opens a tiny window in which it
- displays the title of the program being transmitted (as glanced from
- the sender's CD file). The window's background color varies from
- bright yellow to dark red as the CD file gets older. When the
- transmission stops the window goes away altogether, to pop up only
- when it is resumed.
- X
- The Python program "stations.py" waits for incoming station call
- messages (transmitted regularly by "broadcast") and prints essential
- info from them on stdout.
- X
- The Python program "nielsen.py" implements a rudimentary way of
- finding out who's listening to what. Pass it a "-w" option to list
- the users on each host where it finds a listener. You must then be
- able to log in to that host remotely (with rlogin or rsh) without
- typing your password.
- X
- There is also one Perl program, just to show that you don't need to be
- entirely helpless if you don't have Python nor Motif:
- X
- The Perl program "stations.pl" listens for and prints essential
- information about stations. Extension to the functionality if
- X"stations.py" is left as an exercise to the reader.
- X
- X
- Author
- X------
- X
- The author of this software is:
- X
- Guido van Rossum
- CWI, dept. CST
- Kruislaan 413
- X1098 SJ Amsterdam
- The Netherlands
- X
- XE-mail (Internet) : Guido.van.Rossum@cwi.nl (guido@cwi.nl)
- XE-mail (X.400) : G=Guido;S=van.Rossum;O=cwi;PRMD=surf;ADMD=400net;C=nl
- X
- The "libst" U-LAW conversion library is written and copyrighted by Jef
- Poskanzer.
- X
- If you port this software to other systems or have useful additions
- X(like translations of Python programs to C), I'd like to hear from
- you.
- X
- X
- Acknowledgements
- X----------------
- X
- I would like the following contributors for pieces of code and/or
- documentation:
- X
- Toerless Eckert for the -n, -l, -r and -t options to radio
- X
- Paul Friedman for the -v option
- X
- Axel Belinfante for starting the man pages
- X
- Reimer A. Mellin for the NeXT port
- X
- Jack Jansen for the tuner programs and for many discussions about
- possible features
- X
- Behr de Ruiter for the idea for the checkradio program
- X
- X
- Copyright notice
- X----------------
- X
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- END_OF_FILE
- if test 15880 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'adpcm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'adpcm.c'\"
- else
- echo shar: Extracting \"'adpcm.c'\" \(7085 characters\)
- sed "s/^X//" >'adpcm.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/*
- X** Intel/DVI ADPCM coder/decoder.
- X**
- X** The algorithm for this coder was taken from the IMA Compatability Project
- X** proceedings, Vol 2, Number 2; May 1992.
- X**
- X** Version 1.1, 16-Dec-92.
- X**
- X** Change log:
- X** - Fixed a stupid bug, where the delta was computed as
- X** stepsize*code/4 in stead of stepsize*(code+0.5)/4. The old behavior can
- X** still be gotten by defining STUPID_V1_BUG.
- X*/
- X
- X#include "adpcm.h"
- X
- X#ifndef __STDC__
- X#define signed
- X#endif
- X
- X/* Intel ADPCM step variation table */
- static int indexTable[16] = {
- X -1, -1, -1, -1, 2, 4, 6, 8,
- X -1, -1, -1, -1, 2, 4, 6, 8,
- X};
- X
- static int stepsizeTable[89] = {
- X 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- X 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- X 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- X 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- X 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- X 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- X 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- X 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- X 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
- X};
- X
- void
- adpcm_coder(indata, outdata, len, state)
- X short indata[];
- X char outdata[];
- X int len;
- X struct adpcm_state *state;
- X{
- X short *inp; /* Input buffer pointer */
- X signed char *outp; /* output buffer pointer */
- X int val; /* Current input sample value */
- X int sign; /* Current adpcm sign bit */
- X int delta; /* Current adpcm output value */
- X int step; /* Stepsize */
- X int valprev; /* virtual previous output value */
- X int vpdiff; /* Current change to valprev */
- X int index; /* Current step change index */
- X int outputbuffer; /* place to keep previous 4-bit value */
- X int bufferstep; /* toggle between outputbuffer/output */
- X
- X outp = (signed char *)outdata;
- X inp = indata;
- X
- X if (state) {
- X valprev = state->valprev;
- X index = state->index;
- X }
- X else {
- X valprev = 0;
- X index = 0;
- X }
- X step = stepsizeTable[index];
- X
- X bufferstep = 1;
- X
- X for ( ; len > 0 ; len-- ) {
- X val = *inp++;
- X
- X /* Step 1 - compute difference with previous value */
- X delta = val - valprev;
- X sign = (delta < 0) ? 8 : 0;
- X if ( sign ) delta = (-delta);
- X
- X /* Step 2 - Divide and clamp */
- X#ifdef NODIVMUL
- X {
- X int tmp = 0;
- X#ifdef STUPID_V1_BUG
- X vpdiff = 0;
- X#else
- X vpdiff = (step >> 3);
- X#endif /* STUPID_V1_BUG */
- X if ( delta > step ) {
- X tmp = 4;
- X delta -= step;
- X vpdiff += step;
- X }
- X step >>= 1;
- X if ( delta > step ) {
- X tmp |= 2;
- X delta -= step;
- X vpdiff += step;
- X }
- X step >>= 1;
- X if ( delta > step ) {
- X tmp |= 1;
- X vpdiff += step;
- X }
- X delta = tmp;
- X }
- X#else
- X delta = (delta<<2) / step;
- X if ( delta > 7 ) delta = 7;
- X
- X#ifdef STUPID_V1_BUG
- X vpdiff = (delta*step) >> 2;
- X#else
- X vpdiff = ((delta*step) >> 2) + (step >> 3);
- X#endif /* STUPID_V1_BUG */
- X#endif /* NODIVMUL */
- X
- X /* Step 3 - Update previous value */
- X if ( sign )
- X valprev -= vpdiff;
- X else
- X valprev += vpdiff;
- X
- X /* Step 4 - Clamp previous value to 16 bits */
- X if ( valprev > 32767 )
- X valprev = 32767;
- X else if ( valprev < -32768 )
- X valprev = -32768;
- X
- X /* Step 5 - Assemble value, update index and step values */
- X delta |= sign;
- X
- X index += indexTable[delta];
- X if ( index < 0 ) index = 0;
- X if ( index > 88 ) index = 88;
- X step = stepsizeTable[index];
- X
- X /* Step 6 - Output value */
- X if ( bufferstep ) {
- X outputbuffer = (delta << 4) & 0xf0;
- X } else {
- X *outp++ = (delta & 0x0f) | outputbuffer;
- X }
- X bufferstep = !bufferstep;
- X }
- X
- X /* Output last step, if needed */
- X if ( !bufferstep )
- X *outp++ = outputbuffer;
- X
- X if (state) {
- X state->valprev = valprev;
- X state->index = index;
- X }
- X}
- X
- void
- adpcm_decoder(indata, outdata, len, state)
- X char indata[];
- X short outdata[];
- X int len;
- X struct adpcm_state *state;
- X{
- X signed char *inp; /* Input buffer pointer */
- X short *outp; /* output buffer pointer */
- X int sign; /* Current adpcm sign bit */
- X int delta; /* Current adpcm output value */
- X int step; /* Stepsize */
- X int valprev; /* virtual previous output value */
- X int vpdiff; /* Current change to valprev */
- X int index; /* Current step change index */
- X int inputbuffer; /* place to keep next 4-bit value */
- X int bufferstep; /* toggle between inputbuffer/input */
- X
- X outp = outdata;
- X inp = (signed char *)indata;
- X
- X if (state) {
- X valprev = state->valprev;
- X index = state->index;
- X }
- X else {
- X valprev = 0;
- X index = 0;
- X }
- X step = stepsizeTable[index];
- X
- X bufferstep = 0;
- X
- X for ( ; len > 0 ; len-- ) {
- X
- X /* Step 1 - get the delta value and compute next index */
- X if ( bufferstep ) {
- X delta = inputbuffer & 0xf;
- X } else {
- X inputbuffer = *inp++;
- X delta = (inputbuffer >> 4) & 0xf;
- X }
- X bufferstep = !bufferstep;
- X
- X /* Step 2 - Find new index value (for later) */
- X index += indexTable[delta];
- X if ( index < 0 ) index = 0;
- X if ( index > 88 ) index = 88;
- X
- X /* Step 3 - Separate sign and magnitude */
- X sign = delta & 8;
- X delta = delta & 7;
- X
- X /* Step 4 - update output value */
- X#ifdef NODIVMUL
- X#ifdef STUPID_V1_BUG
- X vpdiff = 0;
- X#else
- X vpdiff = step >> 1;
- X#endif /* STUPID_V1_BUG */
- X if ( delta & 4 ) vpdiff += (step << 2);
- X if ( delta & 2 ) vpdiff += (step << 1);
- X if ( delta & 1 ) vpdiff += step;
- X vpdiff >>= 2;
- X#else
- X#ifdef STUPID_V1_BUG
- X vpdiff = ((delta*step) >> 2);
- X#else
- X vpdiff = ((delta*step) >> 2) + (step >> 3);
- X#endif /* STUPID_V1_BUG */
- X#endif /* ! NODIVMUL */
- X if ( sign )
- X valprev -= vpdiff;
- X else
- X valprev += vpdiff;
- X
- X /* Step 5 - clamp output value */
- X if ( valprev > 32767 )
- X valprev = 32767;
- X else if ( valprev < -32768 )
- X valprev = -32768;
- X
- X /* Step 6 - Update step value */
- X step = stepsizeTable[index];
- X
- X /* Step 7 - Output value */
- X *outp++ = valprev;
- X }
- X
- X if (state) {
- X state->valprev = valprev;
- X state->index = index;
- X }
- X}
- END_OF_FILE
- if test 7085 -ne `wc -c <'adpcm.c'`; then
- echo shar: \"'adpcm.c'\" unpacked with wrong size!
- fi
- # end of 'adpcm.c'
- fi
- if test -f 'adpcm.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'adpcm.h'\"
- else
- echo shar: Extracting \"'adpcm.h'\" \(563 characters\)
- sed "s/^X//" >'adpcm.h' <<'END_OF_FILE'
- X/*
- X** adpcm.h - include file for adpcm coder.
- X**
- X** Version 1.0, 7-Jul-92.
- X*/
- X
- struct adpcm_state {
- X short valprev; /* Previous output value */
- X char index; /* Index into stepsize table */
- X};
- X
- X#ifdef __STDC__
- X#define ARGS(x) x
- X#else
- X#define ARGS(x) ()
- X#endif
- X
- void adpcm_coder ARGS((short [], char [], int, struct adpcm_state *));
- void adpcm_decoder ARGS((char [], short [], int, struct adpcm_state *));
- void ulaw_adpcm_coder ARGS((char [], char [], int, struct adpcm_state *));
- void adpcm_ulaw_decoder ARGS((char [], char [], int, struct adpcm_state *));
- END_OF_FILE
- if test 563 -ne `wc -c <'adpcm.h'`; then
- echo shar: \"'adpcm.h'\" unpacked with wrong size!
- fi
- # end of 'adpcm.h'
- fi
- if test -f 'broadcast.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'broadcast.man'\"
- else
- echo shar: Extracting \"'broadcast.man'\" \(7425 characters\)
- sed "s/^X//" >'broadcast.man' <<'END_OF_FILE'
- X.TH BROADCAST 1
- X.SH NAME
- broadcast \- send audio UDP packets to be received by radio
- X.SH SYNOPSIS
- X.B broadcast
- X[
- X.B "\-a"
- X] [
- X.B "\-A"
- X] [
- X.BI "\-b " addr
- X] ... [
- X.BI "\-c " port
- X] [
- X.BI \-d
- X]
- X [
- X.BI "\-m " ttl
- X] [
- X.BI \-n
- X] [
- X.BI "\-p " port
- X] [
- X.BI \-t
- X]
- X [
- X.BI "\-L " logfile
- X] [
- X.BI "-N " name
- X] [
- X.BI "\P " programfile
- X]
- X.SH DESCRIPTION
- X.I Broadcast
- reads audio data in U-LAW format (8000 samples/second, 1 byte/sample,
- logarithmically encoded) from standard input, chops it up into packets
- of about 1400 bytes each, and transmits these as UDP broadcast packets.
- On a typical ethernet, this uses about 1 percent of the net available
- bandwith (less than 6 maximum-size packets per second). If this is
- still too much, the
- X.B \-a
- option can cut the required bandwidth in half.
- X.PP
- The program
- X.IR radio (1)
- listens for these packets, reassembles them and makes the encoded
- sound audible, given suitable hardware.
- X.PP
- It is possible to use multiple transmission stations (each identified
- by a different UDP port), and to transmit to multiple connected
- subnets simultaneously, as long as the gateways let UDP broadcast
- packets through.
- XEach transmission station should run on a different host though.
- X.SH OPTIONS
- X.TP 10
- X.BR "\-a"
- Use ADPCM (Adaptive Delta Pulse Code Modulation) to compress the audio data.
- It sends out packets at the same rate, but the packet size is cut in
- half. This saves about 50 percent of the required network bandwidth,
- at the cost of some CPU time (for the receivers as well as as for the
- sender). There is a slight degradation in sound quality, but the
- quality is actually still quite good. The receiver adapts itself
- automatically to the data format.
- X.TP 10
- X.BR "\-A"
- Use a variant on ADPCM (Adaptive Delta Pulse Code Modulation) which is
- compatible the IVS program from INRIA.
- X.TP 10
- X.BI "\-b " addr
- IP address to send to. The default is either the local net broadcast address
- or a multicast address assigned to radio if the host supports IP multicasts.
- The address may be a host name (for unicast), an IP broadcast address,
- or an IP multicast address (addresses beginning with 224).
- More than one
- X.B \-b
- option may be given; the data is sent to each address.
- X.TP 10
- X.BI "\-c " port
- Use this UDP port number as control port (default 54320).
- Normally you never need to change this; the control port is used by
- optional ``tuner'' software (distributed separately).
- X.TP 10
- X.B \-d
- Turn on debugging (a message on stderr for each 8 packets sent).
- X.TP 10
- X.BI "\-m " ttl
- Use this to specify a multicast TTL, to control how far the multicasts
- will propagate. A value of 0 restricts them to the same host,
- X1 to the same subnet, 32 to the same ``site,'' 64 to the same ``region,''
- X128 to the same continent, and 255 is unrestricted. The default is 32.
- Note that this option only has an effect if your machine supports multicasts
- and you specify a multicast address with the
- X.B \-b
- option.
- X.TP 10
- X.B \-n
- No silence suppression.
- Normally, when the input contains more than 20 seconds of silence,
- output packets are suppressed until some noise is detected again.
- This option turns off that feature.
- X.TP 10
- X.BI "\-p " port
- Transmit to this UDP port number (default 54321).
- X.TP 10
- X.B \-t
- When the input is faster than real time, e.g., read from a file, this
- option ensures that the packets are sent out at the correct rate (8000
- bytes/sec).
- Normally, it is presumed that the standard input takes care of this.
- X.TP 10
- X.BI "\-L " logfile
- The filename of the file where recent program information is logged.
- Typically, each time the current program information is changed it is
- also appended to this file.
- Default is $HOME/.CDlog.
- X.TP 10
- X.BI "\-N " name
- The name of the station.
- Default the current username.
- X.TP 10
- X.BI "\-P " programfile
- The name of the file where current program information is kept (one line).
- Typically, this file contains three colon-separated fields:
- performer, composer, and title, where the composer field is only used
- for classical music.
- Default is $HOME/.CD.
- X.SH TYPICAL USAGE
- Due to the different interface to audio input hardware on different
- systems, transmissions are started differently on different platforms.
- X.PP
- To start transmissions on Sun Sparcs, run this command (probably in
- the background, once you've debugged your audio setup):
- X.IP
- broadcast -p \fIport\fP </dev/audio
- X.PP
- You must connect a mono audio source to the machine using a standard
- cable provided by Sun.
- Control the input gain with
- X.IR x_gaintool (1)
- or
- X.IP gaintool (1)
- X(these programs can be found in /usr/demo/SOUND in SunOS 4.1).
- X.PP
- This command start transmissions on SGI IRIX:
- X.IP
- recordulaw | broadcast -p \fIport\fP
- X.PP
- Connect a stereo audio source to the machine using a standard walkman
- jack.
- If you're using an early 4D/35, check that you have audio hardware and
- software installed -- the output from hinv will tell you this.
- Control the the input gain with
- X.IR apanel (1).
- X.PP
- On the NeXT you start transmissions as follows:
- X.IP
- sndulaw | broadcast -p \fIport\fP
- X.PP
- This takes input from the microphone; you may also connect an audio
- source to the microphone input (probably needs some attenuation to get
- the impedance right).
- X.SH FORWARDING
- If nets A and B are connected by a gateway that blocks UDP broadcasts
- but lets normal packets through, you can set up a forwarding station
- as follows.
- Assume A.1 is the host on net A where broadcasts originate, A.0 is the
- broadcast address for net A, host B.1 is the forwarding host on net B,
- and B.0 is net B's broadcast address.
- X(You will have to specify IP broadcast addresses in the decimal
- X.I ddd.ddd.ddd.ddd
- format; usually the broadcast address for a net is the same as the IP
- address for hosts on that net with the last byte changed to 0 or 255.)
- On host A.1, run
- X.I broadcast
- as follows:
- X.IP
- broadcast -b A.0 -b B.1
- X.PP
- On host B.1, run this pipeline:
- X.IP
- radio -l B.1 -r A.1 -f | broadcast -b B.0
- X.PP
- Now all hosts on nets A and B can listen to the broadcasts from host
- A.1, at the cost of 100% extra (unicast) packets on both nets.
- X.PP
- If the gateway lets UDP broadcast packets through, no forwarding is
- necessary; running ``broadcast -b A.0 -b B.0'' on host A.1 is
- sufficient.
- X.SH AUTHOR
- Guido van Rossum
- X.SH VERSION
- This manual page documents broadcast version 2.0, patchlevel 0.
- X.SH SEE ALSO
- radio(1)
- X.SH COPYRIGHT
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- END_OF_FILE
- if test 7425 -ne `wc -c <'broadcast.man'`; then
- echo shar: \"'broadcast.man'\" unpacked with wrong size!
- fi
- # end of 'broadcast.man'
- fi
- if test -f 'libst.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libst.c'\"
- else
- echo shar: Extracting \"'libst.c'\" \(3474 characters\)
- sed "s/^X//" >'libst.c' <<'END_OF_FILE'
- X/* libst.c - portable sound tools library
- X*/
- X
- X/*
- X** This routine converts from linear to ulaw.
- X**
- X** Craig Reese: IDA/Supercomputing Research Center
- X** Joe Campbell: Department of Defense
- X** 29 September 1989
- X**
- X** References:
- X** 1) CCITT Recommendation G.711 (very difficult to follow)
- X** 2) "A New Digital Technique for Implementation of Any
- X** Continuous PCM Companding Law," Villeret, Michel,
- X** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
- X** 1973, pg. 11.12-11.17
- X** 3) MIL-STD-188-113,"Interoperability and Performance Standards
- X** for Analog-to_Digital Conversion Techniques,"
- X** 17 February 1987
- X**
- X** Input: Signed 16 bit linear sample
- X** Output: 8 bit ulaw sample
- X*/
- X
- X/* #define ZEROTRAP /* turn on the trap as per the MIL-STD */
- X#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
- X#define CLIP 32635
- X
- unsigned char
- st_linear_to_ulaw( sample )
- int sample;
- X {
- X static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- X 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- X 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- X 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
- X int sign, exponent, mantissa;
- X unsigned char ulawbyte;
- X
- X /* Get the sample into sign-magnitude. */
- X sign = (sample >> 8) & 0x80; /* set aside the sign */
- X if ( sign != 0 ) sample = -sample; /* get magnitude */
- X if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
- X
- X /* Convert from 16 bit linear to ulaw. */
- X sample = sample + BIAS;
- X exponent = exp_lut[( sample >> 7 ) & 0xFF];
- X mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
- X ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
- X#ifdef ZEROTRAP
- X if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
- X#endif
- X
- X return ulawbyte;
- X }
- X
- X/*
- X** This routine converts from ulaw to 16 bit linear.
- X**
- X** Craig Reese: IDA/Supercomputing Research Center
- X** 29 September 1989
- X**
- X** References:
- X** 1) CCITT Recommendation G.711 (very difficult to follow)
- X** 2) MIL-STD-188-113,"Interoperability and Performance Standards
- X** for Analog-to_Digital Conversion Techniques,"
- X** 17 February 1987
- X**
- X** Input: 8 bit ulaw sample
- X** Output: signed 16 bit linear sample
- X*/
- X
- int
- st_ulaw_to_linear_slow( ulawbyte )
- unsigned char ulawbyte;
- X {
- X static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
- X int sign, exponent, mantissa, sample;
- X
- X ulawbyte = ~ ulawbyte;
- X sign = ( ulawbyte & 0x80 );
- X exponent = ( ulawbyte >> 4 ) & 0x07;
- X mantissa = ulawbyte & 0x0F;
- X sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
- X if ( sign != 0 ) sample = -sample;
- X
- X return sample;
- X }
- END_OF_FILE
- if test 3474 -ne `wc -c <'libst.c'`; then
- echo shar: \"'libst.c'\" unpacked with wrong size!
- fi
- # end of 'libst.c'
- fi
- if test -f 'libst.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libst.h'\"
- else
- echo shar: Extracting \"'libst.h'\" \(3224 characters\)
- sed "s/^X//" >'libst.h' <<'END_OF_FILE'
- X/* libst.h - include file for portable sound tools library
- X**
- X** Copyright (C) 1989 by Jef Poskanzer.
- X**
- X** Permission to use, copy, modify, and distribute this software and its
- X** documentation for any purpose and without fee is hereby granted, provided
- X** that the above copyright notice appear in all copies and that both that
- X** copyright notice and this permission notice appear in supporting
- X** documentation. This software is provided "as is" without express or
- X** implied warranty.
- X*/
- X
- X#define SAMPLES_PER_SECOND 8192
- X
- X#define MINLIN -32768
- X#define MAXLIN 32767
- X#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; else if ( x > MAXLIN ) x = MAXLIN; } while ( 0 )
- X
- unsigned char st_linear_to_ulaw( /* int sample */ );
- int st_ulaw_to_linear_slow( /* unsigned char ulawbyte */ );
- X
- X/*
- X** This macro converts from ulaw to 16 bit linear, faster.
- X**
- X** Jef Poskanzer
- X** 23 October 1989
- X**
- X** Input: 8 bit ulaw sample
- X** Output: signed 16 bit linear sample
- X*/
- X#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
- X
- static int ulaw_table[256] = {
- X -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
- X -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
- X -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
- X -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
- X -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
- X -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
- X -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
- X -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
- X -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
- X -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
- X -876, -844, -812, -780, -748, -716, -684, -652,
- X -620, -588, -556, -524, -492, -460, -428, -396,
- X -372, -356, -340, -324, -308, -292, -276, -260,
- X -244, -228, -212, -196, -180, -164, -148, -132,
- X -120, -112, -104, -96, -88, -80, -72, -64,
- X -56, -48, -40, -32, -24, -16, -8, 0,
- X 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
- X 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
- X 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
- X 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
- X 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
- X 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
- X 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
- X 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
- X 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
- X 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
- X 876, 844, 812, 780, 748, 716, 684, 652,
- X 620, 588, 556, 524, 492, 460, 428, 396,
- X 372, 356, 340, 324, 308, 292, 276, 260,
- X 244, 228, 212, 196, 180, 164, 148, 132,
- X 120, 112, 104, 96, 88, 80, 72, 64,
- X 56, 48, 40, 32, 24, 16, 8, 0 };
- END_OF_FILE
- if test 3224 -ne `wc -c <'libst.h'`; then
- echo shar: \"'libst.h'\" unpacked with wrong size!
- fi
- # end of 'libst.h'
- fi
- if test -f 'nielsen.py' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'nielsen.py'\"
- else
- echo shar: Extracting \"'nielsen.py'\" \(2897 characters\)
- sed "s/^X//" >'nielsen.py' <<'END_OF_FILE'
- X#! /ufs/guido/bin/sgi/python
- X
- X# /***********************************************************
- X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- X# Netherlands.
- X#
- X# All Rights Reserved
- X#
- X# Permission to use, copy, modify, and distribute this software and its
- X# documentation for any purpose and without fee is hereby granted,
- X# provided that the above copyright notice appear in all copies and that
- X# both that copyright notice and this permission notice appear in
- X# supporting documentation, and that the names of Stichting Mathematisch
- X# Centrum or CWI not be used in advertising or publicity pertaining to
- X# distribution of the software without specific, written prior permission.
- X#
- X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X#
- X# ******************************************************************/
- X
- X# Radio listening statistics.
- X#
- X# usage: nielsen [-w] [port]
- X# -w print who's logged on (slow)
- X# port alternate port to broadcast to
- X#
- X# XXX should understand -b options as well, instead of hardwiring addresses.
- X
- import sys, os, time, string
- from socket import *
- try:
- X # 'nis' is an optional module which interfaces to NIS (a.k.a. YP)
- X import nis
- except ImportError:
- X # If nis doesn't exist, too bad -- don't print hostnames then
- X nis = None
- X
- addrlist = '192.16.184.0', '192.16.191.0', '192.16.201.255'
- port = 54320
- who = 0
- if sys.argv[1:2] == ['-w']: who = 1; sys.argv[1:2] = []
- if sys.argv[1:]: port = eval(sys.argv[1])
- X
- s = socket(AF_INET, SOCK_DGRAM)
- s.allowbroadcast(1)
- for addr in addrlist:
- X s.sendto('radio:i', (addr, port))
- X
- TIMEOUT = 7
- X
- try:
- X while 1:
- X # Time-out if no next response within TIMEOUT seconds
- X for i in range(TIMEOUT):
- X if s.avail(): break
- X else: time.sleep(1)
- X else:
- X print 'Time-out -- assume no more responses.'
- X break # out of the enclosing while loop
- X data, (host, port) = s.recvfrom(1400)
- X print data, host,
- X try:
- X response = nis.match(host, 'hosts.byaddr')
- X words = string.split(response)
- X print words[1],
- X except nis.error:
- X pass
- X print
- X if who:
- X cmd = 'rusers ' + host
- X line = os.popen(cmd, 'r').read()
- X words = string.split(line)
- X del words[0]
- X for w in words[:]:
- X if words.count(w) > 1: words.remove(w)
- X words.sort()
- X for w in words: print w,
- X print
- X # Old version using rsh who:
- X # cmd = 'who | sed \'s/ .*//\' | sort -u'
- X # sts = os.system('rsh ' + host + ' "' + cmd + '"')
- except KeyboardInterrupt:
- X pass
- END_OF_FILE
- if test 2897 -ne `wc -c <'nielsen.py'`; then
- echo shar: \"'nielsen.py'\" unpacked with wrong size!
- fi
- chmod +x 'nielsen.py'
- # end of 'nielsen.py'
- fi
- if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patchlevel.h'\"
- else
- echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
- sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
- X#define PATCHLEVEL 2
- END_OF_FILE
- if test 21 -ne `wc -c <'patchlevel.h'`; then
- echo shar: \"'patchlevel.h'\" unpacked with wrong size!
- fi
- # end of 'patchlevel.h'
- fi
- if test -f 'playulaw.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'playulaw.c'\"
- else
- echo shar: Extracting \"'playulaw.c'\" \(4154 characters\)
- sed "s/^X//" >'playulaw.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/* Play ulaw audio data read from stdin */
- X
- X#define BUFFERSIZE 4000
- X
- X#ifdef sgi
- X#define USE_AL
- X#endif
- X#ifdef sun
- X#define USE_SUN
- X#endif
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <stdlib.h>
- X#include <fcntl.h>
- X#include <signal.h>
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <netinet/in.h>
- X
- X#ifdef USE_AL
- X#include <audio.h>
- X#include "libst.h"
- X
- long savestate[] = {
- X AL_OUTPUT_RATE, 0,
- X};
- X#endif
- X
- X#ifdef USE_SUN
- X#include <stropts.h>
- X#endif
- X
- X/* getopt() interface */
- extern int optind;
- extern char * optarg;
- X
- X/* Forward */
- void cleanup_handler();
- X
- X/* Globals */
- char *progname;
- X
- main(argc, argv)
- X int argc;
- X char **argv;
- X{
- X char buf[BUFFERSIZE];
- X int n;
- X int c;
- X int ifd, ofd;
- X int sts = 0;
- X#ifdef USE_AL
- X short obuf[BUFFERSIZE];
- X ALport aport;
- X ALconfig config;
- X int i;
- X long pvbuf[2];
- X#endif
- X
- X progname = argv[0];
- X while ((c = getopt(argc, argv, "")) != EOF) {
- X switch (c) {
- X case '?':
- X usage();
- X }
- X }
- X
- X if (optind >= argc) {
- X ifd = fileno(stdin);
- X }
- X else {
- X if (optind+1 < argc)
- X usage();
- X ifd = open(argv[optind], 0);
- X if (ifd < 0) {
- X perror(argv[optind]);
- X exit(1);
- X }
- X }
- X
- X#ifdef USE_AL
- X /* Fetch the original state */
- X ALgetparams(AL_DEFAULT_DEVICE, savestate,
- X sizeof(savestate) / sizeof(long));
- X
- X /* Set signal handlers */
- X signal(SIGINT, cleanup_handler);
- X signal(SIGTERM, cleanup_handler);
- X
- X /* Configure and open an SGI audio port */
- X config = ALnewconfig();
- X ALsetchannels(config, AL_MONO);
- X ALsetwidth(config, AL_SAMPLE_16);
- X ALsetqueuesize(config, 16000); /* 2 seconds slop */
- X aport = ALopenport("radio", "w", config);
- X if (aport == NULL) {
- X perror("ALopenport");
- X exit(1);
- X }
- X
- X /* Set the output sampling rate to 8000 Hz */
- X /* Do this after ALopenport so we needn't undo it if that fails */
- X pvbuf[0] = AL_OUTPUT_RATE;
- X pvbuf[1] = AL_RATE_8000;
- X ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2L);
- X#else
- X /* Write to /dev/audio */
- X if ((ofd = open("/dev/audio", O_WRONLY | O_NDELAY)) < 0) {
- X perror("/dev/audio");
- X exit(1);
- X }
- X#endif
- X
- X for (;;) {
- X n = read(ifd, buf, BUFFERSIZE);
- X if (n <= 0) {
- X if (n < 0) {
- X perror("read");
- X sts = 1;
- X }
- X break;
- X }
- X#ifdef USE_AL
- X for (i = 0; i < n; i++)
- X obuf[i] = st_ulaw_to_linear(buf[i]);
- X ALwritesamps(aport, obuf, (long)n);
- X#else
- X if (write(ofd, buf, n) != n) {
- X perror("write");
- X sts = 1;
- X break;
- X }
- X#endif
- X }
- X
- X#ifdef USE_AL
- X /* Wait until all sound has played */
- X while(ALgetfilled(aport) > 0) /* still sound to play */
- X sginap(1); /* sleep for 1/60 of a second */
- X
- X /* Restore the output sampling rate */
- X ALsetparams(AL_DEFAULT_DEVICE, savestate,
- X sizeof(savestate) / sizeof(long));
- X#endif
- X
- X exit(sts);
- X}
- X
- usage()
- X{
- X fprintf(stderr, "usage: %s [file]\n", progname);
- X exit(2);
- X}
- X
- X#ifdef USE_AL
- X
- void cleanup_handler(sig)
- X int sig;
- X{
- X signal(sig, SIG_DFL);
- X ALsetparams(AL_DEFAULT_DEVICE, savestate,
- X sizeof(savestate) / sizeof(long));
- X kill(getpid(), sig);
- X}
- X
- X#endif /* USE_AL */
- END_OF_FILE
- if test 4154 -ne `wc -c <'playulaw.c'`; then
- echo shar: \"'playulaw.c'\" unpacked with wrong size!
- fi
- # end of 'playulaw.c'
- fi
- if test -f 'radio.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'radio.h'\"
- else
- echo shar: Extracting \"'radio.h'\" \(2085 characters\)
- sed "s/^X//" >'radio.h' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/* Constants shared by radio.c and broadcast.c */
- X
- X#define BCASTCTLPORT 54319
- X#define RADIOCTLPORT 54320
- X#define RCVPORT 54321
- X#define SENDPORT 54318
- X#define INFOPORT 54317
- X
- X#define SAMPLINGRATE 8000
- X
- X#define BUFFERSIZE 1400
- X#define CTLPKTSIZE 512
- X#define INFOFREQ ((30*SAMPLINGRATE) / BUFFERSIZE)
- X
- X#define HEADERSIZE 2 /* IVS header: 2 bytes (type, encoding) */
- X
- X#define TYPE_MASK (3<<6)
- X#define AUDIO_TYPE (2<<6)
- X
- X#define PCM_64 0
- X#define PCM_32 1
- X#define ADPCM_32 2
- X#define VADPCM 3
- X#define ADPCM_32_W_STATE 66
- X
- X#ifndef DEFMCAST
- X#define DEFMCAST "224.0.2.5"
- X#endif
- X
- X#ifndef MULTICAST_TTL
- X#define MULTICAST_TTL 32
- X#endif
- X
- X#define VERSION "2.0"
- X
- X#ifdef sgi
- X#define USE_AL
- X#define CHECK_X_SERVER
- X#define HAVE_MCAST
- X#endif
- X
- X#ifdef sun
- X#define SUNHACKS
- X#define USE_SUN
- X#define CHECK_X_SERVER
- X#endif
- X
- X#ifdef NeXT
- X#define USE_NX
- X#endif
- END_OF_FILE
- if test 2085 -ne `wc -c <'radio.h'`; then
- echo shar: \"'radio.h'\" unpacked with wrong size!
- fi
- # end of 'radio.h'
- fi
- if test -f 'radio.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'radio.man'\"
- else
- echo shar: Extracting \"'radio.man'\" \(4529 characters\)
- sed "s/^X//" >'radio.man' <<'END_OF_FILE'
- X.TH RADIO 1
- X.SH NAME
- radio \- receive audio UDP packets transmitted by broadcast
- X.SH SYNOPSIS
- X.B radio
- X[
- X.B \-c
- X.I port
- X] [
- X.B \-d
- X] [
- X.B \-f
- X] [
- X.B \-l
- X.I addr
- X] [
- X.B \-m
- X.I mcastgrp
- X]
- X [
- X.B \-n
- X] [
- X.B \-p
- X.I port
- X] [
- X.B -r
- X.I addr
- X] [
- X.B \-s
- X] [
- X.B \-t
- X] [
- X.B \-v
- X.I volume
- X]
- X.SH DESCRIPTION
- X.I Radio
- allows you to listen to audio transmitted as UDP packets on a local
- area network by
- X.IR broadcast (1).
- Obviously, this requires a workstation with audio hardware; currently
- the program works on SGI Indigo and 4D/35 workstations, Sun Sparcs, and
- all NeXTs.
- X.PP
- X.I Radio
- is normally run in the background.
- You may need a system-specific tool to change the volume or direct the
- output to the speaker or headphone jack; e.g., on an SGI, you would
- use
- X.IR apanel (1);
- X on a Sun you would use
- X.IR gaintool (1)
- or, when using X,
- X.IR x_gaintool (1)
- X(these programs can be found in /usr/demo/SOUND in SunOS 4.1).
- With OpenWindows 3.0, you can use
- X.IR audiotool (1).
- X(On the NeXT, just use the volume keys on the keyboard.)
- X.PP
- Some loss of UDP packets is tolerated; this is heard as short
- interruptions of the sound.
- X.SH OPTIONS
- X.TP 10
- X.BI "\-c " port
- Use this UDP port number as control port (default 54320).
- Normally you never need to change this; the control port is used by
- optional ``tuner'' software (not distributed) and possibly by listener
- polling programs.
- X.TP 10
- X.B \-d
- Turn on debugging (a message on stderr for each 8 packets received,
- and when rare or unexpected events happen).
- X.TP 10
- X.B \-f
- XFilter mode: write the U-LAW audio data to stdout instead of
- sending it to the audio hardware.
- X.TP 10
- X.BI "\-l " addr
- Listen only for packets to IP address
- X.I addr
- X(useful for forwarding stations).
- X.TP 10
- X.BI "\-m " mcastgrp
- Multicast group.
- This only makes sense if the same multicast group is passed to the
- X.B \-b
- option of
- X.IR broadcast (1).
- Using multicasting instead of broadcasting reduces the load on
- machines that aren't listening.
- You should use the same multicast group for all stations on the local network.
- X(Note that even if a multicast group is specified, stations using broadcasts
- can still be picked up by radio).
- X.TP 10
- X.B \-n
- Noninterruptable mode (Sun Sparc only).
- By default,
- X.I radio
- notices when another program wants to open the
- audio output device, and temporarily ``backs off'' until the other
- program is finished, hoping it won't take too long.
- This option turns off that feature.
- X.TP 10
- X.BI "\-p " port
- Receive packets sent to this UDP port number (default 54321).
- This corresponds to the port used by
- X.I broadcast.
- Port numbers 1..99 are shorthands for 54321..54419.
- X.TP 10
- X.BI "\-r " addr
- Listen only for packets from IP address
- X.I addr
- X(useful for forwarding stations).
- X.TP 10
- X.B \-s
- Secure mode: don't listen to the control port.
- This is for really paranoid users: in theory, any user on the net
- can override the port specified with \fB\-p\fP by sending a control
- message to the control port of your radio program.
- X.TP 10
- X.B \-t
- Tee mode: write the U-LAW audio data to stdout as well as
- sending it to the audio hardware.
- X.TP 10
- X.BI "\-v " volume
- Set the initial volume, on a scale from 0 to 100. (SGI and Sun Sparc only.)
- By default, the volume is left unchanged.
- When the volume is specified this way, its original value is restored
- when the program exits.
- X.SH AUTHOR
- Guido van Rossum
- X.SH VERSION
- This manual page documents radio version 2.0, patchlevel 1.
- X.SH SEE ALSO
- broadcast(1)
- X.SH COPYRIGHT
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- END_OF_FILE
- if test 4529 -ne `wc -c <'radio.man'`; then
- echo shar: \"'radio.man'\" unpacked with wrong size!
- fi
- # end of 'radio.man'
- fi
- if test -f 'recordlinear.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'recordlinear.c'\"
- else
- echo shar: Extracting \"'recordlinear.c'\" \(3541 characters\)
- sed "s/^X//" >'recordlinear.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/* Record SGI audio data and output it as 8 kHz signed 16-bits samples,
- X converting the sampling rate and encoding on the fly.
- X This writes to stdout.
- X
- X Caveats:
- X - since it uses an audio port, of which there can only be 4 open
- X at a time, running several copies is not a good idea;
- X see broadcast.c and radio.c for a distribution mechanism.
- X
- X To do:
- X - support the other three sampling rates
- X*/
- X
- X#include <stdio.h>
- X#include <audio.h>
- X
- int inrate;
- X
- X#define OUTRATE 8000
- X#define INBUFSIZE 48000
- X
- main(argc, argv)
- X int argc;
- X char **argv;
- X{
- X short inbuf[INBUFSIZE];
- X short outbuf[8000];
- X ALconfig c;
- X ALport p;
- X int n;
- X int insamps;
- X int sts = 0;
- X
- X checkinrate();
- X insamps = calcinsamps();
- X
- X c = ALnewconfig();
- X if (c == NULL) {
- X perror("ALnewconfig");
- X exit(1);
- X }
- X ALsetwidth(c, AL_SAMPLE_16);
- X ALsetchannels(c, AL_MONO);
- X
- X p = ALopenport(argv[0], "r", c);
- X if (p == NULL) {
- X perror("ALopenport");
- X exit(1);
- X }
- X
- X for (;;) {
- X checkinrate();
- X insamps = calcinsamps();
- X ALreadsamps(p, (void *)inbuf, insamps);
- X n = convert(inbuf, insamps, outbuf);
- X n = n * sizeof(short);
- X if (write(1, (char *)outbuf, n) != n) {
- X perror("write error");
- X sts = 1;
- X break;
- X }
- X }
- X
- X exit(sts);
- X}
- X
- int calcinsamps()
- X{
- X int insamps = inrate/2;
- X if (insamps > INBUFSIZE)
- X insamps = INBUFSIZE;
- X return insamps;
- X}
- X
- checkinrate()
- X{
- X inrate = getinrate();
- X if ((inrate/OUTRATE)*OUTRATE != inrate) {
- X fprintf(stderr,
- X "current sampling rate (%d) is not a multiple of %d\n",
- X inrate, OUTRATE);
- X exit(1);
- X }
- X}
- X
- int getinrate()
- X{
- X long PVbuffer[2];
- X
- X PVbuffer[0] = AL_INPUT_RATE;
- X ALgetparams(AL_DEFAULT_DEVICE, PVbuffer, 2);
- X return PVbuffer[1];
- X}
- X
- int convert(inbuf, n, outbuf)
- X short *inbuf;
- X int n;
- X short *outbuf;
- X{
- X register short *inp = inbuf;
- X register short *inend = inbuf + n;
- X register int di = inrate/OUTRATE;
- X register int x;
- X register short *outp = outbuf;
- X
- X while (inp < inend) {
- X switch (di) {
- X case 1:
- X *outp++ = *inp++;
- X break;
- X case 2:
- X x = *inp++;
- X x += *inp++;
- X *outp++ = x >> 1;
- X break;
- X case 4:
- X x = *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X *outp++ = x >> 2;
- X break;
- X case 6:
- X x = *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X *outp++ = x / 24;
- X break;
- X }
- X }
- X
- X return outp - outbuf;
- X}
- END_OF_FILE
- if test 3541 -ne `wc -c <'recordlinear.c'`; then
- echo shar: \"'recordlinear.c'\" unpacked with wrong size!
- fi
- # end of 'recordlinear.c'
- fi
- if test -f 'recordulaw.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'recordulaw.c'\"
- else
- echo shar: Extracting \"'recordulaw.c'\" \(4711 characters\)
- sed "s/^X//" >'recordulaw.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/* Record SGI audio data and output it at 8 kHz to Sparc uLAW format,
- X converting the sampling rate and encoding on the fly.
- X This writes to stdout -- use rsh to pipe it to /dev/audio on a Sparc.
- X No Sun audio header is added.
- X
- X Caveats:
- X - since it uses an audio port, of which there can only be 4 open
- X at a time, running several copies is not a good idea;
- X see broadcast.c and radio.c for a distribution mechanism.
- X
- X To do:
- X - support the other three sampling rates
- X*/
- X
- X#include <stdio.h>
- X#include <audio.h>
- X
- int inrate;
- X
- X#define OUTRATE 8000
- X#define INBUFSIZE 48000
- X
- main(argc, argv)
- X int argc;
- X char **argv;
- X{
- X short inbuf[INBUFSIZE];
- X char outbuf[8000];
- X ALconfig c;
- X ALport p;
- X int n;
- X int insamps;
- X int sts = 0;
- X
- X checkinrate();
- X insamps = calcinsamps();
- X
- X c = ALnewconfig();
- X if (c == NULL) {
- X perror("ALnewconfig");
- X exit(1);
- X }
- X ALsetwidth(c, AL_SAMPLE_16);
- X ALsetchannels(c, AL_MONO);
- X
- X p = ALopenport(argv[0], "r", c);
- X if (p == NULL) {
- X perror("ALopenport");
- X exit(1);
- X }
- X
- X initcvt();
- X
- X for (;;) {
- X checkinrate();
- X insamps = calcinsamps();
- X ALreadsamps(p, (void *)inbuf, insamps);
- X n = convert(inbuf, insamps, outbuf);
- X if (write(1, outbuf, n) != n) {
- X perror("write error");
- X sts = 1;
- X break;
- X }
- X }
- X
- X exit(sts);
- X}
- X
- int calcinsamps()
- X{
- X int insamps = inrate/2;
- X if (insamps > INBUFSIZE)
- X insamps = INBUFSIZE;
- X return insamps;
- X}
- X
- checkinrate()
- X{
- X inrate = getinrate();
- X if ((inrate/OUTRATE)*OUTRATE != inrate) {
- X fprintf(stderr,
- X "current sampling rate (%d) is not a multiple of %d\n",
- X inrate, OUTRATE);
- X exit(1);
- X }
- X}
- X
- int getinrate()
- X{
- X long PVbuffer[2];
- X
- X PVbuffer[0] = AL_INPUT_RATE;
- X ALgetparams(AL_DEFAULT_DEVICE, PVbuffer, 2);
- X return PVbuffer[1];
- X}
- X
- X/* Convert a bufferful of data from SGI to uLAW format
- X - inrate samples/sec --> 8000 samples/sec
- X - 16 bit linear encoding --> 8 bit uLAW encoding
- X*/
- X
- extern unsigned char *cvtvec; /* Forward */
- X
- int convert(inbuf, n, outbuf)
- X short *inbuf;
- X int n;
- X unsigned char *outbuf;
- X{
- X register short *inp = inbuf;
- X register short *inend = inbuf + n;
- X register int di = inrate/OUTRATE;
- X register int x;
- X register unsigned char *outp = outbuf;
- X
- X while (inp < inend) {
- X switch (di) {
- X case 1:
- X *outp++ = cvtvec[*inp++ >> 2];
- X break;
- X case 2:
- X x = *inp++;
- X x += *inp++;
- X *outp++ = cvtvec[x >> 3];
- X break;
- X case 4:
- X x = *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X *outp++ = cvtvec[x >> 4];
- X break;
- X case 6:
- X x = *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X x += *inp++;
- X *outp++ = cvtvec[x / 24];
- X break;
- X }
- X }
- X
- X return outp - outbuf;
- X}
- X
- X
- X/* convert two's complement ch (1+13 bits) into uLAW format (8 bits) */
- X
- unsigned int cvt(ch)
- int ch;
- X{
- X int mask;
- X
- X if (ch < 0) {
- X ch = -ch;
- X mask = 0x7f;
- X } else {
- X mask = 0xff;
- X }
- X
- X if (ch < 32) {
- X ch = 0xF0 | 15 - (ch / 2);
- X } else if (ch < 96) {
- X ch = 0xE0 | 15 - (ch - 32) / 4;
- X } else if (ch < 224) {
- X ch = 0xD0 | 15 - (ch - 96) / 8;
- X } else if (ch < 480) {
- X ch = 0xC0 | 15 - (ch - 224) / 16;
- X } else if (ch < 992) {
- X ch = 0xB0 | 15 - (ch - 480) / 32;
- X } else if (ch < 2016) {
- X ch = 0xA0 | 15 - (ch - 992) / 64;
- X } else if (ch < 4064) {
- X ch = 0x90 | 15 - (ch - 2016) / 128;
- X } else if (ch < 8160) {
- X ch = 0x80 | 15 - (ch - 4064) / 256;
- X } else {
- X ch = 0x80;
- X }
- X
- X return (mask & ch);
- X}
- X
- unsigned char cvttab[1<<14];
- unsigned char *cvtvec = &cvttab[1<<13];
- X
- initcvt()
- X{
- X int i;
- X for (i = -(1<<13); i < (1<<13); i++)
- X cvtvec[i] = cvt(i);
- X}
- END_OF_FILE
- if test 4711 -ne `wc -c <'recordulaw.c'`; then
- echo shar: \"'recordulaw.c'\" unpacked with wrong size!
- fi
- # end of 'recordulaw.c'
- fi
- if test -f 'sndulaw.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sndulaw.c'\"
- else
- echo shar: Extracting \"'sndulaw.c'\" \(2972 characters\)
- sed "s/^X//" >'sndulaw.c' <<'END_OF_FILE'
- X/*
- X * Author : Reimer A. Mellin
- X * Date : 4.12.1991
- X * no copyrights
- X *
- X *
- X * ulaw: based on recordchaintest.c
- X * it writes a endless stream of Sound to stdout until terminated or
- X * interrupted.
- X * sndrecord can't be used, since it can not write to stdout :-(
- X */
- X
- X#import <stdio.h>
- X#import <signal.h>
- X#import <sound/sound.h>
- X
- X#define NUM_BUFFERS 5
- X#define BUF_SIZE 8000
- X
- static SNDSoundStruct *buffers[NUM_BUFFERS];
- static FILE *sfp;
- X
- static void record(int tag);
- X
- static int recordDone(SNDSoundStruct *s, int tag, int err)
- X/*
- X * Called when a buffer has been recorded.
- X * Appends the buffer to the soundfile.
- X */
- X{
- X if (err)
- X fprintf(stderr, "recordDone: %s\n", SNDSoundError(err));
- X if (fwrite((void *)((char *)s + s->dataLocation), 1, s->dataSize, sfp) !=
- X s->dataSize)
- X fprintf(stderr, "recordDone: could not write data to soundfile\n");
- X return 0;
- X}
- X
- static void record(int bufNum)
- X/*
- X * Initiates recording into a buffers[bufNum].
- X */
- X{
- X int err;
- X
- X
- X if (err = SNDStartRecording(buffers[bufNum], bufNum+1, 0, 0, SND_NULL_FUN,
- X recordDone))
- X fprintf(stderr, "record: %s\n", SNDSoundError(err));
- X}
- X
- static void init(int n, int size)
- X/*
- X * Allocate n sound buffers.
- X * Creates the soundfile.
- X */
- X{
- X int i, err;
- X SNDSoundStruct s;
- X
- X for (i = 0; i < n; i++)
- X if (err = SNDAlloc(&buffers[i], size, SND_FORMAT_MULAW_8,
- X SND_RATE_CODEC, 1, 4))
- X fprintf(stderr, "init: %s\n", SNDSoundError(err));
- X
- X s.magic = SND_MAGIC;
- X s.dataLocation = sizeof(SNDSoundStruct);
- X s.dataSize = 0;
- X s.dataFormat = SND_FORMAT_MULAW_8;
- X s.samplingRate = SND_RATE_CODEC;
- X s.channelCount = 1;
- X (void)strcpy( s.info, "ram");
- X if (fwrite((void *)&s, sizeof(SNDSoundStruct), 1, sfp) != 1)
- X fprintf(stderr, "init: could not write dummy header to soundfile\n");
- X}
- X
- static void cleanup(void)
- X/*
- X * Write the soundfile header.
- X */
- X{
- X SNDSoundStruct s;
- X
- X s.magic = SND_MAGIC;
- X s.dataLocation = sizeof(SNDSoundStruct);
- X s.dataSize = 0;
- X s.dataFormat = SND_FORMAT_MULAW_8;
- X s.samplingRate = SND_RATE_CODEC;
- X s.channelCount = 1;
- X (void)strcpy( s.info, "ram");
- X
- X if(!isatty(fileno(sfp))) {
- X rewind(sfp);
- X if (fwrite((void *)&s, sizeof(SNDSoundStruct), 1, sfp) != 1)
- X fprintf(stderr, "cleanup: could not write header to soundfile\n");
- X }
- X fflush(sfp);
- X exit(0);
- X}
- X
- main(int argc, char *argv[])
- X{
- X int i;
- X
- X if( argc > 1 ) {
- X fprintf(stderr, "%s: Records sound from CODEC and writes it to stdout\n",
- X argv[0]);
- X exit(1);
- X }
- X sfp = stdout;
- X (void)signal( SIGTERM, (void *)cleanup);
- X (void)signal( SIGINT, (void *)cleanup);
- X
- X /* prepare sound and start the first 5 recordings */
- X init(NUM_BUFFERS, BUF_SIZE);
- X for (i = 0; i < NUM_BUFFERS; i++) {
- X record(i);
- X }
- X for(;;){
- X /* As soon as the first is finished, restart it */
- X for (i = 0; i < NUM_BUFFERS; i++) {
- X SNDWait(i+1);
- X record(i);
- X }
- X }
- X cleanup();
- X}
- END_OF_FILE
- if test 2972 -ne `wc -c <'sndulaw.c'`; then
- echo shar: \"'sndulaw.c'\" unpacked with wrong size!
- fi
- # end of 'sndulaw.c'
- fi
- if test -f 'socklib.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'socklib.c'\"
- else
- echo shar: Extracting \"'socklib.c'\" \(3341 characters\)
- sed "s/^X//" >'socklib.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/* Socket-related subroutines shared by broadcast and radio */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <stdlib.h>
- X#include <fcntl.h>
- X#include <netdb.h>
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <netinet/in.h>
- X
- int
- opensock(sockdesc, localname, localport, remotename, remoteport, broadcast)
- X char *sockdesc;
- X char *localname;
- X int localport;
- X char *remotename;
- X int remoteport;
- X int broadcast;
- X{
- X int s;
- X struct sockaddr_in sin;
- X char desc[512];
- X
- X s = socket(AF_INET, SOCK_DGRAM, 0);
- X if (s < 0) {
- X sprintf(desc, "socket(%s)", sockdesc);
- X perror(desc);
- X exit(1);
- X }
- X memset((char *)&sin, '\0', sizeof(sin));
- X if(localname) {
- X setipaddr(localname, &sin);
- X }
- X else {
- X sin.sin_addr.s_addr = INADDR_ANY;
- X sin.sin_family = AF_INET;
- X }
- X sin.sin_port = htons(localport);
- X
- X#ifdef SO_REUSEPORT
- X if (!broadcast) {
- X int on = 1;
- X if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
- X &on, sizeof (on)) < 0) {
- X sprintf(desc,"setsockopt(%s, SO_REUSEPORT)", sockdesc);
- X perror(desc);
- X /* Don't exit -- this isn't fatal */
- X }
- X }
- X#endif
- X
- X if (bind(s, &sin, sizeof sin) < 0) {
- X sprintf(desc,"bind(%s)", sockdesc);
- X perror(desc);
- X exit(1);
- X }
- X
- X if(remotename) {
- X memset((char *)&sin, '\0', sizeof(sin));
- X setipaddr(remotename, &sin);
- X sin.sin_port = htons(remoteport);
- X
- X if (connect(s, &sin, sizeof sin) < 0) {
- X sprintf(desc, "connect(%s)", sockdesc);
- X perror(desc);
- X exit(1);
- X }
- X }
- X
- X if(broadcast) {
- X int on = 1;
- X if (setsockopt(s, SOL_SOCKET, SO_BROADCAST,
- X &on, sizeof (on)) < 0) {
- X sprintf(desc,"setsockopt(%s, SO_BROADCAST)", sockdesc);
- X perror(desc);
- X exit(1);
- X }
- X }
- X return s;
- X}
- X
- int
- setipaddr(name, addr_ret)
- X char *name;
- X struct sockaddr_in *addr_ret;
- X{
- X struct hostent *hp;
- X
- X if((hp = gethostbyname(name)) == NULL) {
- X if((addr_ret->sin_addr.s_addr = inet_addr(name)) == -1) {
- X return(-1);
- X }
- X }
- X else {
- X memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
- X }
- X addr_ret->sin_family = AF_INET;
- X return 4;
- X}
- END_OF_FILE
- if test 3341 -ne `wc -c <'socklib.c'`; then
- echo shar: \"'socklib.c'\" unpacked with wrong size!
- fi
- # end of 'socklib.c'
- fi
- if test -f 'stations.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stations.pl'\"
- else
- echo shar: Extracting \"'stations.pl'\" \(854 characters\)
- sed "s/^X//" >'stations.pl' <<'END_OF_FILE'
- X#!/usr/bin/perl
- X##
- X## Find radio stations
- X##
- X## (A small subset of the functionality of stations.py for now)
- X##
- X## Written by; Jeff Beadles jeff@onion.rain.com
- X##
- X# this emulates #! processing on machines that don't support it.
- eval "exec /usr/bin/perl -S $0 $*"
- X if $running_under_some_shell_and_not_perl;
- X
- require 'sys/socket.ph';
- X
- X($name, $aliases, $proto) = getprotobyname('udp');
- X
- X$this = pack('S n a4 x8' , &AF_INET, 54317, "\0\0\0\0");
- X
- socket(S, &AF_INET, &SOCK_DGRAM, $proto) || die "socket: $!";
- bind(S, $this) || die "bind: $!";
- X
- while (1) {
- X recv(S, $buf, 1024, 0) || die "recv: $!\n";
- X chop($buf);
- X ($t_radio,$t_s,$t_name,$t_port,$t_xmit,$t_log,$t_age) = split(/:/,$buf,7);
- X print "Bogus message '$buf'\n" if ($t_radio ne "radio");
- X print "Receiving station '$t_name' on port $t_port\n";
- X}
- END_OF_FILE
- if test 854 -ne `wc -c <'stations.pl'`; then
- echo shar: \"'stations.pl'\" unpacked with wrong size!
- fi
- chmod +x 'stations.pl'
- # end of 'stations.pl'
- fi
- if test -f 'stations.py' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stations.py'\"
- else
- echo shar: Extracting \"'stations.py'\" \(3128 characters\)
- sed "s/^X//" >'stations.py' <<'END_OF_FILE'
- X#! /usr/local/bin/python
- X
- X# /***********************************************************
- X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- X# Netherlands.
- X#
- X# All Rights Reserved
- X#
- X# Permission to use, copy, modify, and distribute this software and its
- X# documentation for any purpose and without fee is hereby granted,
- X# provided that the above copyright notice appear in all copies and that
- X# both that copyright notice and this permission notice appear in
- X# supporting documentation, and that the names of Stichting Mathematisch
- X# Centrum or CWI not be used in advertising or publicity pertaining to
- X# distribution of the software without specific, written prior permission.
- X#
- X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X#
- X# ******************************************************************/
- X
- X# Print station call packets received from broadcast programs around the net.
- X
- import time
- import string
- import os
- from stat import *
- from socket import *
- X##from SOCKET import *
- X
- INFOPORT = 54317
- BCASTCTLPORT = 54319
- X
- def main():
- X s = socket(AF_INET, SOCK_DGRAM)
- X## s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) # Python 0.9.7 or higher
- X s.allowbroadcast(1) # Python 0.9.6
- X s.bind('', INFOPORT)
- X s.sendto('radio:s', ('<broadcast>', BCASTCTLPORT))
- X while 1:
- X data, sender = s.recvfrom(100)
- X if data[:7] == 'radio:S':
- X name, prt, tr, log, age, prg = decodeinfo(data)
- X print name+':', prg,
- X if age >= 0: print '(' + formatage(age) + ')',
- X print
- X elif data[:6] == 'radio:':
- X print 'bad control packet:', `data`
- X else:
- X print 'bad packet received'
- X
- X
- def formatage(age):
- X if age < 60: return `age` + ' sec'
- X if age < 3600: return `age/60` + ' min'
- X if age < 24*3600: return `age/3600` + ' hrs'
- X return `age/(24*3600)` + ' days'
- X
- def decodeinfo(data):
- X fields = string.splitfields(data, ':')
- X name = fields[2]
- X port = eval(fields[3])
- X if fields[4:]:
- X transmitting = eval(fields[4])
- X logfile = fields[5]
- X age = eval(fields[6])
- X contents = string.joinfields(fields[7:], ':')
- X else:
- X transmitting = -1
- X programfile = '/ufs/' + name + '/CD'
- X logfile = programfile + 'log'
- X age = getage(programfile)
- X if age == None:
- X age = -1
- X contents = getcontents(programfile)
- X if contents == None:
- X contents = '???'
- X return name, port, transmitting, logfile, age, contents
- X return None
- X
- def getcontents(filename):
- X try:
- X f = open(filename, 'r')
- X except IOError:
- X return None
- X res = f.readline()
- X f.close()
- X return string.strip(res)
- X
- def getage(filename):
- X try:
- X st = os.stat(filename)
- X except os.error:
- X return None
- X return time.time() - st[ST_MTIME]
- X
- X
- try:
- X main()
- except KeyboardInterrupt:
- X print
- X print '[Interrupt]'
- END_OF_FILE
- if test 3128 -ne `wc -c <'stations.py'`; then
- echo shar: \"'stations.py'\" unpacked with wrong size!
- fi
- # end of 'stations.py'
- fi
- if test -f 'ttytuner.py' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ttytuner.py'\"
- else
- echo shar: Extracting \"'ttytuner.py'\" \(7530 characters\)
- sed "s/^X//" >'ttytuner.py' <<'END_OF_FILE'
- X#!/usr/local/bin/python
- X
- X# /***********************************************************
- X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- X# Netherlands.
- X#
- X# All Rights Reserved
- X#
- X# Permission to use, copy, modify, and distribute this software and its
- X# documentation for any purpose and without fee is hereby granted,
- X# provided that the above copyright notice appear in all copies and that
- X# both that copyright notice and this permission notice appear in
- X# supporting documentation, and that the names of Stichting Mathematisch
- X# Centrum or CWI not be used in advertising or publicity pertaining to
- X# distribution of the software without specific, written prior permission.
- X#
- X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X#
- X# ******************************************************************/
- X
- X# A tuner to control radio programs, by Jack Jansen.
- X
- import sys
- import os
- import time
- import socket
- import time
- import string
- import getopt
- from stat import ST_MTIME
- X
- X
- RADIOCTLPORT=54320
- TRANSMITTERCTLPORT=54319
- CTLWS=socket.gethostname()
- X
- X# The list of networks to broadcast on, when looking for radio
- X# stations. This should somehow be gotten differently.
- X#
- MCASTLIST = ['192.16.184.0', '192.16.191.0', '192.16.201.255']
- X# MCASTLIST = ['192.16.201.255']
- X
- class struct(): pass
- info = struct()
- X
- X#
- X# sendsock - send a message (and get optional reply)
- X#
- def sendsock(host, port, msg, needrepl):
- X try:
- X host = socket.gethostbyname(host)
- X s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- X s.sendto(msg, (host,port))
- X if needrepl:
- X # Loop for max. 2.5 seconds waiting for a reply
- X i = 0
- X while i < 5 and not s.avail():
- X time.millisleep(500)
- X i = i + 1
- X if not s.avail():
- X print 'Radio program not responding'
- X return ''
- X return s.recv(500)
- X except socket.error:
- X print 'Incorrect radio settings'
- X if needrepl:
- X return ''
- X else:
- X return
- X#
- X# sendmulti - send a multicast message (and get replies)
- X#
- def sendmulti(mcastlist, port, msg):
- X rv = []
- X try:
- X s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- X s.allowbroadcast(1)
- X for host in mcastlist:
- X s.sendto(msg, (host,port))
- X # Loop for max. 2.5 seconds waiting for a reply
- X i = 0
- X while i < 25:
- X time.millisleep(100)
- X i = i + 1
- X if s.avail():
- X rv.append(s.recv(500))
- X except socket.error:
- X print 'Incorrect mcast settings'
- X return rv
- X#
- X# getstationinfo - Return playlist, current and playing time (in minutes).
- X# Returns a triple (playlist-filename, current record, playing time)
- X#
- def getstationinfo(info):
- X name = info[0]
- X if len(info) > 3:
- X playlist = info[3]
- X else:
- X playlist = '/ufs/' + name + '/CDlog'
- X if len(info) > 5:
- X since = eval(info[4])
- X cur = string.joinfields(info[5:], ':')
- X else:
- X curfn = '/ufs/' + name + '/CD'
- X try:
- X curf = open(curfn,'r')
- X cur = curf.readline()
- X curf.close()
- X except IOError:
- X cur = '???'
- X if cur[-1:] == '\n':
- X cur = cur[:-1]
- X try:
- X sb = os.stat(curfn)
- X since = time.time() - sb[ST_MTIME]
- X except os.error:
- X since = -1
- X if since >= 0: since = since / 60 # Convert to minutes
- X if since < 0:
- X str = '??'
- X elif since < 60:
- X str = `since` + ' mins'
- X else:
- X since = since / 60
- X if since < 24:
- X str = `since` + ' hrs'
- X else:
- X str = `since / 24` + ' days'
- X return playlist, cur, str
- X
- X#
- X# updateinfo - Update one of the views with info on station 'name'
- X#
- def printinfo(info):
- X name = info[0]
- X print 'Station '+ name + ':'
- X print '\tPort ' + `info[1]`
- X if name == '' or name[:3] == '???':
- X print '\tNo information on station'
- X else:
- X try:
- X p, c, t = getstationinfo(info)
- X except IOError:
- X return
- X if c <> '' and c <> '???':
- X print '\tCurrently playing: ' + c
- X if t <> '??':
- X print '\tSince: ' + t
- X if p <> '':
- X print '\tPlaylist in file: ' + p
- X
- X#
- X# getstations - Return an array of (stationname, stationport)
- X# listing all available stations.
- X#
- def getstations():
- X stations = []
- X raw = sendmulti(MCASTLIST, TRANSMITTERCTLPORT, 'radio:s')
- X for i in raw:
- X if i[:7] == 'radio:S':
- X fields = string.splitfields(i,':')[2:]
- X fields[1] = string.atoi(fields[1])
- X stations.append(fields)
- X else:
- X print 'Funny reply from transmitter:', i[:7]
- X return stations
- X
- X#
- X# getcurstation - Return (name,port) for station to which radio
- X# on workstation ws is currently tuned to.
- X#
- def getcurstation(stationlist, ws, port):
- X rv = sendsock(ws, port, 'radio:i', 1)
- X if rv == '':
- X return ('',0)
- X if rv[0:8] <> 'radio:I:':
- X print 'Illegal reply from radio:',rv
- X return ('',0)
- X # Remove optional pause field
- X rv = rv[8:]
- X rv = string.splitfields(rv,':')
- X if len(rv) == 1: # Old: port
- X tport = string.atoi(rv[0])
- X playing = 1
- X elif len(rv) == 2: # newer: playing, port
- X tport = string.atoi(rv[1])
- X playing = string.atoi(rv[0])
- X elif len(rv) == 3: # Still newer: playing, port, version
- X tport = string.atoi(rv[1])
- X playing = string.atoi(rv[0])
- X else: # Too new
- X print 'Unknown reply to info: ', rv
- X for i in stationlist:
- X if i[1] == tport:
- X return (i, playing)
- X return (('???(port '+`tport`+')' ,tport), playing)
- X
- def main():
- X radio_port = RADIOCTLPORT
- X radio_ws = CTLWS
- X try:
- X optlist, args = getopt.getopt(sys.argv[1:], 'w:p:lLcPCT')
- X mode = ''
- X for o, a in optlist:
- X if o == '-w':
- X radio_ws = a
- X elif o == '-p':
- X radio_port = string.atoi(a)
- X elif mode == '':
- X mode = o[1]
- X else:
- X raise getopt.error
- X if len(args) + len(mode) <> 1:
- X raise getopt.error
- X except getopt.error:
- X print 'Usage: '+sys.argv[0]+' [options] command'
- X print 'Options:'
- X print '\t-w ws\tControl radio on workstation ws'
- X print '\t-p port\tControl radio on port port'
- X print 'Command:'
- X print '\t-l\tList names of active stations'
- X print '\t-L\tList names and info of active stations'
- X print '\t-c\tList info on current station'
- X print '\t-P\tTemporarily suspend radio, freeing port'
- X print '\t-C\tContinue radio'
- X print '\t-T\tToggle suspend/continue'
- X print '\tstation\tTune to new station'
- X sys.exit(1)
- X
- X #
- X # First, do pause/continue command.
- X #
- X if mode == 'P':
- X sendsock(radio_ws, radio_port, 'radio:0', 0)
- X sys.exit(0)
- X if mode == 'C':
- X sendsock(radio_ws, radio_port, 'radio:1', 0)
- X sys.exit(0)
- X if mode == 'T':
- X cn, playing = getcurstation([], radio_ws, radio_port)
- X sendsock(radio_ws, radio_port, 'radio:'+`not playing`, 0)
- X sys.exit(0)
- X #
- X # And list of new stations
- X #
- X stations = getstations()
- X #
- X # Set info for current station
- X #
- X if mode == '' or mode == 'c':
- X cn, playing = getcurstation(stations,radio_ws, radio_port)
- X if mode == 'l':
- X for i in stations:
- X print i[0]
- X elif mode == 'L':
- X for i in stations:
- X printinfo(i)
- X elif mode == 'c':
- X printinfo(cn)
- X else:
- X for i in range(len(stations)):
- X if stations[i][0] == args[0]:
- X sendsock(radio_ws, radio_port, \
- X 'radio:t:' + `stations[i][1]`, 0)
- X sys.exit(0)
- X print 'No such station: ', args[0]
- X
- X
- X
- main()
- X
- X# Local variables:
- X# py-indent-offset: 4
- X# end:
- END_OF_FILE
- if test 7530 -ne `wc -c <'ttytuner.py'`; then
- echo shar: \"'ttytuner.py'\" unpacked with wrong size!
- fi
- chmod +x 'ttytuner.py'
- # end of 'ttytuner.py'
- fi
- if test -f 'ulawadpcm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ulawadpcm.c'\"
- else
- echo shar: Extracting \"'ulawadpcm.c'\" \(7209 characters\)
- sed "s/^X//" >'ulawadpcm.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- 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, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/*
- X** Intel/DVI ADPCM coder/decoder.
- X**
- X** The algorithm for this coder was taken from the IMA Compatability Project
- X** proceedings, Vol 2, Number 2; May 1992.
- X**
- X** Version 1.1, 16-Dec-92.
- X**
- X** Change log:
- X** - Fixed a stupid bug, where the delta was computed as
- X** stepsize*code/4 in stead of stepsize*(code+0.5)/4. The old behavior can
- X** still be gotten by defining STUPID_V1_BUG.
- X*/
- X
- X#include "adpcm.h"
- X#include "libst.h"
- X
- X#ifndef __STDC__
- X#define signed
- X#endif
- X
- X/* Intel ADPCM step variation table */
- static int indexTable[16] = {
- X -1, -1, -1, -1, 2, 4, 6, 8,
- X -1, -1, -1, -1, 2, 4, 6, 8,
- X};
- X
- static int stepsizeTable[89] = {
- X 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- X 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- X 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- X 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- X 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- X 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- X 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- X 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- X 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
- X};
- X
- void
- ulaw_adpcm_coder(indata, outdata, len, state)
- X char indata[];
- X char outdata[];
- X int len;
- X struct adpcm_state *state;
- X{
- X unsigned char *inp; /* Input buffer pointer */
- X signed char *outp; /* output buffer pointer */
- X /* XXX why must outp be signed? */
- X int val; /* Current input sample value */
- X int sign; /* Current adpcm sign bit */
- X int delta; /* Current adpcm output value */
- X int step; /* Stepsize */
- X int valprev; /* virtual previous output value */
- X int vpdiff; /* Current change to valprev */
- X int index; /* Current step change index */
- X int outputbuffer; /* place to keep previous 4-bit value */
- X int bufferstep; /* toggle between outputbuffer/output */
- X
- X outp = (signed char *)outdata;
- X inp = (unsigned char *)indata;
- X
- X if (state) {
- X valprev = state->valprev;
- X index = state->index;
- X }
- X else {
- X valprev = 0;
- X index = 0;
- X }
- X step = stepsizeTable[index];
- X
- X bufferstep = 1;
- X
- X for ( ; len > 0 ; len-- ) {
- X val = st_ulaw_to_linear(*inp++);
- X
- X /* Step 1 - compute difference with previous value */
- X delta = val - valprev;
- X sign = (delta < 0) ? 8 : 0;
- X if ( sign ) delta = (-delta);
- X
- X /* Step 2 - Divide and clamp */
- X#ifdef NODIVMUL
- X {
- X int tmp = 0;
- X#ifdef STUPID_V1_BUG
- X vpdiff = 0;
- X#else
- X vpdiff = (step >> 3);
- X#endif /* STUPID_V1_BUG */
- X if ( delta > step ) {
- X tmp = 4;
- X delta -= step;
- X vpdiff += step;
- X }
- X step >>= 1;
- X if ( delta > step ) {
- X tmp |= 2;
- X delta -= step;
- X vpdiff += step;
- X }
- X step >>= 1;
- X if ( delta > step ) {
- X tmp |= 1;
- X vpdiff += step;
- X }
- X delta = tmp;
- X }
- X#else
- X delta = (delta<<2) / step;
- X if ( delta > 7 ) delta = 7;
- X
- X#ifdef STUPID_V1_BUG
- X vpdiff = (delta*step) >> 2;
- X#else
- X vpdiff = ((delta*step) >> 2) + (step >> 3);
- X#endif /* STUPID_V1_BUG */
- X#endif /* NODIVMUL */
- X
- X /* Step 3 - Update previous value */
- X if ( sign )
- X valprev -= vpdiff;
- X else
- X valprev += vpdiff;
- X
- X /* Step 4 - Clamp previous value to 16 bits */
- X if ( valprev > 32767 )
- X valprev = 32767;
- X else if ( valprev < -32768 )
- X valprev = -32768;
- X
- X /* Step 5 - Assemble value, update index and step values */
- X delta |= sign;
- X
- X index += indexTable[delta];
- X if ( index < 0 ) index = 0;
- X if ( index > 88 ) index = 88;
- X step = stepsizeTable[index];
- X
- X /* Step 6 - Output value */
- X if ( bufferstep ) {
- X outputbuffer = (delta << 4) & 0xf0;
- X } else {
- X *outp++ = (delta & 0x0f) | outputbuffer;
- X }
- X bufferstep = !bufferstep;
- X }
- X
- X /* Output last step, if needed */
- X if ( !bufferstep )
- X *outp++ = outputbuffer;
- X
- X if (state) {
- X state->valprev = valprev;
- X state->index = index;
- X }
- X}
- X
- void
- adpcm_ulaw_decoder(indata, outdata, len, state)
- X char indata[];
- X char outdata[];
- X int len;
- X struct adpcm_state *state;
- X{
- X signed char *inp; /* Input buffer pointer */
- X char *outp; /* output buffer pointer */
- X int sign; /* Current adpcm sign bit */
- X int delta; /* Current adpcm output value */
- X int step; /* Stepsize */
- X int valprev; /* virtual previous output value */
- X int vpdiff; /* Current change to valprev */
- X int index; /* Current step change index */
- X int inputbuffer; /* place to keep next 4-bit value */
- X int bufferstep; /* toggle between inputbuffer/input */
- X
- X outp = outdata;
- X inp = (signed char *)indata;
- X
- X if (state) {
- X valprev = state->valprev;
- X index = state->index;
- X }
- X else {
- X valprev = 0;
- X index = 0;
- X }
- X step = stepsizeTable[index];
- X
- X bufferstep = 0;
- X
- X for ( ; len > 0 ; len-- ) {
- X
- X /* Step 1 - get the delta value and compute next index */
- X if ( bufferstep ) {
- X delta = inputbuffer & 0xf;
- X } else {
- X inputbuffer = *inp++;
- X delta = (inputbuffer >> 4) & 0xf;
- X }
- X bufferstep = !bufferstep;
- X
- X /* Step 2 - Find new index value (for later) */
- X index += indexTable[delta];
- X if ( index < 0 ) index = 0;
- X if ( index > 88 ) index = 88;
- X
- X /* Step 3 - Separate sign and magnitude */
- X sign = delta & 8;
- X delta = delta & 7;
- X
- X /* Step 4 - update output value */
- X#ifdef NODIVMUL
- X#ifdef STUPID_V1_BUG
- X vpdiff = 0;
- X#else
- X vpdiff = step >> 1;
- X#endif /* STUPID_V1_BUG */
- X if ( delta & 4 ) vpdiff += (step << 2);
- X if ( delta & 2 ) vpdiff += (step << 1);
- X if ( delta & 1 ) vpdiff += step;
- X vpdiff >>= 2;
- X#else
- X#ifdef STUPID_V1_BUG
- X vpdiff = ((delta*step) >> 2);
- X#else
- X vpdiff = ((delta*step) >> 2) + (step >> 3);
- X#endif /* STUPID_V1_BUG */
- X#endif /* ! NODIVMUL */
- X if ( sign )
- X valprev -= vpdiff;
- X else
- X valprev += vpdiff;
- X
- X /* Step 5 - clamp output value */
- X if ( valprev > 32767 )
- X valprev = 32767;
- X else if ( valprev < -32768 )
- X valprev = -32768;
- X
- X /* Step 6 - Update step value */
- X step = stepsizeTable[index];
- X
- X /* Step 7 - Output value */
- X *outp++ = st_linear_to_ulaw(valprev);
- X }
- X
- X if (state) {
- X state->valprev = valprev;
- X state->index = index;
- X }
- X}
- END_OF_FILE
- if test 7209 -ne `wc -c <'ulawadpcm.c'`; then
- echo shar: \"'ulawadpcm.c'\" unpacked with wrong size!
- fi
- # end of 'ulawadpcm.c'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-