home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / radio202 / part01 < prev    next >
Encoding:
Text File  |  1993-04-14  |  99.8 KB  |  3,343 lines

  1. Newsgroups: comp.sources.unix
  2. From: guido.van.rossum@cwi.nl (Guido van Rossum)
  3. Subject: v26i162: radio - UDP broadcast/receive utilities for audio data, V2.0.2, Part01/02
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: guido.van.rossum@cwi.nl (Guido van Rossum)
  8. Posting-Number: Volume 26, Issue 162
  9. Archive-Name: radio2.0.2/part01
  10.  
  11. This is Radio version 2.0, patchlevel 2 (a.k.a. 2.0.2).
  12.  
  13. If you have a local area network full of workstations with audio
  14. capabilities and at least one FM/AM radio or other audio source, you can
  15. broadcast the audio over the network, and let other users listen to it.
  16.  
  17. This software works for Sun Sparcs running SunOS 4.0 or 4.1, for SGI Indigo
  18. or Personal IRIS 4D/30 or 4D/35 workstations running SGI IRIX 4.0 or 3.3.2,
  19. and for NeXT workstations (running version 2.1).  At CWI, versions of it
  20. have been in continuous use on a mix of Sun and SGI system types for almost
  21. two years; version 1.0 (patchlevel 4) was last tested on a NeXT.  (I've
  22. heard that the program doesn't work on NeXT 3.1; if you fix it please send
  23. me the changes!)
  24.  
  25. Man pages for "radio" and "broadcast" are provided.
  26.  
  27. The implementation continuously transmits UDP broadcast packets of 1400
  28. bytes each (i.e. less than six per second), which contain the data in U-LAW
  29. format (8000 samples/second, 1 byte/sample, logarithmically encoded).  On a
  30. typical ethernet, this uses about 1 percent of the net available bandwith.
  31. Some loss of UDP packets is tolerated by the receiving program (this is
  32. heard as short interruptions of the sound).  Every now and then, a short
  33. "station call" packet is transmitted as well, for the benefit of advanced
  34. listening programs.
  35.  
  36. It is possible to use multiple transmission stations (each identified by a
  37. different UDP port), and to transmit to multiple connected subnets
  38. simultaneously (as long as the gateways let UDP broadcast packets through).
  39. For reasons you don't want to know, you can only have one broadcasting and
  40. one radio process per host, except on the SGI there may be multiple radio
  41. processes.
  42.  
  43. If you have Motif, you may be interested in the "tuner" program X(version
  44. 1.3) by Jack Jansen.  This is a window-based interface that shows the
  45. different broadcasting stations at your site and lets you tune your radio
  46. process to the station of your choice.  It will be posted to comp.sources.x
  47. around the same time as radio 2.0; you can also ftp it from site ftp.cwi.nl
  48. [192.16.184.180], file /pub/tuner1.3.tar.Z.
  49.  
  50. If you missed a part of the posting of radio, you can ftp the whole
  51. source from ftp.cwi.nl [192.16.184.180], file /pub/radio2.0.tar.Z.
  52.  
  53.     Guido van Rossum
  54.     CWI, dept. CST
  55.     Kruislaan 413
  56.     X1098 SJ  Amsterdam
  57.     The Netherlands
  58.  
  59.     E-mail (Internet)  :  Guido.van.Rossum@cwi.nl (guido@cwi.nl)
  60.  
  61. The "libst" U-LAW conversion library is written and copyrighted by Jef
  62. Poskanzer.
  63.  
  64. #! /bin/sh
  65. # This is a shell archive.  Remove anything before this line, then unpack
  66. # it by saving it into a file and typing "sh file".  To overwrite existing
  67. # files, type "sh file -c".  You can also feed this as standard input via
  68. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  69. # will see the following message at the end:
  70. #        "End of archive 1 (of 2)."
  71. # Contents:  MANIFEST Makefile README adpcm.c adpcm.h broadcast.man
  72. #   libst.c libst.h nielsen.py patchlevel.h playulaw.c radio.h
  73. #   radio.man recordlinear.c recordulaw.c sndulaw.c socklib.c
  74. #   stations.pl stations.py ttytuner.py ulawadpcm.c
  75. # Wrapped by vixie@gw.home.vix.com on Thu Apr 15 18:45:43 1993
  76. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  77. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  78.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  79. else
  80. echo shar: Extracting \"'MANIFEST'\" \(840 characters\)
  81. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  82. X   File Name        Archive #    Description
  83. X-----------------------------------------------------------
  84. X MANIFEST                   1    
  85. X Makefile                   1    
  86. X README                     1    
  87. X adpcm.c                    1    
  88. X adpcm.h                    1    
  89. X broadcast.c                2    
  90. X broadcast.man              1    
  91. X checkradio.py              2    
  92. X libst.c                    1    
  93. X libst.h                    1    
  94. X nielsen.py                 1    
  95. X patchlevel.h               1    
  96. X playulaw.c                 1    
  97. X radio.c                    2    
  98. X radio.h                    1    
  99. X radio.man                  1    
  100. X recordlinear.c             1    
  101. X recordulaw.c               1    
  102. X sndulaw.c                  1    
  103. X socklib.c                  1    
  104. X stations.pl                1    
  105. X stations.py                1    
  106. X ttytuner.py                1    
  107. X ulawadpcm.c                1    
  108. END_OF_FILE
  109. if test 840 -ne `wc -c <'MANIFEST'`; then
  110.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  111. fi
  112. # end of 'MANIFEST'
  113. fi
  114. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  115.   echo shar: Will not clobber existing file \"'Makefile'\"
  116. else
  117. echo shar: Extracting \"'Makefile'\" \(2817 characters\)
  118. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  119. X# /***********************************************************
  120. X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  121. X# Netherlands.
  122. X# 
  123. X#                         All Rights Reserved
  124. X# 
  125. X# Permission to use, copy, modify, and distribute this software and its 
  126. X# documentation for any purpose and without fee is hereby granted, 
  127. X# provided that the above copyright notice appear in all copies and that
  128. X# both that copyright notice and this permission notice appear in 
  129. X# supporting documentation, and that the names of Stichting Mathematisch
  130. X# Centrum or CWI not be used in advertising or publicity pertaining to
  131. X# distribution of the software without specific, written prior permission.
  132. X# 
  133. X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  134. X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  135. X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  136. X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  137. X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  138. X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  139. X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  140. X# 
  141. X# ******************************************************************/
  142. X
  143. X
  144. default:
  145. X        @echo 'You must use "make sun4.0", "make sun4.1",'
  146. X        @echo '"make next" or "make sgi"'
  147. X        exit 1
  148. X
  149. all:        radio broadcast
  150. X
  151. X# Platform-specific entries
  152. X
  153. sun4.0:        # For SunOS 4.x
  154. X        make all LIBS=-lX11
  155. X
  156. sun4.1:        # For SunOS 4.1 with audio library (/usr/demo/SOUND)
  157. X        make all LIBS='-lX11 /usr/demo/SOUND/libaudio.a' \
  158. X            CFLAGS='-DREMHDR -I/usr/demo/SOUND'
  159. X
  160. sun4.1.2:    # For SunOS 4.1 with multicast & audio library (/usr/demo/SOUND)
  161. X        make all LIBS='-lX11 /usr/demo/SOUND/libaudio.a' \
  162. X            CFLAGS='-DHAVE_MCAST -DREMHDR -I/usr/demo/SOUND -DDEFMCAST=\"radio.multicast\"'
  163. X
  164. sgi:        # For SGI IRIX 4.0
  165. X        make all recordulaw recordlinear playulaw LIBS='-lX11 -laudio'
  166. X
  167. next:        # NeXT 2.1
  168. X        make all sndulaw
  169. X
  170. X# Common programs:
  171. X
  172. ROBJ=         radio.o socklib.o ulawadpcm.o adpcm.o libst.o
  173. BOBJ=        broadcast.o socklib.o adpcm.o ulawadpcm.o libst.o
  174. X
  175. radio:        $(ROBJ)
  176. X        $(CC) $(ROBJ) $(LIBS) -o radio
  177. X
  178. broadcast:    $(BOBJ)
  179. X        $(CC) $(BOBJ) $(LIBS) -o broadcast
  180. X
  181. X# NeXT-only programs:
  182. X
  183. sndulaw:    sndulaw.o
  184. X        $(CC) sndulaw.o -o sndulaw
  185. X
  186. X# SGI-only programs:
  187. X
  188. recordulaw:    recordulaw.o libst.o
  189. X        $(CC) recordulaw.o -laudio -o recordulaw
  190. X
  191. recordlinear:    recordlinear.o
  192. X        $(CC) recordlinear.o -laudio -o recordlinear
  193. X
  194. playulaw:    playulaw.o
  195. X        $(CC) playulaw.o -laudio -o playulaw
  196. X
  197. X# Service entries:
  198. X
  199. clean:
  200. X        -rm -f core *.o *~ @* '#'* ,* *.pyc *.BAK Part??
  201. X
  202. clobber:    clean
  203. X        -rm -f radio broadcast recordulaw recordlinear playulaw sndulaw
  204. X
  205. X# Dependencies:
  206. X
  207. broadcast.o:    radio.h adpcm.h
  208. radio.o:    radio.h adpcm.h libst.h
  209. ulawadpcm.o:    adpcm.h libst.h
  210. playulaw.o:    libst.h
  211. END_OF_FILE
  212. if test 2817 -ne `wc -c <'Makefile'`; then
  213.     echo shar: \"'Makefile'\" unpacked with wrong size!
  214. fi
  215. # end of 'Makefile'
  216. fi
  217. if test -f 'README' -a "${1}" != "-c" ; then 
  218.   echo shar: Will not clobber existing file \"'README'\"
  219. else
  220. echo shar: Extracting \"'README'\" \(15880 characters\)
  221. sed "s/^X//" >'README' <<'END_OF_FILE'
  222. Welcome to the wonderful world of Local Area Network radio!
  223. X===========================================================
  224. X
  225. This is Radio version 2.0, patchlevel 2 (a.k.a. 2.0.2).
  226. X
  227. If you have a local area network full of workstations with audio
  228. capabilities and at least one FM/AM radio or other audio source, you
  229. can broadcast the audio over the network, and let other users listen
  230. to it.
  231. X
  232. This software works for Sun Sparcs running SunOS 4.0 or 4.1, for SGI
  233. Indigo or Personal IRIS 4D/30 or 4D/35 workstations running SGI IRIX
  234. X4.0 or 3.3.2, and for NeXT workstations (running version 2.1).  At
  235. CWI, versions of it have been in continuous use on a mix of Sun and
  236. SGI system types for almost two years; version 1.0 (patchlevel 4) was
  237. last tested on a NeXT.  (I've heard that the program doesn't work on
  238. NeXT 3.1; if you fix it please send me the changes!)
  239. X
  240. Man pages for "radio" and "broadcast" are provided.
  241. X
  242. The implementation continuously transmits UDP broadcast packets of
  243. X1400 bytes each (i.e. less than six per second), which contain the
  244. data in U-LAW format (8000 samples/second, 1 byte/sample,
  245. logarithmically encoded).  On a typical ethernet, this uses about 1
  246. percent of the net available bandwith.  Some loss of UDP packets is
  247. tolerated by the receiving program (this is heard as short
  248. interruptions of the sound).  Every now and then, a short "station
  249. call" packet is transmitted as well, for the benefit of advanced
  250. listening programs.
  251. X
  252. It is possible to use multiple transmission stations (each identified
  253. by a different UDP port), and to transmit to multiple connected
  254. subnets simultaneously (as long as the gateways let UDP broadcast
  255. packets through).  For reasons you don't want to know, you can only
  256. have one broadcasting and one radio process per host, except on
  257. the SGI there may be multiple radio processes.
  258. X
  259. If you have Motif, you may be interested in the "tuner" program
  260. X(version 1.3) by Jack Jansen.  This is a window-based interface that
  261. shows the different broadcasting stations at your site and lets you
  262. tune your radio process to the station of your choice.  It will be
  263. posted to comp.sources.x around the same time as radio 2.0; you can
  264. also ftp it from site ftp.cwi.nl [192.16.184.180], file
  265. X/pub/tuner1.3.tar.Z.
  266. X
  267. If you missed a part of the posting of radio, you can ftp the whole
  268. source from ftp.cwi.nl [192.16.184.180], file /pub/radio2.0.tar.Z.
  269. X
  270. This software is copyrighted.  See the notice at the end of this file.
  271. X
  272. X
  273. Changes in 2.0 patchlevel 2
  274. X---------------------------
  275. X
  276. Broadcast can now also read 16-bit linear samples from standard input,
  277. as this is more appropriate for ADPCM encoding (see below).  Use the
  278. X-l option.  There is a program, recordlinear, which outputs such
  279. samples, for the SGI only.
  280. X
  281. On the SGI, radio's cleanup handler (invoked when it receives a TERM
  282. or INTR signal) resets the output volume only if it was set with the
  283. X-v option.  It resets nothing at all if the program was currently
  284. paused by a tuner.
  285. X
  286. There is now a default multicast address, from the unofficial range.
  287. X(This only has meaning for SGI users and for users of a hacked SunOS
  288. version which supports multicast.)
  289. X
  290. Data packets now have a 2-byte header, which is compatible with IVS,
  291. INRIA's video and audio conferencing system, and allows us to support
  292. different encoding schemes.  (The control packet format is unchanged,
  293. compatibility with IVS is not a point here.)  Currently supported
  294. encodings are:
  295. X
  296. X- PCM_64 (pulse-code modulation; in fact, plain u-law as before);
  297. X
  298. X- ADPCM_32 (Adaptive Delta PCM, which takes only 32 kbit/sec with only
  299. X  a slight loss in quality);
  300. X
  301. X- ADPCM_32_W_STATE, which is the same as ADPCM_32 but adds three bytes
  302. X  of state for the encoder to reduce noise (this format is not
  303. X  understood by IVS).
  304. X
  305. The default encoding used by broadcast is PCM_64; use the "-a" option
  306. to use ADPCM_32_W_STATE, or "-A" for ADPCM_32.  The radio program
  307. recognizes the encoding from the data packet header and so it does not
  308. need an option to select the encoding.
  309. X
  310. Changes by Alexander Dupuy <dupuy@tiemann.cs.columbia.edu> (thank you
  311. Alexander!):
  312. X
  313. Makefile: added a sunos4.1.2 target for our hacked version of 4.1.2 with
  314. X      multicasts (a better name would be sun4.1-multi, since multicasting
  315. X      is not standard in 4.1.2 (maybe in Solaris 2.0?).
  316. X
  317. broadcast.c: add a -m (multicast ttl) option, which sets the multicast ttl to
  318. X         control the range over which multicast packets are forwarded.
  319. X         this is necessary if you want multi-subnet multicasts.
  320. X
  321. broadcast.c: use $HOME/.CD and $HOME/.CDlog as default playfiles - this is a
  322. X         bit more portable, as most sites will try to make sure that
  323. X         users' home directories are accessible via the same path name on
  324. X         all machines.  It still fails (for .CDlog) when that is not true.
  325. X       
  326. broadcast.c: if compiled with DEFMCAST defined as a valid multicast address
  327. radio.c:     and HAVE_MCAST defined, broadcast and radio programs will default
  328. X         to the multicast address DEFMCAST instead of broadcast.
  329. X
  330. broadcast.c: increase the maximum size of control packets to 512 bytes, to
  331. radio.c:     support longer song titles (including artist and track title)
  332. X         which WorkMan typically generates.  Note that radio is also
  333. X         changed to use a larger control packet size, since it uses the
  334. X         length of incoming packets to determine whether they are control
  335. X         or data  (this is arguably a bug).
  336. X
  337. radio.c: attempt hostname lookup on -m (multicast) address argument, since it
  338. X     is possible to put multicast addresses in /etc/hosts, NIS, and even,
  339. X     with a bit of work, DNS.
  340. X
  341. broadcast.man: updated to reflect user-visible changes to the broadcast and
  342. radio.man:     radio programs.
  343. X
  344. X
  345. Changes in 2.0 patchlevel 1
  346. X---------------------------
  347. X
  348. On the sun and sgi, radio tries to open a connection to the X server
  349. X(specified by the $DISPLAY environment variable) and every now and
  350. then makes a small request to exercise the connection.  This ensures
  351. that if the user logs out, radio will quit.  If no connection to the X
  352. server can be made, these checks are not made and a warning is printed
  353. that reminds the user to kill radio when logging out.
  354. X
  355. The usage message is more informative.
  356. X
  357. The new option '-t' (tee) sends output to both stdout and the audio
  358. device.  Thanks to Scott Hazen Mueller for suggesting this.
  359. X
  360. The experimental option '-m mcastgrp' (for SGI only) specifies a
  361. multicast group.  By multicasting instead of broadcasting, you can
  362. reduce the load on hosts that aren't listening (see the man page).
  363. X
  364. X
  365. Changes since version 1.0 patchlevel 4
  366. X--------------------------------------
  367. X
  368. X(Skip to the next section if you aren't already using version 1.0 of
  369. radio.)
  370. X
  371. The source structure has been changed -- all files are in one
  372. directory now.
  373. X
  374. More Python programs have been provided, and the existing ones have
  375. been improved.  (Translations to C will be accepted and may end up in
  376. a future distribution -- here's your chance to gain world popularity!)
  377. X
  378. Building for the Sun now requires an explicit choice between sun4.0
  379. and sun4.1 -- "make sun" no longer works.
  380. X
  381. The radio program can now be "paused" by a separate tuner program.
  382. This means you don't have to kill the radio process if you want a few
  383. minutes of silence.
  384. X
  385. The broadcast program now broadcasts "station call" messages to a
  386. fixed port twice a minute, as a service to more sophisticated tuner
  387. programs.  The Python program "stations.py" can be used to display
  388. these station calls (in a primitive manner).
  389. X
  390. The broadcast program now implements silence suppression: if the input
  391. is silent longer than 20 seconds it stops transmitting packets,
  392. keeping network overhead low.  (You may have to tweak the level -- our
  393. typical "silent" input is rather noisy, so we set the livel rather
  394. high.)
  395. X
  396. Many minor changes and bugfixes.
  397. X
  398. X
  399. Building and installing
  400. X-----------------------
  401. X
  402. XFor SunOS 4.1 or higher (assuming the audio library is in
  403. X/usr/demo/SOUND), type "make sun4.1".  For SGI IRIX, type "make sgi".
  404. XFor the NeXT, type "make next".  This should produce binaries for
  405. X"radio" and "broadcast".  For the SGI it also produces binaries
  406. X"recordulaw" and "playulaw"; for the NeXT, it also builds "sndulaw".
  407. Read the Makefile for details -- it's pretty trivial.
  408. X
  409. X(For SunOS 4.0, you may try "make sun4.0" instead.  This does not make
  410. the assumption that the audio library is in /usr/demo/SOUND.  Edit the
  411. Makefile if necessary to accomodate other locations.)
  412. X
  413. XFor SGI IRIX, the Makefile builds the "recordulaw" and "playulaw"
  414. programs.  "recordulaw" uses the IRIX audio library to sample the
  415. audio input and convert it to U-LAW format.  "playulaw" does the
  416. reverse (it is not actually used but provided as a convenience).  The
  417. audio library is available on IRIS 4.0 and on IRIS 3.3.2 or higher.
  418. X
  419. Install the "radio" program on a convenient public place (where
  420. potential listeners can find it, e.g., /usr/local/bin); install
  421. X"broadcast" on a convenient place for yourself (assuming you're the
  422. one doing transmissions).  The "recordulaw" or "sndulaw" programs, if
  423. needed, should be installed together with "broadcast".  On an SGI
  424. system you may install "playulaw" if you like.
  425. X
  426. X
  427. Usage -- transmissions
  428. X----------------------
  429. X
  430. X(See the man page for broadcast for more details.)
  431. X
  432. To start transmissions on Sun Sparcs, run this command (probably in
  433. the background, once you've debugged your audio setup):
  434. X
  435. X    broadcast -p port </dev/audio
  436. X
  437. You must connect a mono audio source to the machine using a standard
  438. cable provided by Sun.  Control the input gain with [x_]gaintool
  439. X(e.g., /usr/demo/SOUND/x_gaintool).
  440. X
  441. X
  442. This command start transmissions on SGI IRIX:
  443. X
  444. X    recordulaw | broadcast -p port
  445. X
  446. Connect a stereo audio source to the machine using a standard walkman
  447. jack.  If you're using an early personal Iris, check that you have
  448. audio hardware and software installed -- the output from hinv will
  449. tell you this.
  450. X
  451. X
  452. On the NeXT you start transmissions as follows:
  453. X
  454. X    sndulaw | broadcast -p port
  455. X
  456. This takes input from the microphone; you may also connect an audio
  457. source to the microphone input (probably needs some attenuation to get
  458. the impedance right).
  459. X
  460. X
  461. By default this broadcasts on the local ethernet.  You can specify one
  462. or more -b options to broadcast, passing it explicit IP broadcast
  463. addresses (last byte 0 or 255, depending on local convention).  You can
  464. specify your local IP net or another net; the latter only works if
  465. your gateways pass UDP broadcasts through (at CWI it works).
  466. X
  467. Note: each transmitter must choose a unique port number.  The default
  468. is 54321; other suitable ports are 54322, 54323, and so on.
  469. X
  470. X
  471. Usage -- reception
  472. X------------------
  473. X
  474. X(See the man page for radio for more details.)
  475. X
  476. To listen to transmissions on either system:
  477. X
  478. X    radio -p port
  479. X
  480. This sends the data directly to the audio output device (speaker or
  481. headphones).  It is also possible to get the ULAW audio data on
  482. standard output with the -f option ("filter").
  483. X
  484. The -v option sets the output volume (on a scale from 0 to 100).  To
  485. change the volume later on a Sun Sparc, use [x_]gaintool (at CWI:
  486. X/usr/demo/SOUND/x_gaintool).  On an SGI, use "apanel".
  487. X
  488. X
  489. Bells 'n whistles
  490. X-----------------
  491. X
  492. Some Python programs are distributed together with radio.  Python is
  493. an object-oriented prototyping language that I developed partly
  494. because I wanted to write system hacks without having to resort to C
  495. or Perl.  Free source and documentation for the Python interpreter is
  496. available by anonymous ftp from various file servers, in particular
  497. ftp.cwi.nl (in the Netherlands) and wuarchive.wustl.edu (in the US).
  498. X
  499. The Python program "ttytuner.py" (by Jack Jansen) can be used to
  500. control the port that radio listens to.  Note that this allows anybody
  501. on the world to control your radio, in principle.  If you don't want
  502. this, you can pass the -s flag (secure), which turns off the control
  503. port altogether.  By convention, the tuner program assumes that every
  504. user who performs transmissions has two files "CD" and "CDlog" in
  505. their home directory giving program information (this is actually a
  506. bad idea, since it requires that the listener and the broadcaster
  507. share the same file name space for user's home directories, but it
  508. saves a lot of complication in the broadcast program).  Jack has also
  509. written a window-oriented tuner (using Motif) -- write to jack@cwi.nl
  510. for source.
  511. X
  512. The Python program "checkradio.py" (after an idea of Behr de Ruiter)
  513. continually checks and displays what one or more stations are
  514. transmitting.  Arguments are port numbers (default is the default port
  515. to which radio is listening).  When the "-t" option is given, it
  516. prints the reports on stdandard output.  Without this option, it must
  517. be running on an SGI machine and uses only one port number argument.
  518. This goes in the background and opens a tiny window in which it
  519. displays the title of the program being transmitted (as glanced from
  520. the sender's CD file).  The window's background color varies from
  521. bright yellow to dark red as the CD file gets older.  When the
  522. transmission stops the window goes away altogether, to pop up only
  523. when it is resumed.
  524. X
  525. The Python program "stations.py" waits for incoming station call
  526. messages (transmitted regularly by "broadcast") and prints essential
  527. info from them on stdout.
  528. X
  529. The Python program "nielsen.py" implements a rudimentary way of
  530. finding out who's listening to what.  Pass it a "-w" option to list
  531. the users on each host where it finds a listener.  You must then be
  532. able to log in to that host remotely (with rlogin or rsh) without
  533. typing your password.
  534. X
  535. There is also one Perl program, just to show that you don't need to be
  536. entirely helpless if you don't have Python nor Motif:
  537. X
  538. The Perl program "stations.pl" listens for and prints essential
  539. information about stations.  Extension to the functionality if
  540. X"stations.py" is left as an exercise to the reader.
  541. X
  542. X
  543. Author
  544. X------
  545. X
  546. The author of this software is:
  547. X
  548. Guido van Rossum
  549. CWI, dept. CST
  550. Kruislaan 413
  551. X1098 SJ  Amsterdam
  552. The Netherlands
  553. X
  554. XE-mail (Internet)  :  Guido.van.Rossum@cwi.nl (guido@cwi.nl)
  555. XE-mail (X.400)     :  G=Guido;S=van.Rossum;O=cwi;PRMD=surf;ADMD=400net;C=nl
  556. X
  557. The "libst" U-LAW conversion library is written and copyrighted by Jef
  558. Poskanzer.
  559. X
  560. If you port this software to other systems or have useful additions
  561. X(like translations of Python programs to C), I'd like to hear from
  562. you.
  563. X
  564. X
  565. Acknowledgements
  566. X----------------
  567. X
  568. I would like the following contributors for pieces of code and/or
  569. documentation:
  570. X
  571. Toerless Eckert for the -n, -l, -r and -t options to radio
  572. X
  573. Paul Friedman for the -v option
  574. X
  575. Axel Belinfante for starting the man pages
  576. X
  577. Reimer A. Mellin for the NeXT port
  578. X
  579. Jack Jansen for the tuner programs and for many discussions about
  580. possible features
  581. X
  582. Behr de Ruiter for the idea for the checkradio program
  583. X
  584. X
  585. Copyright notice
  586. X----------------
  587. X
  588. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  589. Netherlands.
  590. X
  591. X                        All Rights Reserved
  592. X
  593. Permission to use, copy, modify, and distribute this software and its 
  594. documentation for any purpose and without fee is hereby granted, 
  595. provided that the above copyright notice appear in all copies and that
  596. both that copyright notice and this permission notice appear in 
  597. supporting documentation, and that the names of Stichting Mathematisch
  598. Centrum or CWI not be used in advertising or publicity pertaining to
  599. distribution of the software without specific, written prior permission.
  600. X
  601. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  602. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  603. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  604. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  605. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  606. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  607. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  608. END_OF_FILE
  609. if test 15880 -ne `wc -c <'README'`; then
  610.     echo shar: \"'README'\" unpacked with wrong size!
  611. fi
  612. # end of 'README'
  613. fi
  614. if test -f 'adpcm.c' -a "${1}" != "-c" ; then 
  615.   echo shar: Will not clobber existing file \"'adpcm.c'\"
  616. else
  617. echo shar: Extracting \"'adpcm.c'\" \(7085 characters\)
  618. sed "s/^X//" >'adpcm.c' <<'END_OF_FILE'
  619. X/***********************************************************
  620. Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  621. Netherlands.
  622. X
  623. X                        All Rights Reserved
  624. X
  625. Permission to use, copy, modify, and distribute this software and its 
  626. documentation for any purpose and without fee is hereby granted, 
  627. provided that the above copyright notice appear in all copies and that
  628. both that copyright notice and this permission notice appear in 
  629. supporting documentation, and that the names of Stichting Mathematisch
  630. Centrum or CWI not be used in advertising or publicity pertaining to
  631. distribution of the software without specific, written prior permission.
  632. X
  633. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  634. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  635. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  636. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  637. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  638. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  639. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  640. X
  641. X******************************************************************/
  642. X
  643. X/*
  644. X** Intel/DVI ADPCM coder/decoder.
  645. X**
  646. X** The algorithm for this coder was taken from the IMA Compatability Project
  647. X** proceedings, Vol 2, Number 2; May 1992.
  648. X**
  649. X** Version 1.1, 16-Dec-92.
  650. X**
  651. X** Change log:
  652. X** - Fixed a stupid bug, where the delta was computed as
  653. X**   stepsize*code/4 in stead of stepsize*(code+0.5)/4. The old behavior can
  654. X**   still be gotten by defining STUPID_V1_BUG.
  655. X*/
  656. X
  657. X#include "adpcm.h"
  658. X
  659. X#ifndef __STDC__
  660. X#define signed
  661. X#endif
  662. X
  663. X/* Intel ADPCM step variation table */
  664. static int indexTable[16] = {
  665. X    -1, -1, -1, -1, 2, 4, 6, 8,
  666. X    -1, -1, -1, -1, 2, 4, 6, 8,
  667. X};
  668. X
  669. static int stepsizeTable[89] = {
  670. X    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  671. X    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  672. X    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  673. X    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  674. X    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  675. X    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  676. X    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  677. X    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  678. X    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  679. X};
  680. X    
  681. void
  682. adpcm_coder(indata, outdata, len, state)
  683. X    short indata[];
  684. X    char outdata[];
  685. X    int len;
  686. X    struct adpcm_state *state;
  687. X{
  688. X    short *inp;            /* Input buffer pointer */
  689. X    signed char *outp;        /* output buffer pointer */
  690. X    int val;            /* Current input sample value */
  691. X    int sign;            /* Current adpcm sign bit */
  692. X    int delta;            /* Current adpcm output value */
  693. X    int step;            /* Stepsize */
  694. X    int valprev;        /* virtual previous output value */
  695. X    int vpdiff;            /* Current change to valprev */
  696. X    int index;            /* Current step change index */
  697. X    int outputbuffer;        /* place to keep previous 4-bit value */
  698. X    int bufferstep;        /* toggle between outputbuffer/output */
  699. X
  700. X    outp = (signed char *)outdata;
  701. X    inp = indata;
  702. X
  703. X    if (state) {
  704. X    valprev = state->valprev;
  705. X    index = state->index;
  706. X    }
  707. X    else {
  708. X    valprev = 0;
  709. X    index = 0;
  710. X    }
  711. X    step = stepsizeTable[index];
  712. X    
  713. X    bufferstep = 1;
  714. X
  715. X    for ( ; len > 0 ; len-- ) {
  716. X    val = *inp++;
  717. X
  718. X    /* Step 1 - compute difference with previous value */
  719. X    delta = val - valprev;
  720. X    sign = (delta < 0) ? 8 : 0;
  721. X    if ( sign ) delta = (-delta);
  722. X
  723. X    /* Step 2 - Divide and clamp */
  724. X#ifdef NODIVMUL
  725. X        {
  726. X        int tmp = 0;
  727. X#ifdef STUPID_V1_BUG
  728. X        vpdiff = 0;
  729. X#else
  730. X        vpdiff = (step >> 3);
  731. X#endif /* STUPID_V1_BUG */
  732. X        if ( delta > step ) {
  733. X        tmp = 4;
  734. X        delta -= step;
  735. X        vpdiff += step;
  736. X        }
  737. X        step >>= 1;
  738. X        if ( delta > step  ) {
  739. X        tmp |= 2;
  740. X        delta -= step;
  741. X        vpdiff += step;
  742. X        }
  743. X        step >>= 1;
  744. X        if ( delta > step ) {
  745. X        tmp |= 1;
  746. X        vpdiff += step;
  747. X        }
  748. X        delta = tmp;
  749. X    }
  750. X#else
  751. X    delta = (delta<<2) / step;
  752. X    if ( delta > 7 ) delta = 7;
  753. X
  754. X#ifdef STUPID_V1_BUG
  755. X    vpdiff = (delta*step) >> 2;
  756. X#else
  757. X    vpdiff = ((delta*step) >> 2) + (step >> 3);
  758. X#endif /* STUPID_V1_BUG */
  759. X#endif /* NODIVMUL */
  760. X      
  761. X    /* Step 3 - Update previous value */
  762. X    if ( sign )
  763. X      valprev -= vpdiff;
  764. X    else
  765. X      valprev += vpdiff;
  766. X
  767. X    /* Step 4 - Clamp previous value to 16 bits */
  768. X    if ( valprev > 32767 )
  769. X      valprev = 32767;
  770. X    else if ( valprev < -32768 )
  771. X      valprev = -32768;
  772. X
  773. X    /* Step 5 - Assemble value, update index and step values */
  774. X    delta |= sign;
  775. X    
  776. X    index += indexTable[delta];
  777. X    if ( index < 0 ) index = 0;
  778. X    if ( index > 88 ) index = 88;
  779. X    step = stepsizeTable[index];
  780. X
  781. X    /* Step 6 - Output value */
  782. X    if ( bufferstep ) {
  783. X        outputbuffer = (delta << 4) & 0xf0;
  784. X    } else {
  785. X        *outp++ = (delta & 0x0f) | outputbuffer;
  786. X    }
  787. X    bufferstep = !bufferstep;
  788. X    }
  789. X
  790. X    /* Output last step, if needed */
  791. X    if ( !bufferstep )
  792. X      *outp++ = outputbuffer;
  793. X    
  794. X    if (state) {
  795. X    state->valprev = valprev;
  796. X    state->index = index;
  797. X    }
  798. X}
  799. X
  800. void
  801. adpcm_decoder(indata, outdata, len, state)
  802. X    char indata[];
  803. X    short outdata[];
  804. X    int len;
  805. X    struct adpcm_state *state;
  806. X{
  807. X    signed char *inp;        /* Input buffer pointer */
  808. X    short *outp;        /* output buffer pointer */
  809. X    int sign;            /* Current adpcm sign bit */
  810. X    int delta;            /* Current adpcm output value */
  811. X    int step;            /* Stepsize */
  812. X    int valprev;        /* virtual previous output value */
  813. X    int vpdiff;            /* Current change to valprev */
  814. X    int index;            /* Current step change index */
  815. X    int inputbuffer;        /* place to keep next 4-bit value */
  816. X    int bufferstep;        /* toggle between inputbuffer/input */
  817. X
  818. X    outp = outdata;
  819. X    inp = (signed char *)indata;
  820. X
  821. X    if (state) {
  822. X    valprev = state->valprev;
  823. X    index = state->index;
  824. X    }
  825. X    else {
  826. X    valprev = 0;
  827. X    index = 0;
  828. X    }
  829. X    step = stepsizeTable[index];
  830. X
  831. X    bufferstep = 0;
  832. X    
  833. X    for ( ; len > 0 ; len-- ) {
  834. X    
  835. X    /* Step 1 - get the delta value and compute next index */
  836. X    if ( bufferstep ) {
  837. X        delta = inputbuffer & 0xf;
  838. X    } else {
  839. X        inputbuffer = *inp++;
  840. X        delta = (inputbuffer >> 4) & 0xf;
  841. X    }
  842. X    bufferstep = !bufferstep;
  843. X
  844. X    /* Step 2 - Find new index value (for later) */
  845. X    index += indexTable[delta];
  846. X    if ( index < 0 ) index = 0;
  847. X    if ( index > 88 ) index = 88;
  848. X
  849. X    /* Step 3 - Separate sign and magnitude */
  850. X    sign = delta & 8;
  851. X    delta = delta & 7;
  852. X
  853. X    /* Step 4 - update output value */
  854. X#ifdef NODIVMUL
  855. X#ifdef STUPID_V1_BUG
  856. X    vpdiff = 0;
  857. X#else
  858. X    vpdiff = step >> 1;
  859. X#endif /* STUPID_V1_BUG */
  860. X    if ( delta & 4 ) vpdiff += (step << 2);
  861. X    if ( delta & 2 ) vpdiff += (step << 1);
  862. X    if ( delta & 1 ) vpdiff += step;
  863. X    vpdiff >>= 2;
  864. X#else
  865. X#ifdef STUPID_V1_BUG
  866. X    vpdiff = ((delta*step) >> 2);
  867. X#else
  868. X    vpdiff = ((delta*step) >> 2) + (step >> 3);
  869. X#endif /* STUPID_V1_BUG */
  870. X#endif /* ! NODIVMUL */
  871. X    if ( sign )
  872. X      valprev -= vpdiff;
  873. X    else
  874. X      valprev += vpdiff;
  875. X
  876. X    /* Step 5 - clamp output value */
  877. X    if ( valprev > 32767 )
  878. X      valprev = 32767;
  879. X    else if ( valprev < -32768 )
  880. X      valprev = -32768;
  881. X
  882. X    /* Step 6 - Update step value */
  883. X    step = stepsizeTable[index];
  884. X
  885. X    /* Step 7 - Output value */
  886. X    *outp++ = valprev;
  887. X    }
  888. X
  889. X    if (state) {
  890. X    state->valprev = valprev;
  891. X    state->index = index;
  892. X    }
  893. X}
  894. END_OF_FILE
  895. if test 7085 -ne `wc -c <'adpcm.c'`; then
  896.     echo shar: \"'adpcm.c'\" unpacked with wrong size!
  897. fi
  898. # end of 'adpcm.c'
  899. fi
  900. if test -f 'adpcm.h' -a "${1}" != "-c" ; then 
  901.   echo shar: Will not clobber existing file \"'adpcm.h'\"
  902. else
  903. echo shar: Extracting \"'adpcm.h'\" \(563 characters\)
  904. sed "s/^X//" >'adpcm.h' <<'END_OF_FILE'
  905. X/*
  906. X** adpcm.h - include file for adpcm coder.
  907. X**
  908. X** Version 1.0, 7-Jul-92.
  909. X*/
  910. X
  911. struct adpcm_state {
  912. X    short    valprev;    /* Previous output value */
  913. X    char    index;        /* Index into stepsize table */
  914. X};
  915. X
  916. X#ifdef __STDC__
  917. X#define ARGS(x) x
  918. X#else
  919. X#define ARGS(x) ()
  920. X#endif
  921. X
  922. void adpcm_coder ARGS((short [], char [], int, struct adpcm_state *));
  923. void adpcm_decoder ARGS((char [], short [], int, struct adpcm_state *));
  924. void ulaw_adpcm_coder ARGS((char [], char [], int, struct adpcm_state *));
  925. void adpcm_ulaw_decoder ARGS((char [], char [], int, struct adpcm_state *));
  926. END_OF_FILE
  927. if test 563 -ne `wc -c <'adpcm.h'`; then
  928.     echo shar: \"'adpcm.h'\" unpacked with wrong size!
  929. fi
  930. # end of 'adpcm.h'
  931. fi
  932. if test -f 'broadcast.man' -a "${1}" != "-c" ; then 
  933.   echo shar: Will not clobber existing file \"'broadcast.man'\"
  934. else
  935. echo shar: Extracting \"'broadcast.man'\" \(7425 characters\)
  936. sed "s/^X//" >'broadcast.man' <<'END_OF_FILE'
  937. X.TH BROADCAST 1
  938. X.SH NAME
  939. broadcast \- send audio UDP packets to be received by radio
  940. X.SH SYNOPSIS
  941. X.B broadcast
  942. X[
  943. X.B "\-a"
  944. X] [
  945. X.B "\-A"
  946. X] [
  947. X.BI "\-b " addr
  948. X] ... [
  949. X.BI "\-c " port
  950. X] [
  951. X.BI \-d
  952. X]
  953. X          [
  954. X.BI "\-m " ttl
  955. X] [
  956. X.BI \-n
  957. X] [
  958. X.BI "\-p " port
  959. X] [
  960. X.BI \-t
  961. X]
  962. X          [
  963. X.BI "\-L " logfile
  964. X] [
  965. X.BI "-N " name
  966. X] [
  967. X.BI "\P " programfile
  968. X]
  969. X.SH DESCRIPTION
  970. X.I Broadcast
  971. reads audio data in U-LAW format (8000 samples/second, 1 byte/sample,
  972. logarithmically encoded) from standard input, chops it up into packets
  973. of about 1400 bytes each, and transmits these as UDP broadcast packets.
  974. On a typical ethernet, this uses about 1 percent of the net available
  975. bandwith (less than 6 maximum-size packets per second).  If this is
  976. still too much, the
  977. X.B \-a
  978. option can cut the required bandwidth in half.
  979. X.PP
  980. The program
  981. X.IR radio (1)
  982. listens for these packets, reassembles them and makes the encoded
  983. sound audible, given suitable hardware.
  984. X.PP
  985. It is possible to use multiple transmission stations (each identified
  986. by a different UDP port), and to transmit to multiple connected
  987. subnets simultaneously, as long as the gateways let UDP broadcast
  988. packets through.
  989. XEach transmission station should run on a different host though.
  990. X.SH OPTIONS
  991. X.TP 10
  992. X.BR "\-a"
  993. Use ADPCM (Adaptive Delta Pulse Code Modulation) to compress the audio data.
  994. It sends out packets at the same rate, but the packet size is cut in
  995. half.  This saves about 50 percent of the required network bandwidth,
  996. at the cost of some CPU time (for the receivers as well as as for the
  997. sender).  There is a slight degradation in sound quality, but the
  998. quality is actually still quite good.  The receiver adapts itself
  999. automatically to the data format.
  1000. X.TP 10
  1001. X.BR "\-A"
  1002. Use a variant on ADPCM (Adaptive Delta Pulse Code Modulation) which is
  1003. compatible the IVS program from INRIA.
  1004. X.TP 10
  1005. X.BI "\-b " addr
  1006. IP address to send to.  The default is either the local net broadcast address
  1007. or a multicast address assigned to radio if the host supports IP multicasts.
  1008. The address may be a host name (for unicast), an IP broadcast address,
  1009. or an IP multicast address (addresses beginning with 224).
  1010. More than one
  1011. X.B \-b
  1012. option may be given; the data is sent to each address.
  1013. X.TP 10
  1014. X.BI "\-c " port
  1015. Use this UDP port number as control port (default 54320).
  1016. Normally you never need to change this; the control port is used by
  1017. optional ``tuner'' software (distributed separately).
  1018. X.TP 10
  1019. X.B \-d
  1020. Turn on debugging (a message on stderr for each 8 packets sent).
  1021. X.TP 10
  1022. X.BI "\-m " ttl
  1023. Use this to specify a multicast TTL, to control how far the multicasts
  1024. will propagate.  A value of 0 restricts them to the same host,
  1025. X1 to the same subnet, 32 to the same ``site,'' 64 to the same ``region,''
  1026. X128 to the same continent, and 255 is unrestricted.  The default is 32.
  1027. Note that this option only has an effect if your machine supports multicasts
  1028. and you specify a multicast address with the 
  1029. X.B \-b
  1030. option.
  1031. X.TP 10
  1032. X.B \-n
  1033. No silence suppression.
  1034. Normally, when the input contains more than 20 seconds of silence,
  1035. output packets are suppressed until some noise is detected again.
  1036. This option turns off that feature.
  1037. X.TP 10
  1038. X.BI "\-p " port
  1039. Transmit to this UDP port number (default 54321).
  1040. X.TP 10
  1041. X.B \-t
  1042. When the input is faster than real time, e.g., read from a file, this
  1043. option ensures that the packets are sent out at the correct rate (8000
  1044. bytes/sec).
  1045. Normally, it is presumed that the standard input takes care of this.
  1046. X.TP 10
  1047. X.BI "\-L " logfile
  1048. The filename of the file where recent program information is logged.
  1049. Typically, each time the current program information is changed it is
  1050. also appended to this file.
  1051. Default is $HOME/.CDlog.
  1052. X.TP 10
  1053. X.BI "\-N " name
  1054. The name of the station.
  1055. Default the current username.
  1056. X.TP 10
  1057. X.BI "\-P " programfile
  1058. The name of the file where current program information is kept (one line).
  1059. Typically, this file contains three colon-separated fields:
  1060. performer, composer, and title, where the composer field is only used
  1061. for classical music.
  1062. Default is $HOME/.CD.
  1063. X.SH TYPICAL USAGE
  1064. Due to the different interface to audio input hardware on different
  1065. systems, transmissions are started differently on different platforms.
  1066. X.PP
  1067. To start transmissions on Sun Sparcs, run this command (probably in
  1068. the background, once you've debugged your audio setup):
  1069. X.IP
  1070. broadcast -p \fIport\fP </dev/audio
  1071. X.PP
  1072. You must connect a mono audio source to the machine using a standard
  1073. cable provided by Sun.
  1074. Control the input gain with
  1075. X.IR x_gaintool (1)
  1076. or
  1077. X.IP gaintool (1)
  1078. X(these programs can be found in /usr/demo/SOUND in SunOS 4.1).
  1079. X.PP
  1080. This command start transmissions on SGI IRIX:
  1081. X.IP
  1082. recordulaw | broadcast -p \fIport\fP
  1083. X.PP
  1084. Connect a stereo audio source to the machine using a standard walkman
  1085. jack.
  1086. If you're using an early 4D/35, check that you have audio hardware and
  1087. software installed -- the output from hinv will tell you this.
  1088. Control the the input gain with
  1089. X.IR apanel (1).
  1090. X.PP
  1091. On the NeXT you start transmissions as follows:
  1092. X.IP
  1093. sndulaw | broadcast -p \fIport\fP
  1094. X.PP
  1095. This takes input from the microphone; you may also connect an audio
  1096. source to the microphone input (probably needs some attenuation to get
  1097. the impedance right).
  1098. X.SH FORWARDING
  1099. If nets A and B are connected by a gateway that blocks UDP broadcasts
  1100. but lets normal packets through, you can set up a forwarding station
  1101. as follows.
  1102. Assume A.1 is the host on net A where broadcasts originate, A.0 is the
  1103. broadcast address for net A, host B.1 is the forwarding host on net B,
  1104. and B.0 is net B's broadcast address.
  1105. X(You will have to specify IP broadcast addresses in the decimal
  1106. X.I ddd.ddd.ddd.ddd
  1107. format; usually the broadcast address for a net is the same as the IP
  1108. address for hosts on that net with the last byte changed to 0 or 255.)
  1109. On host A.1, run
  1110. X.I broadcast
  1111. as follows:
  1112. X.IP
  1113. broadcast -b A.0 -b B.1
  1114. X.PP
  1115. On host B.1, run this pipeline:
  1116. X.IP
  1117. radio -l B.1 -r A.1 -f | broadcast -b B.0
  1118. X.PP
  1119. Now all hosts on nets A and B can listen to the broadcasts from host
  1120. A.1, at the cost of 100% extra (unicast) packets on both nets.
  1121. X.PP
  1122. If the gateway lets UDP broadcast packets through, no forwarding is
  1123. necessary; running ``broadcast -b A.0 -b B.0'' on host A.1 is
  1124. sufficient.
  1125. X.SH AUTHOR
  1126. Guido van Rossum
  1127. X.SH VERSION
  1128. This manual page documents broadcast version 2.0, patchlevel 0.
  1129. X.SH SEE ALSO
  1130. radio(1)
  1131. X.SH COPYRIGHT
  1132. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  1133. Netherlands.
  1134. X
  1135. X                        All Rights Reserved
  1136. X
  1137. Permission to use, copy, modify, and distribute this software and its 
  1138. documentation for any purpose and without fee is hereby granted, 
  1139. provided that the above copyright notice appear in all copies and that
  1140. both that copyright notice and this permission notice appear in 
  1141. supporting documentation, and that the names of Stichting Mathematisch
  1142. Centrum or CWI not be used in advertising or publicity pertaining to
  1143. distribution of the software without specific, written prior permission.
  1144. X
  1145. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1146. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1147. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1148. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1149. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1150. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1151. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1152. END_OF_FILE
  1153. if test 7425 -ne `wc -c <'broadcast.man'`; then
  1154.     echo shar: \"'broadcast.man'\" unpacked with wrong size!
  1155. fi
  1156. # end of 'broadcast.man'
  1157. fi
  1158. if test -f 'libst.c' -a "${1}" != "-c" ; then 
  1159.   echo shar: Will not clobber existing file \"'libst.c'\"
  1160. else
  1161. echo shar: Extracting \"'libst.c'\" \(3474 characters\)
  1162. sed "s/^X//" >'libst.c' <<'END_OF_FILE'
  1163. X/* libst.c - portable sound tools library
  1164. X*/
  1165. X
  1166. X/*
  1167. X** This routine converts from linear to ulaw.
  1168. X**
  1169. X** Craig Reese: IDA/Supercomputing Research Center
  1170. X** Joe Campbell: Department of Defense
  1171. X** 29 September 1989
  1172. X**
  1173. X** References:
  1174. X** 1) CCITT Recommendation G.711  (very difficult to follow)
  1175. X** 2) "A New Digital Technique for Implementation of Any
  1176. X**     Continuous PCM Companding Law," Villeret, Michel,
  1177. X**     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
  1178. X**     1973, pg. 11.12-11.17
  1179. X** 3) MIL-STD-188-113,"Interoperability and Performance Standards
  1180. X**     for Analog-to_Digital Conversion Techniques,"
  1181. X**     17 February 1987
  1182. X**
  1183. X** Input: Signed 16 bit linear sample
  1184. X** Output: 8 bit ulaw sample
  1185. X*/
  1186. X
  1187. X/* #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
  1188. X#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
  1189. X#define CLIP 32635
  1190. X
  1191. unsigned char
  1192. st_linear_to_ulaw( sample )
  1193. int sample;
  1194. X    {
  1195. X    static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
  1196. X                               4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  1197. X                               5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  1198. X                               5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  1199. X                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  1200. X                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  1201. X                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  1202. X                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  1203. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1204. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1205. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1206. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1207. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1208. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1209. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1210. X                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
  1211. X    int sign, exponent, mantissa;
  1212. X    unsigned char ulawbyte;
  1213. X
  1214. X    /* Get the sample into sign-magnitude. */
  1215. X    sign = (sample >> 8) & 0x80;        /* set aside the sign */
  1216. X    if ( sign != 0 ) sample = -sample;        /* get magnitude */
  1217. X    if ( sample > CLIP ) sample = CLIP;        /* clip the magnitude */
  1218. X
  1219. X    /* Convert from 16 bit linear to ulaw. */
  1220. X    sample = sample + BIAS;
  1221. X    exponent = exp_lut[( sample >> 7 ) & 0xFF];
  1222. X    mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
  1223. X    ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
  1224. X#ifdef ZEROTRAP
  1225. X    if ( ulawbyte == 0 ) ulawbyte = 0x02;    /* optional CCITT trap */
  1226. X#endif
  1227. X
  1228. X    return ulawbyte;
  1229. X    }
  1230. X
  1231. X/*
  1232. X** This routine converts from ulaw to 16 bit linear.
  1233. X**
  1234. X** Craig Reese: IDA/Supercomputing Research Center
  1235. X** 29 September 1989
  1236. X**
  1237. X** References:
  1238. X** 1) CCITT Recommendation G.711  (very difficult to follow)
  1239. X** 2) MIL-STD-188-113,"Interoperability and Performance Standards
  1240. X**     for Analog-to_Digital Conversion Techniques,"
  1241. X**     17 February 1987
  1242. X**
  1243. X** Input: 8 bit ulaw sample
  1244. X** Output: signed 16 bit linear sample
  1245. X*/
  1246. X
  1247. int
  1248. st_ulaw_to_linear_slow( ulawbyte )
  1249. unsigned char ulawbyte;
  1250. X    {
  1251. X    static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
  1252. X    int sign, exponent, mantissa, sample;
  1253. X
  1254. X    ulawbyte = ~ ulawbyte;
  1255. X    sign = ( ulawbyte & 0x80 );
  1256. X    exponent = ( ulawbyte >> 4 ) & 0x07;
  1257. X    mantissa = ulawbyte & 0x0F;
  1258. X    sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
  1259. X    if ( sign != 0 ) sample = -sample;
  1260. X
  1261. X    return sample;
  1262. X    }
  1263. END_OF_FILE
  1264. if test 3474 -ne `wc -c <'libst.c'`; then
  1265.     echo shar: \"'libst.c'\" unpacked with wrong size!
  1266. fi
  1267. # end of 'libst.c'
  1268. fi
  1269. if test -f 'libst.h' -a "${1}" != "-c" ; then 
  1270.   echo shar: Will not clobber existing file \"'libst.h'\"
  1271. else
  1272. echo shar: Extracting \"'libst.h'\" \(3224 characters\)
  1273. sed "s/^X//" >'libst.h' <<'END_OF_FILE'
  1274. X/* libst.h - include file for portable sound tools library
  1275. X**
  1276. X** Copyright (C) 1989 by Jef Poskanzer.
  1277. X**
  1278. X** Permission to use, copy, modify, and distribute this software and its
  1279. X** documentation for any purpose and without fee is hereby granted, provided
  1280. X** that the above copyright notice appear in all copies and that both that
  1281. X** copyright notice and this permission notice appear in supporting
  1282. X** documentation.  This software is provided "as is" without express or
  1283. X** implied warranty.
  1284. X*/
  1285. X
  1286. X#define SAMPLES_PER_SECOND 8192
  1287. X
  1288. X#define MINLIN -32768
  1289. X#define MAXLIN 32767
  1290. X#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; else if ( x > MAXLIN ) x = MAXLIN; } while ( 0 )
  1291. X
  1292. unsigned char st_linear_to_ulaw( /* int sample */ );
  1293. int st_ulaw_to_linear_slow( /* unsigned char ulawbyte */ );
  1294. X
  1295. X/*
  1296. X** This macro converts from ulaw to 16 bit linear, faster.
  1297. X**
  1298. X** Jef Poskanzer
  1299. X** 23 October 1989
  1300. X**
  1301. X** Input: 8 bit ulaw sample
  1302. X** Output: signed 16 bit linear sample
  1303. X*/
  1304. X#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
  1305. X
  1306. static int ulaw_table[256] = {
  1307. X    -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
  1308. X    -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
  1309. X    -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
  1310. X    -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
  1311. X     -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
  1312. X     -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
  1313. X     -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
  1314. X     -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
  1315. X     -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
  1316. X     -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
  1317. X      -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
  1318. X      -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
  1319. X      -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
  1320. X      -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
  1321. X      -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
  1322. X       -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
  1323. X     32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
  1324. X     23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
  1325. X     15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
  1326. X     11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
  1327. X      7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
  1328. X      5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
  1329. X      3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
  1330. X      2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
  1331. X      1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
  1332. X      1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
  1333. X       876,    844,    812,    780,    748,    716,    684,    652,
  1334. X       620,    588,    556,    524,    492,    460,    428,    396,
  1335. X       372,    356,    340,    324,    308,    292,    276,    260,
  1336. X       244,    228,    212,    196,    180,    164,    148,    132,
  1337. X       120,    112,    104,     96,     88,     80,     72,     64,
  1338. X    56,     48,     40,     32,     24,     16,      8,      0 };
  1339. END_OF_FILE
  1340. if test 3224 -ne `wc -c <'libst.h'`; then
  1341.     echo shar: \"'libst.h'\" unpacked with wrong size!
  1342. fi
  1343. # end of 'libst.h'
  1344. fi
  1345. if test -f 'nielsen.py' -a "${1}" != "-c" ; then 
  1346.   echo shar: Will not clobber existing file \"'nielsen.py'\"
  1347. else
  1348. echo shar: Extracting \"'nielsen.py'\" \(2897 characters\)
  1349. sed "s/^X//" >'nielsen.py' <<'END_OF_FILE'
  1350. X#! /ufs/guido/bin/sgi/python
  1351. X
  1352. X# /***********************************************************
  1353. X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  1354. X# Netherlands.
  1355. X# 
  1356. X#                         All Rights Reserved
  1357. X# 
  1358. X# Permission to use, copy, modify, and distribute this software and its 
  1359. X# documentation for any purpose and without fee is hereby granted, 
  1360. X# provided that the above copyright notice appear in all copies and that
  1361. X# both that copyright notice and this permission notice appear in 
  1362. X# supporting documentation, and that the names of Stichting Mathematisch
  1363. X# Centrum or CWI not be used in advertising or publicity pertaining to
  1364. X# distribution of the software without specific, written prior permission.
  1365. X# 
  1366. X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1367. X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1368. X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1369. X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1370. X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1371. X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1372. X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1373. X# 
  1374. X# ******************************************************************/
  1375. X
  1376. X# Radio listening statistics.
  1377. X#
  1378. X# usage: nielsen [-w] [port]
  1379. X# -w    print who's logged on (slow)
  1380. X# port    alternate port to broadcast to
  1381. X#
  1382. X# XXX should understand -b options as well, instead of hardwiring addresses.
  1383. X
  1384. import sys, os, time, string
  1385. from socket import *
  1386. try:
  1387. X    # 'nis' is an optional module which interfaces to NIS (a.k.a. YP)
  1388. X    import nis
  1389. except ImportError:
  1390. X    # If nis doesn't exist, too bad -- don't print hostnames then
  1391. X    nis = None
  1392. X
  1393. addrlist = '192.16.184.0', '192.16.191.0', '192.16.201.255'
  1394. port = 54320
  1395. who = 0
  1396. if sys.argv[1:2] == ['-w']: who = 1; sys.argv[1:2] = []
  1397. if sys.argv[1:]: port = eval(sys.argv[1])
  1398. X
  1399. s = socket(AF_INET, SOCK_DGRAM)
  1400. s.allowbroadcast(1)
  1401. for addr in addrlist:
  1402. X    s.sendto('radio:i', (addr, port))
  1403. X
  1404. TIMEOUT = 7
  1405. X
  1406. try:
  1407. X    while 1:
  1408. X        # Time-out if no next response within TIMEOUT seconds
  1409. X        for i in range(TIMEOUT):
  1410. X            if s.avail(): break
  1411. X            else: time.sleep(1)
  1412. X        else:
  1413. X            print 'Time-out -- assume no more responses.'
  1414. X            break # out of the enclosing while loop
  1415. X        data, (host, port) = s.recvfrom(1400)
  1416. X        print data, host,
  1417. X        try:
  1418. X            response = nis.match(host, 'hosts.byaddr')
  1419. X            words = string.split(response)
  1420. X            print words[1],
  1421. X        except nis.error:
  1422. X            pass
  1423. X        print
  1424. X        if who:
  1425. X            cmd = 'rusers ' + host
  1426. X            line = os.popen(cmd, 'r').read()
  1427. X            words = string.split(line)
  1428. X            del words[0]
  1429. X            for w in words[:]:
  1430. X                if words.count(w) > 1: words.remove(w)
  1431. X            words.sort()
  1432. X            for w in words: print w,
  1433. X            print
  1434. X            # Old version using rsh who:
  1435. X            # cmd = 'who | sed \'s/ .*//\' | sort -u'
  1436. X            # sts = os.system('rsh ' + host + ' "' + cmd + '"')
  1437. except KeyboardInterrupt:
  1438. X    pass
  1439. END_OF_FILE
  1440. if test 2897 -ne `wc -c <'nielsen.py'`; then
  1441.     echo shar: \"'nielsen.py'\" unpacked with wrong size!
  1442. fi
  1443. chmod +x 'nielsen.py'
  1444. # end of 'nielsen.py'
  1445. fi
  1446. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  1447.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  1448. else
  1449. echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
  1450. sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  1451. X#define PATCHLEVEL 2
  1452. END_OF_FILE
  1453. if test 21 -ne `wc -c <'patchlevel.h'`; then
  1454.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  1455. fi
  1456. # end of 'patchlevel.h'
  1457. fi
  1458. if test -f 'playulaw.c' -a "${1}" != "-c" ; then 
  1459.   echo shar: Will not clobber existing file \"'playulaw.c'\"
  1460. else
  1461. echo shar: Extracting \"'playulaw.c'\" \(4154 characters\)
  1462. sed "s/^X//" >'playulaw.c' <<'END_OF_FILE'
  1463. X/***********************************************************
  1464. Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1465. Netherlands.
  1466. X
  1467. X                        All Rights Reserved
  1468. X
  1469. Permission to use, copy, modify, and distribute this software and its 
  1470. documentation for any purpose and without fee is hereby granted, 
  1471. provided that the above copyright notice appear in all copies and that
  1472. both that copyright notice and this permission notice appear in 
  1473. supporting documentation, and that the names of Stichting Mathematisch
  1474. Centrum or CWI not be used in advertising or publicity pertaining to
  1475. distribution of the software without specific, written prior permission.
  1476. X
  1477. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1478. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1479. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1480. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1481. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1482. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1483. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1484. X
  1485. X******************************************************************/
  1486. X
  1487. X/* Play ulaw audio data read from stdin */
  1488. X
  1489. X#define BUFFERSIZE 4000
  1490. X
  1491. X#ifdef sgi
  1492. X#define USE_AL
  1493. X#endif
  1494. X#ifdef sun
  1495. X#define USE_SUN
  1496. X#endif
  1497. X
  1498. X#include <stdio.h>
  1499. X#include <errno.h>
  1500. X#include <stdlib.h>
  1501. X#include <fcntl.h>
  1502. X#include <signal.h>
  1503. X
  1504. X#include <sys/types.h>
  1505. X#include <sys/socket.h>
  1506. X#include <sys/time.h>
  1507. X#include <netinet/in.h>
  1508. X
  1509. X#ifdef USE_AL
  1510. X#include <audio.h>
  1511. X#include "libst.h"
  1512. X
  1513. long savestate[] = {
  1514. X    AL_OUTPUT_RATE, 0,
  1515. X};
  1516. X#endif
  1517. X
  1518. X#ifdef USE_SUN
  1519. X#include <stropts.h>
  1520. X#endif
  1521. X
  1522. X/* getopt() interface */
  1523. extern int optind;
  1524. extern char * optarg;
  1525. X
  1526. X/* Forward */
  1527. void cleanup_handler();
  1528. X
  1529. X/* Globals */
  1530. char *progname;
  1531. X
  1532. main(argc, argv)
  1533. X    int argc;
  1534. X    char **argv;
  1535. X{
  1536. X    char buf[BUFFERSIZE];
  1537. X    int n;
  1538. X    int c;
  1539. X    int ifd, ofd;
  1540. X    int sts = 0;
  1541. X#ifdef USE_AL
  1542. X    short obuf[BUFFERSIZE];
  1543. X    ALport aport;
  1544. X    ALconfig config;
  1545. X    int i;
  1546. X    long pvbuf[2];
  1547. X#endif
  1548. X
  1549. X    progname = argv[0];
  1550. X    while ((c = getopt(argc, argv, "")) != EOF) {
  1551. X        switch (c) {
  1552. X        case '?':
  1553. X            usage();
  1554. X        }
  1555. X    }
  1556. X
  1557. X    if (optind >= argc) {
  1558. X        ifd = fileno(stdin);
  1559. X    }
  1560. X    else {
  1561. X        if (optind+1 < argc)
  1562. X            usage();
  1563. X        ifd = open(argv[optind], 0);
  1564. X        if (ifd < 0) {
  1565. X            perror(argv[optind]);
  1566. X            exit(1);
  1567. X        }
  1568. X    }
  1569. X
  1570. X#ifdef USE_AL
  1571. X    /* Fetch the original state */
  1572. X    ALgetparams(AL_DEFAULT_DEVICE, savestate,
  1573. X            sizeof(savestate) / sizeof(long));
  1574. X
  1575. X    /* Set signal handlers */
  1576. X    signal(SIGINT, cleanup_handler);
  1577. X    signal(SIGTERM, cleanup_handler);
  1578. X
  1579. X    /* Configure and open an SGI audio port */
  1580. X    config = ALnewconfig();
  1581. X    ALsetchannels(config, AL_MONO);
  1582. X    ALsetwidth(config, AL_SAMPLE_16);
  1583. X    ALsetqueuesize(config, 16000); /* 2 seconds slop */
  1584. X    aport = ALopenport("radio", "w", config);
  1585. X    if (aport == NULL) {
  1586. X        perror("ALopenport");
  1587. X        exit(1);
  1588. X    }
  1589. X
  1590. X    /* Set the output sampling rate to 8000 Hz */
  1591. X    /* Do this after ALopenport so we needn't undo it if that fails */
  1592. X    pvbuf[0] = AL_OUTPUT_RATE;
  1593. X    pvbuf[1] = AL_RATE_8000;
  1594. X    ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2L);
  1595. X#else
  1596. X    /* Write to /dev/audio */
  1597. X    if ((ofd = open("/dev/audio", O_WRONLY | O_NDELAY)) < 0) {
  1598. X        perror("/dev/audio");
  1599. X        exit(1);
  1600. X    }
  1601. X#endif
  1602. X
  1603. X    for (;;) {
  1604. X        n = read(ifd, buf, BUFFERSIZE);
  1605. X        if (n <= 0) {
  1606. X            if (n < 0) {
  1607. X                perror("read");
  1608. X                sts = 1;
  1609. X            }
  1610. X            break;
  1611. X        }
  1612. X#ifdef USE_AL
  1613. X        for (i = 0; i < n; i++)
  1614. X            obuf[i] = st_ulaw_to_linear(buf[i]);
  1615. X        ALwritesamps(aport, obuf, (long)n);
  1616. X#else
  1617. X        if (write(ofd, buf, n) != n) {
  1618. X            perror("write");
  1619. X            sts = 1;
  1620. X            break;
  1621. X        }
  1622. X#endif
  1623. X    }
  1624. X
  1625. X#ifdef USE_AL
  1626. X    /* Wait until all sound has played */
  1627. X    while(ALgetfilled(aport) > 0) /* still sound to play */
  1628. X        sginap(1);    /* sleep for 1/60 of a second */
  1629. X
  1630. X    /* Restore the output sampling rate */
  1631. X    ALsetparams(AL_DEFAULT_DEVICE, savestate,
  1632. X            sizeof(savestate) / sizeof(long));
  1633. X#endif
  1634. X
  1635. X    exit(sts);
  1636. X}
  1637. X
  1638. usage()
  1639. X{
  1640. X    fprintf(stderr, "usage: %s [file]\n", progname);
  1641. X    exit(2);
  1642. X}
  1643. X
  1644. X#ifdef USE_AL
  1645. X
  1646. void cleanup_handler(sig)
  1647. X    int sig;
  1648. X{
  1649. X    signal(sig, SIG_DFL);
  1650. X    ALsetparams(AL_DEFAULT_DEVICE, savestate,
  1651. X            sizeof(savestate) / sizeof(long));
  1652. X    kill(getpid(), sig);
  1653. X}
  1654. X
  1655. X#endif /* USE_AL */
  1656. END_OF_FILE
  1657. if test 4154 -ne `wc -c <'playulaw.c'`; then
  1658.     echo shar: \"'playulaw.c'\" unpacked with wrong size!
  1659. fi
  1660. # end of 'playulaw.c'
  1661. fi
  1662. if test -f 'radio.h' -a "${1}" != "-c" ; then 
  1663.   echo shar: Will not clobber existing file \"'radio.h'\"
  1664. else
  1665. echo shar: Extracting \"'radio.h'\" \(2085 characters\)
  1666. sed "s/^X//" >'radio.h' <<'END_OF_FILE'
  1667. X/***********************************************************
  1668. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  1669. Netherlands.
  1670. X
  1671. X                        All Rights Reserved
  1672. X
  1673. Permission to use, copy, modify, and distribute this software and its 
  1674. documentation for any purpose and without fee is hereby granted, 
  1675. provided that the above copyright notice appear in all copies and that
  1676. both that copyright notice and this permission notice appear in 
  1677. supporting documentation, and that the names of Stichting Mathematisch
  1678. Centrum or CWI not be used in advertising or publicity pertaining to
  1679. distribution of the software without specific, written prior permission.
  1680. X
  1681. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1682. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1683. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1684. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1685. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1686. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1687. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1688. X
  1689. X******************************************************************/
  1690. X
  1691. X/* Constants shared by radio.c and broadcast.c */
  1692. X
  1693. X#define BCASTCTLPORT        54319
  1694. X#define RADIOCTLPORT        54320
  1695. X#define RCVPORT            54321
  1696. X#define SENDPORT        54318
  1697. X#define INFOPORT        54317
  1698. X
  1699. X#define SAMPLINGRATE        8000
  1700. X
  1701. X#define BUFFERSIZE        1400
  1702. X#define CTLPKTSIZE        512
  1703. X#define INFOFREQ        ((30*SAMPLINGRATE) / BUFFERSIZE)
  1704. X
  1705. X#define HEADERSIZE        2 /* IVS header: 2 bytes (type, encoding) */
  1706. X
  1707. X#define TYPE_MASK        (3<<6)
  1708. X#define AUDIO_TYPE        (2<<6)
  1709. X
  1710. X#define PCM_64            0
  1711. X#define PCM_32            1
  1712. X#define ADPCM_32        2
  1713. X#define VADPCM            3
  1714. X#define ADPCM_32_W_STATE    66
  1715. X
  1716. X#ifndef DEFMCAST
  1717. X#define DEFMCAST        "224.0.2.5"
  1718. X#endif
  1719. X
  1720. X#ifndef MULTICAST_TTL
  1721. X#define MULTICAST_TTL        32
  1722. X#endif
  1723. X
  1724. X#define VERSION            "2.0"
  1725. X
  1726. X#ifdef sgi
  1727. X#define USE_AL
  1728. X#define CHECK_X_SERVER
  1729. X#define HAVE_MCAST
  1730. X#endif
  1731. X
  1732. X#ifdef sun
  1733. X#define SUNHACKS
  1734. X#define USE_SUN
  1735. X#define CHECK_X_SERVER
  1736. X#endif
  1737. X
  1738. X#ifdef NeXT
  1739. X#define USE_NX
  1740. X#endif
  1741. END_OF_FILE
  1742. if test 2085 -ne `wc -c <'radio.h'`; then
  1743.     echo shar: \"'radio.h'\" unpacked with wrong size!
  1744. fi
  1745. # end of 'radio.h'
  1746. fi
  1747. if test -f 'radio.man' -a "${1}" != "-c" ; then 
  1748.   echo shar: Will not clobber existing file \"'radio.man'\"
  1749. else
  1750. echo shar: Extracting \"'radio.man'\" \(4529 characters\)
  1751. sed "s/^X//" >'radio.man' <<'END_OF_FILE'
  1752. X.TH RADIO 1
  1753. X.SH NAME
  1754. radio \- receive audio UDP packets transmitted by broadcast
  1755. X.SH SYNOPSIS
  1756. X.B radio
  1757. X[
  1758. X.B \-c
  1759. X.I port
  1760. X] [
  1761. X.B \-d
  1762. X] [
  1763. X.B \-f
  1764. X] [
  1765. X.B \-l
  1766. X.I addr
  1767. X] [
  1768. X.B \-m
  1769. X.I mcastgrp
  1770. X]
  1771. X [
  1772. X.B \-n
  1773. X] [
  1774. X.B \-p
  1775. X.I port
  1776. X] [
  1777. X.B -r
  1778. X.I addr
  1779. X] [
  1780. X.B \-s
  1781. X] [
  1782. X.B \-t
  1783. X] [
  1784. X.B \-v
  1785. X.I volume
  1786. X]
  1787. X.SH DESCRIPTION
  1788. X.I Radio
  1789. allows you to listen to audio transmitted as UDP packets on a local
  1790. area network by
  1791. X.IR broadcast (1).
  1792. Obviously, this requires a workstation with audio hardware; currently
  1793. the program works on SGI Indigo and 4D/35 workstations, Sun Sparcs, and
  1794. all NeXTs.
  1795. X.PP
  1796. X.I Radio
  1797. is normally run in the background.
  1798. You may need a system-specific tool to change the volume or direct the
  1799. output to the speaker or headphone jack; e.g., on an SGI, you would
  1800. use
  1801. X.IR apanel (1);
  1802. X on a Sun you would use
  1803. X.IR gaintool (1)
  1804. or, when using X,
  1805. X.IR x_gaintool (1)
  1806. X(these programs can be found in /usr/demo/SOUND in SunOS 4.1).
  1807. With OpenWindows 3.0, you can use
  1808. X.IR audiotool (1).
  1809. X(On the NeXT, just use the volume keys on the keyboard.)
  1810. X.PP
  1811. Some loss of UDP packets is tolerated; this is heard as short
  1812. interruptions of the sound.
  1813. X.SH OPTIONS
  1814. X.TP 10
  1815. X.BI "\-c " port
  1816. Use this UDP port number as control port (default 54320).
  1817. Normally you never need to change this; the control port is used by
  1818. optional ``tuner'' software (not distributed) and possibly by listener
  1819. polling programs.
  1820. X.TP 10
  1821. X.B \-d
  1822. Turn on debugging (a message on stderr for each 8 packets received,
  1823. and when rare or unexpected events happen).
  1824. X.TP 10
  1825. X.B \-f
  1826. XFilter mode: write the U-LAW audio data to stdout instead of
  1827. sending it to the audio hardware.
  1828. X.TP 10
  1829. X.BI "\-l " addr
  1830. Listen only for packets to IP address
  1831. X.I addr
  1832. X(useful for forwarding stations).
  1833. X.TP 10
  1834. X.BI "\-m " mcastgrp
  1835. Multicast group.
  1836. This only makes sense if the same multicast group is passed to the
  1837. X.B \-b
  1838. option of
  1839. X.IR broadcast (1).
  1840. Using multicasting instead of broadcasting reduces the load on
  1841. machines that aren't listening.
  1842. You should use the same multicast group for all stations on the local network.
  1843. X(Note that even if a multicast group is specified, stations using broadcasts
  1844. can still be picked up by radio).
  1845. X.TP 10
  1846. X.B \-n
  1847. Noninterruptable mode (Sun Sparc only).
  1848. By default,
  1849. X.I radio
  1850. notices when another program wants to open the
  1851. audio output device, and temporarily ``backs off'' until the other
  1852. program is finished, hoping it won't take too long.
  1853. This option turns off that feature.
  1854. X.TP 10
  1855. X.BI "\-p " port
  1856. Receive packets sent to this UDP port number (default 54321).
  1857. This corresponds to the port used by
  1858. X.I broadcast.
  1859. Port numbers 1..99 are shorthands for 54321..54419.
  1860. X.TP 10
  1861. X.BI "\-r " addr
  1862. Listen only for packets from IP address
  1863. X.I addr
  1864. X(useful for forwarding stations).
  1865. X.TP 10
  1866. X.B \-s
  1867. Secure mode: don't listen to the control port.
  1868. This is for really paranoid users: in theory, any user on the net
  1869. can override the port specified with \fB\-p\fP by sending a control
  1870. message to the control port of your radio program.
  1871. X.TP 10
  1872. X.B \-t
  1873. Tee mode: write the U-LAW audio data to stdout as well as
  1874. sending it to the audio hardware.
  1875. X.TP 10
  1876. X.BI "\-v " volume
  1877. Set the initial volume, on a scale from 0 to 100.  (SGI and Sun Sparc only.)
  1878. By default, the volume is left unchanged.
  1879. When the volume is specified this way, its original value is restored
  1880. when the program exits.
  1881. X.SH AUTHOR
  1882. Guido van Rossum
  1883. X.SH VERSION
  1884. This manual page documents radio version 2.0, patchlevel 1.
  1885. X.SH SEE ALSO
  1886. broadcast(1)
  1887. X.SH COPYRIGHT
  1888. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  1889. Netherlands.
  1890. X
  1891. X                        All Rights Reserved
  1892. X
  1893. Permission to use, copy, modify, and distribute this software and its 
  1894. documentation for any purpose and without fee is hereby granted, 
  1895. provided that the above copyright notice appear in all copies and that
  1896. both that copyright notice and this permission notice appear in 
  1897. supporting documentation, and that the names of Stichting Mathematisch
  1898. Centrum or CWI not be used in advertising or publicity pertaining to
  1899. distribution of the software without specific, written prior permission.
  1900. X
  1901. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1902. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1903. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1904. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1905. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1906. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1907. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1908. END_OF_FILE
  1909. if test 4529 -ne `wc -c <'radio.man'`; then
  1910.     echo shar: \"'radio.man'\" unpacked with wrong size!
  1911. fi
  1912. # end of 'radio.man'
  1913. fi
  1914. if test -f 'recordlinear.c' -a "${1}" != "-c" ; then 
  1915.   echo shar: Will not clobber existing file \"'recordlinear.c'\"
  1916. else
  1917. echo shar: Extracting \"'recordlinear.c'\" \(3541 characters\)
  1918. sed "s/^X//" >'recordlinear.c' <<'END_OF_FILE'
  1919. X/***********************************************************
  1920. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  1921. Netherlands.
  1922. X
  1923. X                        All Rights Reserved
  1924. X
  1925. Permission to use, copy, modify, and distribute this software and its 
  1926. documentation for any purpose and without fee is hereby granted, 
  1927. provided that the above copyright notice appear in all copies and that
  1928. both that copyright notice and this permission notice appear in 
  1929. supporting documentation, and that the names of Stichting Mathematisch
  1930. Centrum or CWI not be used in advertising or publicity pertaining to
  1931. distribution of the software without specific, written prior permission.
  1932. X
  1933. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1934. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1935. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1936. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1937. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1938. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1939. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1940. X
  1941. X******************************************************************/
  1942. X
  1943. X/* Record SGI audio data and output it as 8 kHz signed 16-bits samples,
  1944. X   converting the sampling rate and encoding on the fly.
  1945. X   This writes to stdout.
  1946. X   
  1947. X   Caveats:
  1948. X   - since it uses an audio port, of which there can only be 4 open
  1949. X     at a time, running several copies is not a good idea;
  1950. X     see broadcast.c and radio.c for a distribution mechanism.
  1951. X
  1952. X  To do:
  1953. X  - support the other three sampling rates
  1954. X*/
  1955. X
  1956. X#include <stdio.h>
  1957. X#include <audio.h>
  1958. X
  1959. int inrate;
  1960. X
  1961. X#define OUTRATE    8000
  1962. X#define INBUFSIZE 48000
  1963. X
  1964. main(argc, argv)
  1965. X    int argc;
  1966. X    char **argv;
  1967. X{
  1968. X    short inbuf[INBUFSIZE];
  1969. X    short outbuf[8000];
  1970. X    ALconfig c;
  1971. X    ALport p;
  1972. X    int n;
  1973. X    int insamps;
  1974. X    int sts = 0;
  1975. X    
  1976. X    checkinrate();
  1977. X    insamps = calcinsamps();
  1978. X    
  1979. X    c = ALnewconfig();
  1980. X    if (c == NULL) {
  1981. X        perror("ALnewconfig");
  1982. X        exit(1);
  1983. X    }
  1984. X    ALsetwidth(c, AL_SAMPLE_16);
  1985. X    ALsetchannels(c, AL_MONO);
  1986. X    
  1987. X    p = ALopenport(argv[0], "r", c);
  1988. X    if (p == NULL) {
  1989. X        perror("ALopenport");
  1990. X        exit(1);
  1991. X    }
  1992. X
  1993. X    for (;;) {
  1994. X        checkinrate();
  1995. X        insamps = calcinsamps();
  1996. X        ALreadsamps(p, (void *)inbuf, insamps);
  1997. X        n = convert(inbuf, insamps, outbuf);
  1998. X        n = n * sizeof(short);
  1999. X        if (write(1, (char *)outbuf, n) != n) {
  2000. X            perror("write error");
  2001. X            sts = 1;
  2002. X            break;
  2003. X        }
  2004. X    }
  2005. X
  2006. X    exit(sts);
  2007. X}
  2008. X
  2009. int calcinsamps()
  2010. X{
  2011. X    int insamps = inrate/2;
  2012. X    if (insamps > INBUFSIZE)
  2013. X        insamps = INBUFSIZE;
  2014. X    return insamps;
  2015. X}
  2016. X
  2017. checkinrate()
  2018. X{
  2019. X    inrate = getinrate();
  2020. X    if ((inrate/OUTRATE)*OUTRATE != inrate) {
  2021. X        fprintf(stderr,
  2022. X            "current sampling rate (%d) is not a multiple of %d\n",
  2023. X            inrate, OUTRATE);
  2024. X        exit(1);
  2025. X    }
  2026. X}
  2027. X
  2028. int getinrate()
  2029. X{
  2030. X    long PVbuffer[2];
  2031. X    
  2032. X    PVbuffer[0] = AL_INPUT_RATE;
  2033. X    ALgetparams(AL_DEFAULT_DEVICE, PVbuffer, 2);
  2034. X    return PVbuffer[1];
  2035. X}
  2036. X
  2037. int convert(inbuf, n, outbuf)
  2038. X    short *inbuf;
  2039. X    int n;
  2040. X    short *outbuf;
  2041. X{
  2042. X    register short *inp = inbuf;
  2043. X    register short *inend = inbuf + n;
  2044. X    register int di = inrate/OUTRATE;
  2045. X    register int x;
  2046. X    register short *outp = outbuf;
  2047. X
  2048. X    while (inp < inend) {
  2049. X        switch (di) {
  2050. X        case 1:
  2051. X            *outp++ = *inp++;
  2052. X            break;
  2053. X        case 2:
  2054. X            x = *inp++;
  2055. X            x += *inp++;
  2056. X            *outp++ = x >> 1;
  2057. X            break;
  2058. X        case 4:
  2059. X            x = *inp++;
  2060. X            x += *inp++;
  2061. X            x += *inp++;
  2062. X            x += *inp++;
  2063. X            *outp++ = x >> 2;
  2064. X            break;
  2065. X        case 6:
  2066. X            x = *inp++;
  2067. X            x += *inp++;
  2068. X            x += *inp++;
  2069. X            x += *inp++;
  2070. X            x += *inp++;
  2071. X            x += *inp++;
  2072. X            *outp++ = x / 24;
  2073. X            break;
  2074. X        }
  2075. X    }
  2076. X
  2077. X    return outp - outbuf;
  2078. X}
  2079. END_OF_FILE
  2080. if test 3541 -ne `wc -c <'recordlinear.c'`; then
  2081.     echo shar: \"'recordlinear.c'\" unpacked with wrong size!
  2082. fi
  2083. # end of 'recordlinear.c'
  2084. fi
  2085. if test -f 'recordulaw.c' -a "${1}" != "-c" ; then 
  2086.   echo shar: Will not clobber existing file \"'recordulaw.c'\"
  2087. else
  2088. echo shar: Extracting \"'recordulaw.c'\" \(4711 characters\)
  2089. sed "s/^X//" >'recordulaw.c' <<'END_OF_FILE'
  2090. X/***********************************************************
  2091. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  2092. Netherlands.
  2093. X
  2094. X                        All Rights Reserved
  2095. X
  2096. Permission to use, copy, modify, and distribute this software and its 
  2097. documentation for any purpose and without fee is hereby granted, 
  2098. provided that the above copyright notice appear in all copies and that
  2099. both that copyright notice and this permission notice appear in 
  2100. supporting documentation, and that the names of Stichting Mathematisch
  2101. Centrum or CWI not be used in advertising or publicity pertaining to
  2102. distribution of the software without specific, written prior permission.
  2103. X
  2104. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2105. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2106. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2107. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2108. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2109. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2110. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2111. X
  2112. X******************************************************************/
  2113. X
  2114. X/* Record SGI audio data and output it at 8 kHz to Sparc uLAW format,
  2115. X   converting the sampling rate and encoding on the fly.
  2116. X   This writes to stdout -- use rsh to pipe it to /dev/audio on a Sparc.
  2117. X   No Sun audio header is added.
  2118. X   
  2119. X   Caveats:
  2120. X   - since it uses an audio port, of which there can only be 4 open
  2121. X     at a time, running several copies is not a good idea;
  2122. X     see broadcast.c and radio.c for a distribution mechanism.
  2123. X
  2124. X  To do:
  2125. X  - support the other three sampling rates
  2126. X*/
  2127. X
  2128. X#include <stdio.h>
  2129. X#include <audio.h>
  2130. X
  2131. int inrate;
  2132. X
  2133. X#define OUTRATE    8000
  2134. X#define INBUFSIZE 48000
  2135. X
  2136. main(argc, argv)
  2137. X    int argc;
  2138. X    char **argv;
  2139. X{
  2140. X    short inbuf[INBUFSIZE];
  2141. X    char outbuf[8000];
  2142. X    ALconfig c;
  2143. X    ALport p;
  2144. X    int n;
  2145. X    int insamps;
  2146. X    int sts = 0;
  2147. X    
  2148. X    checkinrate();
  2149. X    insamps = calcinsamps();
  2150. X    
  2151. X    c = ALnewconfig();
  2152. X    if (c == NULL) {
  2153. X        perror("ALnewconfig");
  2154. X        exit(1);
  2155. X    }
  2156. X    ALsetwidth(c, AL_SAMPLE_16);
  2157. X    ALsetchannels(c, AL_MONO);
  2158. X    
  2159. X    p = ALopenport(argv[0], "r", c);
  2160. X    if (p == NULL) {
  2161. X        perror("ALopenport");
  2162. X        exit(1);
  2163. X    }
  2164. X
  2165. X    initcvt();
  2166. X
  2167. X    for (;;) {
  2168. X        checkinrate();
  2169. X        insamps = calcinsamps();
  2170. X        ALreadsamps(p, (void *)inbuf, insamps);
  2171. X        n = convert(inbuf, insamps, outbuf);
  2172. X        if (write(1, outbuf, n) != n) {
  2173. X            perror("write error");
  2174. X            sts = 1;
  2175. X            break;
  2176. X        }
  2177. X    }
  2178. X
  2179. X    exit(sts);
  2180. X}
  2181. X
  2182. int calcinsamps()
  2183. X{
  2184. X    int insamps = inrate/2;
  2185. X    if (insamps > INBUFSIZE)
  2186. X        insamps = INBUFSIZE;
  2187. X    return insamps;
  2188. X}
  2189. X
  2190. checkinrate()
  2191. X{
  2192. X    inrate = getinrate();
  2193. X    if ((inrate/OUTRATE)*OUTRATE != inrate) {
  2194. X        fprintf(stderr,
  2195. X            "current sampling rate (%d) is not a multiple of %d\n",
  2196. X            inrate, OUTRATE);
  2197. X        exit(1);
  2198. X    }
  2199. X}
  2200. X
  2201. int getinrate()
  2202. X{
  2203. X    long PVbuffer[2];
  2204. X    
  2205. X    PVbuffer[0] = AL_INPUT_RATE;
  2206. X    ALgetparams(AL_DEFAULT_DEVICE, PVbuffer, 2);
  2207. X    return PVbuffer[1];
  2208. X}
  2209. X
  2210. X/* Convert a bufferful of data from SGI to uLAW format
  2211. X   - inrate samples/sec --> 8000 samples/sec
  2212. X   - 16 bit linear encoding --> 8 bit uLAW encoding
  2213. X*/
  2214. X
  2215. extern unsigned char *cvtvec; /* Forward */
  2216. X
  2217. int convert(inbuf, n, outbuf)
  2218. X    short *inbuf;
  2219. X    int n;
  2220. X    unsigned char *outbuf;
  2221. X{
  2222. X    register short *inp = inbuf;
  2223. X    register short *inend = inbuf + n;
  2224. X    register int di = inrate/OUTRATE;
  2225. X    register int x;
  2226. X    register unsigned char *outp = outbuf;
  2227. X
  2228. X    while (inp < inend) {
  2229. X        switch (di) {
  2230. X        case 1:
  2231. X            *outp++ = cvtvec[*inp++ >> 2];
  2232. X            break;
  2233. X        case 2:
  2234. X            x = *inp++;
  2235. X            x += *inp++;
  2236. X            *outp++ = cvtvec[x >> 3];
  2237. X            break;
  2238. X        case 4:
  2239. X            x = *inp++;
  2240. X            x += *inp++;
  2241. X            x += *inp++;
  2242. X            x += *inp++;
  2243. X            *outp++ = cvtvec[x >> 4];
  2244. X            break;
  2245. X        case 6:
  2246. X            x = *inp++;
  2247. X            x += *inp++;
  2248. X            x += *inp++;
  2249. X            x += *inp++;
  2250. X            x += *inp++;
  2251. X            x += *inp++;
  2252. X            *outp++ = cvtvec[x / 24];
  2253. X            break;
  2254. X        }
  2255. X    }
  2256. X
  2257. X    return outp - outbuf;
  2258. X}
  2259. X
  2260. X
  2261. X/* convert two's complement ch (1+13 bits) into uLAW format (8 bits) */
  2262. X
  2263. unsigned int cvt(ch)
  2264. int ch;
  2265. X{
  2266. X    int mask;
  2267. X
  2268. X    if (ch < 0) {
  2269. X        ch = -ch;
  2270. X        mask = 0x7f;
  2271. X    } else {
  2272. X        mask = 0xff;
  2273. X    }
  2274. X
  2275. X    if (ch < 32) {
  2276. X        ch = 0xF0 | 15 - (ch / 2);
  2277. X    } else if (ch < 96) {
  2278. X        ch = 0xE0 | 15 - (ch - 32) / 4;
  2279. X    } else if (ch < 224) {
  2280. X        ch = 0xD0 | 15 - (ch - 96) / 8;
  2281. X    } else if (ch < 480) {
  2282. X        ch = 0xC0 | 15 - (ch - 224) / 16;
  2283. X    } else if (ch < 992) {
  2284. X        ch = 0xB0 | 15 - (ch - 480) / 32;
  2285. X    } else if (ch < 2016) {
  2286. X        ch = 0xA0 | 15 - (ch - 992) / 64;
  2287. X    } else if (ch < 4064) {
  2288. X        ch = 0x90 | 15 - (ch - 2016) / 128;
  2289. X    } else if (ch < 8160) {
  2290. X        ch = 0x80 | 15 - (ch - 4064) /    256;
  2291. X    } else {
  2292. X        ch = 0x80;
  2293. X    }
  2294. X
  2295. X    return (mask & ch);
  2296. X}
  2297. X
  2298. unsigned char cvttab[1<<14];
  2299. unsigned char *cvtvec = &cvttab[1<<13];
  2300. X
  2301. initcvt()
  2302. X{
  2303. X    int i;
  2304. X    for (i = -(1<<13); i < (1<<13); i++)
  2305. X        cvtvec[i] = cvt(i);
  2306. X}
  2307. END_OF_FILE
  2308. if test 4711 -ne `wc -c <'recordulaw.c'`; then
  2309.     echo shar: \"'recordulaw.c'\" unpacked with wrong size!
  2310. fi
  2311. # end of 'recordulaw.c'
  2312. fi
  2313. if test -f 'sndulaw.c' -a "${1}" != "-c" ; then 
  2314.   echo shar: Will not clobber existing file \"'sndulaw.c'\"
  2315. else
  2316. echo shar: Extracting \"'sndulaw.c'\" \(2972 characters\)
  2317. sed "s/^X//" >'sndulaw.c' <<'END_OF_FILE'
  2318. X/*
  2319. X * Author : Reimer A. Mellin
  2320. X * Date : 4.12.1991
  2321. X * no copyrights
  2322. X *
  2323. X *
  2324. X * ulaw: based on recordchaintest.c
  2325. X * it writes a endless stream of Sound to stdout until terminated or
  2326. X * interrupted.
  2327. X * sndrecord can't be used, since it can not write to stdout :-(
  2328. X */ 
  2329. X
  2330. X#import    <stdio.h>
  2331. X#import <signal.h>
  2332. X#import    <sound/sound.h>
  2333. X
  2334. X#define    NUM_BUFFERS    5
  2335. X#define    BUF_SIZE    8000
  2336. X
  2337. static SNDSoundStruct *buffers[NUM_BUFFERS];
  2338. static FILE *sfp;
  2339. X
  2340. static void record(int tag);
  2341. X
  2342. static int recordDone(SNDSoundStruct *s, int tag, int err)
  2343. X/*
  2344. X * Called when a buffer has been recorded.
  2345. X * Appends the buffer to the soundfile.
  2346. X */
  2347. X{
  2348. X    if (err)
  2349. X        fprintf(stderr, "recordDone: %s\n", SNDSoundError(err));
  2350. X    if (fwrite((void *)((char *)s + s->dataLocation), 1, s->dataSize, sfp) !=
  2351. X    s->dataSize)
  2352. X    fprintf(stderr, "recordDone: could not write data to soundfile\n");
  2353. X    return 0;
  2354. X}
  2355. X
  2356. static void record(int bufNum)
  2357. X/*
  2358. X * Initiates recording into a buffers[bufNum].
  2359. X */
  2360. X{
  2361. X    int err;
  2362. X    
  2363. X
  2364. X    if (err = SNDStartRecording(buffers[bufNum], bufNum+1, 0, 0, SND_NULL_FUN,
  2365. X                recordDone))
  2366. X        fprintf(stderr, "record: %s\n", SNDSoundError(err));
  2367. X}
  2368. X
  2369. static void init(int n, int size)
  2370. X/*
  2371. X * Allocate n sound buffers.
  2372. X * Creates the soundfile.
  2373. X */
  2374. X{
  2375. X    int i, err;
  2376. X    SNDSoundStruct s;
  2377. X
  2378. X    for (i = 0; i < n; i++)
  2379. X        if (err = SNDAlloc(&buffers[i], size, SND_FORMAT_MULAW_8,
  2380. X               SND_RATE_CODEC, 1, 4))
  2381. X        fprintf(stderr, "init: %s\n", SNDSoundError(err));
  2382. X
  2383. X    s.magic = SND_MAGIC;
  2384. X    s.dataLocation = sizeof(SNDSoundStruct);
  2385. X    s.dataSize = 0;
  2386. X    s.dataFormat = SND_FORMAT_MULAW_8;
  2387. X    s.samplingRate = SND_RATE_CODEC;
  2388. X    s.channelCount = 1;
  2389. X    (void)strcpy( s.info, "ram");
  2390. X    if (fwrite((void *)&s, sizeof(SNDSoundStruct), 1, sfp) != 1)
  2391. X    fprintf(stderr, "init: could not write dummy header to soundfile\n");
  2392. X}
  2393. X
  2394. static void cleanup(void)
  2395. X/*
  2396. X * Write the soundfile header.
  2397. X */
  2398. X{
  2399. X    SNDSoundStruct s;
  2400. X
  2401. X    s.magic = SND_MAGIC;
  2402. X    s.dataLocation = sizeof(SNDSoundStruct);
  2403. X    s.dataSize = 0;
  2404. X    s.dataFormat = SND_FORMAT_MULAW_8;
  2405. X    s.samplingRate = SND_RATE_CODEC;
  2406. X    s.channelCount = 1;
  2407. X    (void)strcpy( s.info, "ram");
  2408. X
  2409. X    if(!isatty(fileno(sfp))) {
  2410. X      rewind(sfp);
  2411. X      if (fwrite((void *)&s, sizeof(SNDSoundStruct), 1, sfp) != 1)
  2412. X    fprintf(stderr, "cleanup: could not write header to soundfile\n");
  2413. X    }
  2414. X    fflush(sfp);
  2415. X    exit(0);
  2416. X}
  2417. X
  2418. main(int argc, char *argv[])
  2419. X{
  2420. X    int i;
  2421. X
  2422. X    if( argc > 1 ) {
  2423. X      fprintf(stderr, "%s: Records sound from CODEC and writes it to stdout\n",
  2424. X          argv[0]);
  2425. X      exit(1);
  2426. X    }
  2427. X    sfp = stdout;
  2428. X    (void)signal( SIGTERM, (void *)cleanup);
  2429. X    (void)signal( SIGINT, (void *)cleanup);
  2430. X
  2431. X    /* prepare sound and start the first 5 recordings */
  2432. X    init(NUM_BUFFERS, BUF_SIZE);
  2433. X    for (i = 0; i < NUM_BUFFERS; i++) {
  2434. X      record(i);
  2435. X    }
  2436. X    for(;;){
  2437. X      /* As soon as the first is finished, restart it */
  2438. X      for (i = 0; i < NUM_BUFFERS; i++) {
  2439. X    SNDWait(i+1);
  2440. X    record(i);
  2441. X      }
  2442. X    }
  2443. X    cleanup();
  2444. X}
  2445. END_OF_FILE
  2446. if test 2972 -ne `wc -c <'sndulaw.c'`; then
  2447.     echo shar: \"'sndulaw.c'\" unpacked with wrong size!
  2448. fi
  2449. # end of 'sndulaw.c'
  2450. fi
  2451. if test -f 'socklib.c' -a "${1}" != "-c" ; then 
  2452.   echo shar: Will not clobber existing file \"'socklib.c'\"
  2453. else
  2454. echo shar: Extracting \"'socklib.c'\" \(3341 characters\)
  2455. sed "s/^X//" >'socklib.c' <<'END_OF_FILE'
  2456. X/***********************************************************
  2457. Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  2458. Netherlands.
  2459. X
  2460. X                        All Rights Reserved
  2461. X
  2462. Permission to use, copy, modify, and distribute this software and its 
  2463. documentation for any purpose and without fee is hereby granted, 
  2464. provided that the above copyright notice appear in all copies and that
  2465. both that copyright notice and this permission notice appear in 
  2466. supporting documentation, and that the names of Stichting Mathematisch
  2467. Centrum or CWI not be used in advertising or publicity pertaining to
  2468. distribution of the software without specific, written prior permission.
  2469. X
  2470. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2471. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2472. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2473. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2474. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2475. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2476. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2477. X
  2478. X******************************************************************/
  2479. X
  2480. X/* Socket-related subroutines shared by broadcast and radio */
  2481. X
  2482. X#include <stdio.h>
  2483. X#include <errno.h>
  2484. X#include <stdlib.h>
  2485. X#include <fcntl.h>
  2486. X#include <netdb.h>
  2487. X
  2488. X#include <sys/types.h>
  2489. X#include <sys/socket.h>
  2490. X#include <sys/time.h>
  2491. X#include <netinet/in.h>
  2492. X
  2493. int
  2494. opensock(sockdesc, localname, localport, remotename, remoteport, broadcast)
  2495. X    char *sockdesc;
  2496. X    char *localname;
  2497. X    int localport;
  2498. X    char *remotename;
  2499. X    int remoteport;
  2500. X    int broadcast;
  2501. X{
  2502. X    int s;
  2503. X    struct sockaddr_in sin;
  2504. X    char desc[512];
  2505. X
  2506. X    s = socket(AF_INET, SOCK_DGRAM, 0);
  2507. X    if (s < 0) {
  2508. X        sprintf(desc, "socket(%s)", sockdesc);
  2509. X        perror(desc);
  2510. X        exit(1);
  2511. X    }
  2512. X    memset((char *)&sin, '\0', sizeof(sin));
  2513. X    if(localname) {
  2514. X        setipaddr(localname, &sin);
  2515. X    }
  2516. X    else {
  2517. X        sin.sin_addr.s_addr = INADDR_ANY;
  2518. X        sin.sin_family = AF_INET;
  2519. X    }
  2520. X    sin.sin_port = htons(localport);
  2521. X
  2522. X#ifdef SO_REUSEPORT
  2523. X    if (!broadcast) {
  2524. X        int on = 1;
  2525. X        if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
  2526. X                &on, sizeof (on)) < 0) {
  2527. X            sprintf(desc,"setsockopt(%s, SO_REUSEPORT)", sockdesc);
  2528. X            perror(desc);
  2529. X            /* Don't exit -- this isn't fatal */
  2530. X        }
  2531. X    }
  2532. X#endif
  2533. X
  2534. X    if (bind(s, &sin, sizeof sin) < 0) {
  2535. X        sprintf(desc,"bind(%s)", sockdesc);
  2536. X        perror(desc);
  2537. X        exit(1);
  2538. X    }
  2539. X
  2540. X    if(remotename) {
  2541. X        memset((char *)&sin, '\0', sizeof(sin));
  2542. X        setipaddr(remotename, &sin);
  2543. X        sin.sin_port = htons(remoteport);
  2544. X
  2545. X        if (connect(s, &sin, sizeof sin) < 0) {
  2546. X            sprintf(desc, "connect(%s)", sockdesc);
  2547. X            perror(desc);
  2548. X            exit(1);
  2549. X        }
  2550. X    }
  2551. X
  2552. X    if(broadcast) {
  2553. X        int on = 1;
  2554. X        if (setsockopt(s, SOL_SOCKET, SO_BROADCAST,
  2555. X                &on, sizeof (on)) < 0) {
  2556. X            sprintf(desc,"setsockopt(%s, SO_BROADCAST)", sockdesc);
  2557. X            perror(desc);
  2558. X            exit(1);
  2559. X        }
  2560. X    }
  2561. X    return s;
  2562. X}
  2563. X
  2564. int
  2565. setipaddr(name, addr_ret)
  2566. X        char *name;
  2567. X        struct sockaddr_in *addr_ret;
  2568. X{
  2569. X        struct hostent *hp;
  2570. X
  2571. X        if((hp = gethostbyname(name)) == NULL) {
  2572. X                if((addr_ret->sin_addr.s_addr = inet_addr(name)) == -1) {
  2573. X                        return(-1);
  2574. X                }
  2575. X        }
  2576. X    else  {
  2577. X                memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
  2578. X        }
  2579. X        addr_ret->sin_family = AF_INET;
  2580. X        return 4;
  2581. X}
  2582. END_OF_FILE
  2583. if test 3341 -ne `wc -c <'socklib.c'`; then
  2584.     echo shar: \"'socklib.c'\" unpacked with wrong size!
  2585. fi
  2586. # end of 'socklib.c'
  2587. fi
  2588. if test -f 'stations.pl' -a "${1}" != "-c" ; then 
  2589.   echo shar: Will not clobber existing file \"'stations.pl'\"
  2590. else
  2591. echo shar: Extracting \"'stations.pl'\" \(854 characters\)
  2592. sed "s/^X//" >'stations.pl' <<'END_OF_FILE'
  2593. X#!/usr/bin/perl
  2594. X##
  2595. X## Find radio stations
  2596. X##
  2597. X## (A small subset of the functionality of stations.py for now)
  2598. X##
  2599. X## Written by;  Jeff Beadles  jeff@onion.rain.com
  2600. X##
  2601. X# this emulates #! processing on machines that don't support it.
  2602. eval "exec /usr/bin/perl -S $0 $*"
  2603. X    if $running_under_some_shell_and_not_perl;
  2604. X
  2605. require 'sys/socket.ph';
  2606. X
  2607. X($name, $aliases, $proto) = getprotobyname('udp');
  2608. X
  2609. X$this = pack('S n a4 x8' , &AF_INET, 54317, "\0\0\0\0");
  2610. X
  2611. socket(S, &AF_INET, &SOCK_DGRAM, $proto)  || die "socket: $!";
  2612. bind(S, $this)                            || die "bind:   $!";
  2613. X
  2614. while (1) {
  2615. X    recv(S, $buf, 1024, 0) || die "recv:  $!\n";
  2616. X    chop($buf);
  2617. X    ($t_radio,$t_s,$t_name,$t_port,$t_xmit,$t_log,$t_age) = split(/:/,$buf,7);
  2618. X    print "Bogus message '$buf'\n" if ($t_radio ne "radio");
  2619. X    print "Receiving station '$t_name' on port $t_port\n";
  2620. X}
  2621. END_OF_FILE
  2622. if test 854 -ne `wc -c <'stations.pl'`; then
  2623.     echo shar: \"'stations.pl'\" unpacked with wrong size!
  2624. fi
  2625. chmod +x 'stations.pl'
  2626. # end of 'stations.pl'
  2627. fi
  2628. if test -f 'stations.py' -a "${1}" != "-c" ; then 
  2629.   echo shar: Will not clobber existing file \"'stations.py'\"
  2630. else
  2631. echo shar: Extracting \"'stations.py'\" \(3128 characters\)
  2632. sed "s/^X//" >'stations.py' <<'END_OF_FILE'
  2633. X#! /usr/local/bin/python
  2634. X
  2635. X# /***********************************************************
  2636. X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  2637. X# Netherlands.
  2638. X# 
  2639. X#                         All Rights Reserved
  2640. X# 
  2641. X# Permission to use, copy, modify, and distribute this software and its 
  2642. X# documentation for any purpose and without fee is hereby granted, 
  2643. X# provided that the above copyright notice appear in all copies and that
  2644. X# both that copyright notice and this permission notice appear in 
  2645. X# supporting documentation, and that the names of Stichting Mathematisch
  2646. X# Centrum or CWI not be used in advertising or publicity pertaining to
  2647. X# distribution of the software without specific, written prior permission.
  2648. X# 
  2649. X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2650. X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2651. X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2652. X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2653. X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2654. X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2655. X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2656. X# 
  2657. X# ******************************************************************/
  2658. X
  2659. X# Print station call packets received from broadcast programs around the net.
  2660. X
  2661. import time
  2662. import string
  2663. import os
  2664. from stat import *
  2665. from socket import *
  2666. X##from SOCKET import *
  2667. X
  2668. INFOPORT = 54317
  2669. BCASTCTLPORT = 54319
  2670. X
  2671. def main():
  2672. X    s = socket(AF_INET, SOCK_DGRAM)
  2673. X##    s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) # Python 0.9.7 or higher
  2674. X    s.allowbroadcast(1) # Python 0.9.6
  2675. X    s.bind('', INFOPORT)
  2676. X    s.sendto('radio:s', ('<broadcast>', BCASTCTLPORT))
  2677. X    while 1:
  2678. X        data, sender = s.recvfrom(100)
  2679. X        if data[:7] == 'radio:S':
  2680. X            name, prt, tr, log, age, prg = decodeinfo(data)
  2681. X            print name+':', prg,
  2682. X            if age >= 0: print '(' + formatage(age) + ')',
  2683. X            print
  2684. X        elif data[:6] == 'radio:':
  2685. X            print 'bad control packet:', `data`
  2686. X        else:
  2687. X            print 'bad packet received'
  2688. X
  2689. X
  2690. def formatage(age):
  2691. X    if age < 60: return `age` + ' sec'
  2692. X    if age < 3600: return `age/60` + ' min'
  2693. X    if age < 24*3600: return `age/3600` + ' hrs'
  2694. X    return `age/(24*3600)` + ' days'
  2695. X
  2696. def decodeinfo(data):
  2697. X    fields = string.splitfields(data, ':')
  2698. X    name = fields[2]
  2699. X    port = eval(fields[3])
  2700. X    if fields[4:]:
  2701. X        transmitting = eval(fields[4])
  2702. X        logfile = fields[5]
  2703. X        age = eval(fields[6])
  2704. X        contents = string.joinfields(fields[7:], ':')
  2705. X    else:
  2706. X        transmitting = -1
  2707. X        programfile = '/ufs/' + name + '/CD'
  2708. X        logfile = programfile + 'log'
  2709. X        age = getage(programfile)
  2710. X        if age == None:
  2711. X            age = -1
  2712. X        contents = getcontents(programfile)
  2713. X        if contents == None:
  2714. X            contents = '???'
  2715. X    return name, port, transmitting, logfile, age, contents
  2716. X    return None
  2717. X
  2718. def getcontents(filename):
  2719. X    try:
  2720. X        f = open(filename, 'r')
  2721. X    except IOError:
  2722. X        return None
  2723. X    res = f.readline()
  2724. X    f.close()
  2725. X    return string.strip(res)
  2726. X
  2727. def getage(filename):
  2728. X    try:
  2729. X        st = os.stat(filename)
  2730. X    except os.error:
  2731. X        return None
  2732. X    return time.time() - st[ST_MTIME]
  2733. X
  2734. X
  2735. try:
  2736. X    main()
  2737. except KeyboardInterrupt:
  2738. X    print
  2739. X    print '[Interrupt]'
  2740. END_OF_FILE
  2741. if test 3128 -ne `wc -c <'stations.py'`; then
  2742.     echo shar: \"'stations.py'\" unpacked with wrong size!
  2743. fi
  2744. # end of 'stations.py'
  2745. fi
  2746. if test -f 'ttytuner.py' -a "${1}" != "-c" ; then 
  2747.   echo shar: Will not clobber existing file \"'ttytuner.py'\"
  2748. else
  2749. echo shar: Extracting \"'ttytuner.py'\" \(7530 characters\)
  2750. sed "s/^X//" >'ttytuner.py' <<'END_OF_FILE'
  2751. X#!/usr/local/bin/python
  2752. X
  2753. X# /***********************************************************
  2754. X# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  2755. X# Netherlands.
  2756. X# 
  2757. X#                         All Rights Reserved
  2758. X# 
  2759. X# Permission to use, copy, modify, and distribute this software and its 
  2760. X# documentation for any purpose and without fee is hereby granted, 
  2761. X# provided that the above copyright notice appear in all copies and that
  2762. X# both that copyright notice and this permission notice appear in 
  2763. X# supporting documentation, and that the names of Stichting Mathematisch
  2764. X# Centrum or CWI not be used in advertising or publicity pertaining to
  2765. X# distribution of the software without specific, written prior permission.
  2766. X# 
  2767. X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2768. X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2769. X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2770. X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2771. X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2772. X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2773. X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2774. X# 
  2775. X# ******************************************************************/
  2776. X
  2777. X# A tuner to control radio programs, by Jack Jansen.
  2778. X
  2779. import sys
  2780. import os
  2781. import time
  2782. import socket
  2783. import time
  2784. import string
  2785. import getopt
  2786. from stat import ST_MTIME
  2787. X
  2788. X
  2789. RADIOCTLPORT=54320
  2790. TRANSMITTERCTLPORT=54319
  2791. CTLWS=socket.gethostname()
  2792. X
  2793. X# The list of networks to broadcast on, when looking for radio
  2794. X# stations. This should somehow be gotten differently.
  2795. X#
  2796. MCASTLIST = ['192.16.184.0', '192.16.191.0', '192.16.201.255']
  2797. X# MCASTLIST = ['192.16.201.255']
  2798. X
  2799. class struct(): pass
  2800. info = struct()
  2801. X
  2802. X#
  2803. X# sendsock - send a message (and get optional reply)
  2804. X#
  2805. def sendsock(host, port, msg, needrepl):
  2806. X    try:
  2807. X    host = socket.gethostbyname(host)
  2808. X    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  2809. X    s.sendto(msg, (host,port))
  2810. X    if needrepl:
  2811. X        # Loop for max. 2.5 seconds waiting for a reply
  2812. X        i = 0
  2813. X        while i < 5 and not s.avail():
  2814. X        time.millisleep(500)
  2815. X        i = i + 1
  2816. X        if not s.avail():
  2817. X        print 'Radio program not responding'
  2818. X        return ''
  2819. X        return s.recv(500)
  2820. X    except socket.error:
  2821. X    print 'Incorrect radio settings'
  2822. X    if needrepl:
  2823. X        return ''
  2824. X    else:
  2825. X        return
  2826. X#
  2827. X# sendmulti - send a multicast message (and get replies)
  2828. X#
  2829. def sendmulti(mcastlist, port, msg):
  2830. X    rv = []
  2831. X    try:
  2832. X    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  2833. X    s.allowbroadcast(1)
  2834. X    for host in mcastlist:
  2835. X        s.sendto(msg, (host,port))
  2836. X    # Loop for max. 2.5 seconds waiting for a reply
  2837. X    i = 0
  2838. X    while i < 25:
  2839. X        time.millisleep(100)
  2840. X        i = i + 1
  2841. X        if s.avail():
  2842. X        rv.append(s.recv(500))
  2843. X    except socket.error:
  2844. X    print 'Incorrect mcast settings'
  2845. X    return rv
  2846. X#
  2847. X# getstationinfo - Return playlist, current and playing time (in minutes).
  2848. X# Returns a triple (playlist-filename, current record, playing time)
  2849. X#
  2850. def getstationinfo(info):
  2851. X    name = info[0]
  2852. X    if len(info) > 3:
  2853. X    playlist = info[3]
  2854. X    else:
  2855. X    playlist = '/ufs/' + name + '/CDlog'
  2856. X    if len(info) > 5:
  2857. X    since = eval(info[4])
  2858. X    cur = string.joinfields(info[5:], ':')
  2859. X    else:
  2860. X    curfn = '/ufs/' + name + '/CD'
  2861. X    try:
  2862. X        curf = open(curfn,'r')
  2863. X        cur = curf.readline()
  2864. X        curf.close()
  2865. X    except IOError:
  2866. X        cur = '???'
  2867. X    if cur[-1:] == '\n':
  2868. X        cur = cur[:-1]
  2869. X    try:
  2870. X        sb = os.stat(curfn)
  2871. X        since = time.time() - sb[ST_MTIME]
  2872. X    except os.error:
  2873. X        since = -1
  2874. X    if since >= 0: since = since / 60 # Convert to minutes
  2875. X    if since < 0:
  2876. X    str = '??'
  2877. X    elif since < 60:
  2878. X    str = `since` + ' mins'
  2879. X    else:
  2880. X    since = since / 60
  2881. X    if since < 24:
  2882. X        str = `since` + ' hrs'
  2883. X    else:
  2884. X        str = `since / 24` + ' days'
  2885. X    return playlist, cur, str
  2886. X
  2887. X#
  2888. X# updateinfo - Update one of the views with info on station 'name'
  2889. X#
  2890. def printinfo(info):
  2891. X    name = info[0]
  2892. X    print 'Station '+ name + ':'
  2893. X    print '\tPort               ' + `info[1]`
  2894. X    if name == '' or name[:3] == '???':
  2895. X    print '\tNo information on station'
  2896. X    else:
  2897. X    try:
  2898. X        p, c, t = getstationinfo(info)
  2899. X    except IOError:
  2900. X        return
  2901. X    if c <> '' and c <> '???':
  2902. X        print '\tCurrently playing: ' + c
  2903. X    if t <> '??':
  2904. X        print '\tSince:             ' + t
  2905. X    if p <> '':
  2906. X        print '\tPlaylist in file:  ' + p
  2907. X
  2908. X#
  2909. X# getstations - Return an array of (stationname, stationport)
  2910. X# listing all available stations.
  2911. X#
  2912. def getstations():
  2913. X    stations = []
  2914. X    raw = sendmulti(MCASTLIST, TRANSMITTERCTLPORT, 'radio:s')
  2915. X    for i in raw:
  2916. X    if i[:7] == 'radio:S':
  2917. X        fields = string.splitfields(i,':')[2:]
  2918. X        fields[1] = string.atoi(fields[1])
  2919. X        stations.append(fields)
  2920. X    else:
  2921. X        print 'Funny reply from transmitter:', i[:7]
  2922. X    return stations
  2923. X
  2924. X#
  2925. X# getcurstation - Return (name,port) for station to which radio
  2926. X# on workstation ws is currently tuned to.
  2927. X#
  2928. def getcurstation(stationlist, ws, port):
  2929. X    rv = sendsock(ws, port, 'radio:i', 1)
  2930. X    if rv == '':
  2931. X    return ('',0)
  2932. X    if rv[0:8] <> 'radio:I:':
  2933. X    print 'Illegal reply from radio:',rv
  2934. X    return ('',0)
  2935. X    # Remove optional pause field
  2936. X    rv = rv[8:]
  2937. X    rv = string.splitfields(rv,':')
  2938. X    if len(rv) == 1:            # Old: port
  2939. X    tport = string.atoi(rv[0])
  2940. X    playing = 1
  2941. X    elif len(rv) == 2:            # newer: playing, port
  2942. X    tport = string.atoi(rv[1])
  2943. X    playing = string.atoi(rv[0])
  2944. X    elif len(rv) == 3:            # Still newer: playing, port, version
  2945. X    tport = string.atoi(rv[1])
  2946. X    playing = string.atoi(rv[0])
  2947. X    else:                # Too new
  2948. X    print 'Unknown reply to info: ', rv
  2949. X    for i in stationlist:
  2950. X    if i[1] == tport:
  2951. X        return (i, playing)
  2952. X    return (('???(port '+`tport`+')' ,tport), playing)
  2953. X
  2954. def main():
  2955. X    radio_port = RADIOCTLPORT
  2956. X    radio_ws = CTLWS
  2957. X    try:
  2958. X    optlist, args = getopt.getopt(sys.argv[1:], 'w:p:lLcPCT')
  2959. X    mode = ''
  2960. X    for o, a in optlist:
  2961. X        if o == '-w':
  2962. X        radio_ws = a
  2963. X        elif o == '-p':
  2964. X        radio_port = string.atoi(a)
  2965. X        elif mode == '':
  2966. X        mode = o[1]
  2967. X        else:
  2968. X        raise getopt.error
  2969. X    if len(args) + len(mode) <> 1:
  2970. X        raise getopt.error
  2971. X    except getopt.error:
  2972. X    print 'Usage: '+sys.argv[0]+' [options] command'
  2973. X    print 'Options:'
  2974. X    print '\t-w ws\tControl radio on workstation ws'
  2975. X    print '\t-p port\tControl radio on port port'
  2976. X    print 'Command:'
  2977. X    print '\t-l\tList names of active stations'
  2978. X    print '\t-L\tList names and info of active stations'
  2979. X    print '\t-c\tList info on current station'
  2980. X    print '\t-P\tTemporarily suspend radio, freeing port'
  2981. X    print '\t-C\tContinue radio'
  2982. X    print '\t-T\tToggle suspend/continue'
  2983. X    print '\tstation\tTune to new station'
  2984. X    sys.exit(1)
  2985. X    
  2986. X    #
  2987. X    # First, do pause/continue command.
  2988. X    #
  2989. X    if mode == 'P':
  2990. X    sendsock(radio_ws, radio_port, 'radio:0', 0)
  2991. X    sys.exit(0)
  2992. X    if mode == 'C':
  2993. X    sendsock(radio_ws, radio_port, 'radio:1', 0)
  2994. X    sys.exit(0)
  2995. X    if mode == 'T':
  2996. X    cn, playing = getcurstation([], radio_ws, radio_port)
  2997. X    sendsock(radio_ws, radio_port, 'radio:'+`not playing`, 0)
  2998. X    sys.exit(0)
  2999. X    #
  3000. X    # And list of new stations
  3001. X    #
  3002. X    stations = getstations()
  3003. X    #
  3004. X    # Set info for current station
  3005. X    #
  3006. X    if mode == '' or mode == 'c':
  3007. X    cn, playing = getcurstation(stations,radio_ws, radio_port)
  3008. X    if mode == 'l':
  3009. X    for i in stations:
  3010. X        print i[0]
  3011. X    elif mode == 'L':
  3012. X    for i in stations:
  3013. X        printinfo(i)
  3014. X    elif mode == 'c':
  3015. X    printinfo(cn)
  3016. X    else:
  3017. X    for i in range(len(stations)):
  3018. X        if stations[i][0] == args[0]:
  3019. X        sendsock(radio_ws, radio_port, \
  3020. X                'radio:t:' + `stations[i][1]`, 0)
  3021. X        sys.exit(0)
  3022. X    print 'No such station: ', args[0]
  3023. X    
  3024. X    
  3025. X
  3026. main()
  3027. X
  3028. X# Local variables:
  3029. X# py-indent-offset: 4
  3030. X# end:
  3031. END_OF_FILE
  3032. if test 7530 -ne `wc -c <'ttytuner.py'`; then
  3033.     echo shar: \"'ttytuner.py'\" unpacked with wrong size!
  3034. fi
  3035. chmod +x 'ttytuner.py'
  3036. # end of 'ttytuner.py'
  3037. fi
  3038. if test -f 'ulawadpcm.c' -a "${1}" != "-c" ; then 
  3039.   echo shar: Will not clobber existing file \"'ulawadpcm.c'\"
  3040. else
  3041. echo shar: Extracting \"'ulawadpcm.c'\" \(7209 characters\)
  3042. sed "s/^X//" >'ulawadpcm.c' <<'END_OF_FILE'
  3043. X/***********************************************************
  3044. Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  3045. Netherlands.
  3046. X
  3047. X                        All Rights Reserved
  3048. X
  3049. Permission to use, copy, modify, and distribute this software and its 
  3050. documentation for any purpose and without fee is hereby granted, 
  3051. provided that the above copyright notice appear in all copies and that
  3052. both that copyright notice and this permission notice appear in 
  3053. supporting documentation, and that the names of Stichting Mathematisch
  3054. Centrum or CWI not be used in advertising or publicity pertaining to
  3055. distribution of the software without specific, written prior permission.
  3056. X
  3057. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  3058. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  3059. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  3060. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  3061. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  3062. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  3063. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  3064. X
  3065. X******************************************************************/
  3066. X
  3067. X/*
  3068. X** Intel/DVI ADPCM coder/decoder.
  3069. X**
  3070. X** The algorithm for this coder was taken from the IMA Compatability Project
  3071. X** proceedings, Vol 2, Number 2; May 1992.
  3072. X**
  3073. X** Version 1.1, 16-Dec-92.
  3074. X**
  3075. X** Change log:
  3076. X** - Fixed a stupid bug, where the delta was computed as
  3077. X**   stepsize*code/4 in stead of stepsize*(code+0.5)/4. The old behavior can
  3078. X**   still be gotten by defining STUPID_V1_BUG.
  3079. X*/
  3080. X
  3081. X#include "adpcm.h"
  3082. X#include "libst.h"
  3083. X
  3084. X#ifndef __STDC__
  3085. X#define signed
  3086. X#endif
  3087. X
  3088. X/* Intel ADPCM step variation table */
  3089. static int indexTable[16] = {
  3090. X    -1, -1, -1, -1, 2, 4, 6, 8,
  3091. X    -1, -1, -1, -1, 2, 4, 6, 8,
  3092. X};
  3093. X
  3094. static int stepsizeTable[89] = {
  3095. X    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  3096. X    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  3097. X    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  3098. X    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  3099. X    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  3100. X    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  3101. X    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  3102. X    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  3103. X    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  3104. X};
  3105. X    
  3106. void
  3107. ulaw_adpcm_coder(indata, outdata, len, state)
  3108. X    char indata[];
  3109. X    char outdata[];
  3110. X    int len;
  3111. X    struct adpcm_state *state;
  3112. X{
  3113. X    unsigned char *inp;        /* Input buffer pointer */
  3114. X    signed char *outp;        /* output buffer pointer */
  3115. X    /* XXX why must outp be signed? */
  3116. X    int val;            /* Current input sample value */
  3117. X    int sign;            /* Current adpcm sign bit */
  3118. X    int delta;            /* Current adpcm output value */
  3119. X    int step;            /* Stepsize */
  3120. X    int valprev;        /* virtual previous output value */
  3121. X    int vpdiff;            /* Current change to valprev */
  3122. X    int index;            /* Current step change index */
  3123. X    int outputbuffer;        /* place to keep previous 4-bit value */
  3124. X    int bufferstep;        /* toggle between outputbuffer/output */
  3125. X
  3126. X    outp = (signed char *)outdata;
  3127. X    inp = (unsigned char *)indata;
  3128. X
  3129. X    if (state) {
  3130. X    valprev = state->valprev;
  3131. X    index = state->index;
  3132. X    }
  3133. X    else {
  3134. X    valprev = 0;
  3135. X    index = 0;
  3136. X    }
  3137. X    step = stepsizeTable[index];
  3138. X    
  3139. X    bufferstep = 1;
  3140. X
  3141. X    for ( ; len > 0 ; len-- ) {
  3142. X    val = st_ulaw_to_linear(*inp++);
  3143. X
  3144. X    /* Step 1 - compute difference with previous value */
  3145. X    delta = val - valprev;
  3146. X    sign = (delta < 0) ? 8 : 0;
  3147. X    if ( sign ) delta = (-delta);
  3148. X
  3149. X    /* Step 2 - Divide and clamp */
  3150. X#ifdef NODIVMUL
  3151. X        {
  3152. X        int tmp = 0;
  3153. X#ifdef STUPID_V1_BUG
  3154. X        vpdiff = 0;
  3155. X#else
  3156. X        vpdiff = (step >> 3);
  3157. X#endif /* STUPID_V1_BUG */
  3158. X        if ( delta > step ) {
  3159. X        tmp = 4;
  3160. X        delta -= step;
  3161. X        vpdiff += step;
  3162. X        }
  3163. X        step >>= 1;
  3164. X        if ( delta > step  ) {
  3165. X        tmp |= 2;
  3166. X        delta -= step;
  3167. X        vpdiff += step;
  3168. X        }
  3169. X        step >>= 1;
  3170. X        if ( delta > step ) {
  3171. X        tmp |= 1;
  3172. X        vpdiff += step;
  3173. X        }
  3174. X        delta = tmp;
  3175. X    }
  3176. X#else
  3177. X    delta = (delta<<2) / step;
  3178. X    if ( delta > 7 ) delta = 7;
  3179. X
  3180. X#ifdef STUPID_V1_BUG
  3181. X    vpdiff = (delta*step) >> 2;
  3182. X#else
  3183. X    vpdiff = ((delta*step) >> 2) + (step >> 3);
  3184. X#endif /* STUPID_V1_BUG */
  3185. X#endif /* NODIVMUL */
  3186. X      
  3187. X    /* Step 3 - Update previous value */
  3188. X    if ( sign )
  3189. X      valprev -= vpdiff;
  3190. X    else
  3191. X      valprev += vpdiff;
  3192. X
  3193. X    /* Step 4 - Clamp previous value to 16 bits */
  3194. X    if ( valprev > 32767 )
  3195. X      valprev = 32767;
  3196. X    else if ( valprev < -32768 )
  3197. X      valprev = -32768;
  3198. X
  3199. X    /* Step 5 - Assemble value, update index and step values */
  3200. X    delta |= sign;
  3201. X    
  3202. X    index += indexTable[delta];
  3203. X    if ( index < 0 ) index = 0;
  3204. X    if ( index > 88 ) index = 88;
  3205. X    step = stepsizeTable[index];
  3206. X
  3207. X    /* Step 6 - Output value */
  3208. X    if ( bufferstep ) {
  3209. X        outputbuffer = (delta << 4) & 0xf0;
  3210. X    } else {
  3211. X        *outp++ = (delta & 0x0f) | outputbuffer;
  3212. X    }
  3213. X    bufferstep = !bufferstep;
  3214. X    }
  3215. X
  3216. X    /* Output last step, if needed */
  3217. X    if ( !bufferstep )
  3218. X      *outp++ = outputbuffer;
  3219. X
  3220. X    if (state) {
  3221. X    state->valprev = valprev;
  3222. X    state->index = index;
  3223. X    }
  3224. X}
  3225. X
  3226. void
  3227. adpcm_ulaw_decoder(indata, outdata, len, state)
  3228. X    char indata[];
  3229. X    char outdata[];
  3230. X    int len;
  3231. X    struct adpcm_state *state;
  3232. X{
  3233. X    signed char *inp;        /* Input buffer pointer */
  3234. X    char *outp;            /* output buffer pointer */
  3235. X    int sign;            /* Current adpcm sign bit */
  3236. X    int delta;            /* Current adpcm output value */
  3237. X    int step;            /* Stepsize */
  3238. X    int valprev;        /* virtual previous output value */
  3239. X    int vpdiff;            /* Current change to valprev */
  3240. X    int index;            /* Current step change index */
  3241. X    int inputbuffer;        /* place to keep next 4-bit value */
  3242. X    int bufferstep;        /* toggle between inputbuffer/input */
  3243. X
  3244. X    outp = outdata;
  3245. X    inp = (signed char *)indata;
  3246. X
  3247. X    if (state) {
  3248. X    valprev = state->valprev;
  3249. X    index = state->index;
  3250. X    }
  3251. X    else {
  3252. X    valprev = 0;
  3253. X    index = 0;
  3254. X    }
  3255. X    step = stepsizeTable[index];
  3256. X
  3257. X    bufferstep = 0;
  3258. X    
  3259. X    for ( ; len > 0 ; len-- ) {
  3260. X    
  3261. X    /* Step 1 - get the delta value and compute next index */
  3262. X    if ( bufferstep ) {
  3263. X        delta = inputbuffer & 0xf;
  3264. X    } else {
  3265. X        inputbuffer = *inp++;
  3266. X        delta = (inputbuffer >> 4) & 0xf;
  3267. X    }
  3268. X    bufferstep = !bufferstep;
  3269. X
  3270. X    /* Step 2 - Find new index value (for later) */
  3271. X    index += indexTable[delta];
  3272. X    if ( index < 0 ) index = 0;
  3273. X    if ( index > 88 ) index = 88;
  3274. X
  3275. X    /* Step 3 - Separate sign and magnitude */
  3276. X    sign = delta & 8;
  3277. X    delta = delta & 7;
  3278. X
  3279. X    /* Step 4 - update output value */
  3280. X#ifdef NODIVMUL
  3281. X#ifdef STUPID_V1_BUG
  3282. X    vpdiff = 0;
  3283. X#else
  3284. X    vpdiff = step >> 1;
  3285. X#endif /* STUPID_V1_BUG */
  3286. X    if ( delta & 4 ) vpdiff += (step << 2);
  3287. X    if ( delta & 2 ) vpdiff += (step << 1);
  3288. X    if ( delta & 1 ) vpdiff += step;
  3289. X    vpdiff >>= 2;
  3290. X#else
  3291. X#ifdef STUPID_V1_BUG
  3292. X    vpdiff = ((delta*step) >> 2);
  3293. X#else
  3294. X    vpdiff = ((delta*step) >> 2) + (step >> 3);
  3295. X#endif /* STUPID_V1_BUG */
  3296. X#endif /* ! NODIVMUL */
  3297. X    if ( sign )
  3298. X      valprev -= vpdiff;
  3299. X    else
  3300. X      valprev += vpdiff;
  3301. X
  3302. X    /* Step 5 - clamp output value */
  3303. X    if ( valprev > 32767 )
  3304. X      valprev = 32767;
  3305. X    else if ( valprev < -32768 )
  3306. X      valprev = -32768;
  3307. X
  3308. X    /* Step 6 - Update step value */
  3309. X    step = stepsizeTable[index];
  3310. X
  3311. X    /* Step 7 - Output value */
  3312. X    *outp++ = st_linear_to_ulaw(valprev);
  3313. X    }
  3314. X
  3315. X    if (state) {
  3316. X    state->valprev = valprev;
  3317. X    state->index = index;
  3318. X    }
  3319. X}
  3320. END_OF_FILE
  3321. if test 7209 -ne `wc -c <'ulawadpcm.c'`; then
  3322.     echo shar: \"'ulawadpcm.c'\" unpacked with wrong size!
  3323. fi
  3324. # end of 'ulawadpcm.c'
  3325. fi
  3326. echo shar: End of archive 1 \(of 2\).
  3327. cp /dev/null ark1isdone
  3328. MISSING=""
  3329. for I in 1 2 ; do
  3330.     if test ! -f ark${I}isdone ; then
  3331.     MISSING="${MISSING} ${I}"
  3332.     fi
  3333. done
  3334. if test "${MISSING}" = "" ; then
  3335.     echo You have unpacked both archives.
  3336.     rm -f ark[1-9]isdone
  3337. else
  3338.     echo You still need to unpack the following archives:
  3339.     echo "        " ${MISSING}
  3340. fi
  3341. ##  End of shell archive.
  3342. exit 0
  3343.