home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: Sjoerd.Mullender@cwi.nl (Sjoerd Mullender)
- Subject: v26i165: cdsend - read music CD's via SCSI, convert and play [SGI], Part01/01
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: Sjoerd.Mullender@cwi.nl (Sjoerd Mullender)
- Posting-Number: Volume 26, Issue 165
- Archive-Name: cdsend1.2/part01
-
- Cdsend reads audio CD's over the SCSI bus, converts the data to a format
- suitable for broadcast, and writes this converted data to standard output.
- Optionally, the music is also played over the system's own speakers.
-
- Cdsend only works on certain Silicon Graphics systems. It was developed on
- an Iris Indigo.
-
- The db_get_*.c files were grabbed off the net and were written by people at
- SGI.
-
- The code in the file convert.c was taken from sox and adapted to incorporate
- it into cdsend.
-
- Sjoerd Mullender, CWI, Amsterdam (email: Sjoerd.Mullender@cwi.nl).
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: MANIFEST Makefile README cdsend.1 cdsend.c cdsend.h
- # convert.c db_get_TOC.c db_get_id.c
- # Wrapped by vixie@gw.home.vix.com on Thu Apr 15 18:45:22 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(393 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 1
- X README 1
- X cdsend.1 1
- X cdsend.c 1
- X cdsend.h 1
- X convert.c 1
- X db_get_TOC.c 1
- X db_get_id.c 1
- END_OF_FILE
- if test 393 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(301 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- CFLAGS = -O
- X
- all: cdsend
- X
- cdsend: cdsend.o convert.o libcddb.a
- X $(CC) -o cdsend cdsend.o convert.o libcddb.a -lcdaudio -lds -laudio -lc_s
- X
- clean:
- X -rm -f cdsend *.o *~ core
- X
- cdsend.o convert.o: cdsend.h
- X
- libcddb.a: db_get_TOC.o db_get_id.o
- X rm -f libcddb.a
- X ar cr libcddb.a db_get_TOC.o db_get_id.o
- END_OF_FILE
- if test 301 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(563 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- Cdsend reads audio CD's over the SCSI bus, converts the data to a
- format suitable for broadcast, and writes this converted data to
- standard output. Optionally, the music is also played over the
- system's own speakers.
- X
- Cdsend only works on certain Silicon Graphics systems. It was
- developed on an Iris Indigo.
- X
- The db_get_*.c files were grabbed off the net and were written by
- people at SGI.
- X
- The code in the file convert.c was taken from sox and adapted to
- incorporate it into cdsend.
- X
- Author: Sjoerd Mullender, CWI, Amsterdam (email: Sjoerd.Mullender@cwi.nl).
- END_OF_FILE
- if test 563 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'cdsend.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cdsend.1'\"
- else
- echo shar: Extracting \"'cdsend.1'\" \(2845 characters\)
- sed "s/^X//" >'cdsend.1' <<'END_OF_FILE'
- X.TH CDSEND 1 sgi
- X.SH NAME
- cdsend \- read an audio CD and convert
- X.SH SYNOPSIS
- X.B cdsend
- X[
- X.B \-c
- X.I catalogfile
- X] [
- X.B \-n
- X] [
- X.B \-d
- X] [
- X.B \-p
- X] [
- X.B \-l
- X]
- X.SH DESCRIPTION
- X.I Cdsend
- reads audio CD's through the SCSI bus and converts the data to one of
- several formats. The formats are 8kHz, mono, U-law (1 byte per
- sample), and 8kHz, mono, linear (2 bytes per sample). The default is
- to convert to U-law. Linear can be chosen by using the
- X.B \-l
- option.
- X.PP
- When a CD has been read completely, it is automatically ejected from
- the drive. When in daemon mode,
- X.I cdsend
- will then wait for a new CD to be inserted. If a CD that is not an
- audio CD is inserted, it is ignored. This means that
- X.I cdsend
- does not have to be killed when the CD-ROM drive has to be used for
- software installations. Daemon mode is selected by using the
- X.B \-d
- flag.
- X.PP
- Optionally,
- X.I cdsend
- will play the unconverted sound through the audio interface. This can
- be enabled using the
- X.B \-p
- option or by sending a SIGHUP to
- X.IR cdsend .
- X.PP
- X.I Cdsend
- writes information that identifies the CD being read to a file. The
- name of the file is $HOME/.CDcatalognumber, unless another file is
- specified using the
- X.B \-c
- flag. The information written consists of three lines. All lines are
- of the form
- X.IR identifier=value .
- The first line is the result of a hash function on the CD's table of
- contents. This is the same value that is used by
- X.IR cdman (1)
- to generate a file name for the title of the CD. The second line is
- the table of contents. The table of contents is encoded in the way
- that
- X.IR cdplayer (1)
- and
- X.IR cdman (1)
- use. The third line is either the catalog number on the CD (if
- present) or the total playing time of the CD in the format
- X.IR tracks.minutes.seconds.frames .
- X.PP
- When the
- X.B \-n
- flag is present,
- X.I cdsend
- will run with a non-degrading priority. The priority chosen is
- NDPNORMMAX, which is the lowest non-degrading priority higher than the
- normal user priorities. This option will only have an effect if
- X.I cdsend
- is installed set-uid root.
- X.PP
- When playing,
- X.I cdsend
- can still be influenced. This is done by sending certain signals to
- the process. The following signals are accepted.
- X.TP
- X.B SIGHUP
- Toggle between playing and not playing through the system's audio interface.
- X.TP
- X.B SIGUSR1
- Stop playing the current CD and eject it.
- X.PP
- When
- X.I cdsend
- stops playing, whether it is because the CD has finished ot because it
- was sent a SIGHUP, it sets the sampling rate of the audio interface
- back.
- X.PP
- Typically,
- X.I cdsend
- is started as follows:
- X.IP
- cdsend -dnpl | broadcast -l -a -b <broadcast address> &
- X.PP
- With older broadcast programs you may need to use the following:
- X.IP
- cdsend -dnp | broadcast -b <broadcast address> &
- X.SH SEE ALSO
- X.IR schedctl (2),
- X.IR apanel (1),
- X.IR cdman (1),
- X.IR cdplayer (1),
- X.IR broadcast (1).
- END_OF_FILE
- if test 2845 -ne `wc -c <'cdsend.1'`; then
- echo shar: \"'cdsend.1'\" unpacked with wrong size!
- fi
- # end of 'cdsend.1'
- fi
- if test -f 'cdsend.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cdsend.c'\"
- else
- echo shar: Extracting \"'cdsend.c'\" \(8872 characters\)
- sed "s/^X//" >'cdsend.c' <<'END_OF_FILE'
- X/***********************************************************
- Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
- Netherlands.
- X
- X All Rights Reserved
- X
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
- X
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X
- X******************************************************************/
- X
- X/* $Id: cdsend.c,v 1.2 1993/01/18 10:02:47 sjoerd Exp $ */
- X
- X/*
- X * cdsend reads audio CD's over the SCSI bus, converts it to a format
- X * suitable for broadcast, and writes this converted data to standard
- X * output. Optionally, the msuic is also played over the system's own
- X * speakers.
- X *
- X * Options.
- X * -n use non-degradable priority for the program (works
- X * only if installed set-uid root). The default is to
- X * not change the priority.
- X * -d daemon mode. When a CD finishes, hang around until
- X * the next CD is put in the CD player and play it. The
- X * default is to exit after playing one CD.
- X * -p play the music over the system's speakers. Default is
- X * to not play the music.
- X * -l convert the data to 2-byte-per-sample linear format.
- X * Default is to convert to 1-byte-per-sample U-law.
- X * -c file use the specified file to write the CD's
- X * identification to. Default is to write to the file
- X * $HOME/.CDcatalognumber.
- X */
- X
- X#include "cdsend.h"
- X#include <unistd.h>
- X#include <stdlib.h>
- X#include <stdarg.h>
- X#include <stdio.h>
- X#include <signal.h>
- X#include <limits.h>
- X#include <sys/prctl.h>
- X#include <sys/schedctl.h>
- X#include <audio.h>
- X#include <fcntl.h>
- X
- static ALport port; /* audio output port */
- static int playaudio; /* 1 iff we changed output rate */
- static volatile int silent = 1; /* 1 iff we must be quiet */
- static volatile int stop_playing; /* 1 if we must stop playing */
- static int linear = 0; /* 1 iff we produce linear (2-byte) output */
- static long oldparams[2] = {AL_OUTPUT_RATE, 0};
- static long newparams[2] = {AL_OUTPUT_RATE, AL_RATE_44100};
- static char *cdtoc, *cdid;
- static char cdcatnamebuf[1024];
- static char *cdcatname = cdcatnamebuf;
- extern char *db_get_TOC(CDPLAYER *, CDSTATUS *);
- extern char *db_get_id(CDPLAYER *, CDSTATUS *);
- extern char *optarg;
- X
- X/* newer libraries use CDaddcallback and have a backward compatibility */
- X/* define for CDsetcallback, we do it the other way round */
- X#ifndef CDsetcallback
- X#define CDaddcallback CDsetcallback
- X#endif
- X
- X#define DEFCDCATNAME ".CDcatalognumber"
- X
- X/*
- X * Called when the program is interrupted. This means that the audio
- X * params have to be reset, but only if we've changed them.
- X */
- static void
- die(int sig)
- X{
- X if (playaudio)
- X ALsetparams(AL_DEFAULT_DEVICE, oldparams, 2L);
- X exit(sig);
- X}
- X
- X/*
- X * Called when we get a SIGHUP. This means that we must switch from
- X * playing the audio to being silent or vv.
- X */
- static void
- toggle(void)
- X{
- X silent = !silent;
- X}
- X
- X/*
- X * Called when we get a SIGUSR1. This means we have to stop reading
- X * the CD (and eject it). This is useful if the CD player is needed
- X * for official business.
- X */
- static void
- eject(void)
- X{
- X stop_playing = 1;
- X}
- X
- X/*
- X * Callback routine, called to do something to the audio data.
- X */
- static void
- handleaudio(void *arg, CDDATATYPES type, short *audio)
- X{
- X if (!playaudio && !silent) {
- X /* we were silent but want to start playing, so set */
- X /* audio params */
- X ALgetparams(AL_DEFAULT_DEVICE, oldparams, 2L);
- X ALsetparams(AL_DEFAULT_DEVICE, newparams, 2L);
- X playaudio = 1;
- X }
- X /* play the audio, but only if enough space in output port */
- X if (playaudio && ALgetfillable(port) >= CDDA_NUMSAMPLES)
- X ALwritesamps(port, audio, CDDA_NUMSAMPLES);
- X if (playaudio && silent) {
- X /* we were playing but want to be silent now, so reset */
- X /* audio params */
- X ALsetparams(AL_DEFAULT_DEVICE, oldparams, 2L);
- X playaudio = 0;
- X }
- X
- X /* actually do the work we're being paid for */
- X convert_audio_and_print(audio, CDDA_NUMSAMPLES / 2, linear);
- X}
- X
- X/*
- X * Callback routine, called when the CD contains a catalog number.
- X * This routine writes the catalog number and the table of contents to
- X * a file. Other programs can use this information to display the
- X * title of the CD being played.
- X */
- static void
- handlecatalog(void *arg, CDDATATYPES type, char *data)
- X{
- X int i;
- X FILE *fp;
- X
- X for (i = 0; i < 13; i++)
- X if (data[i] != 0)
- X break;
- X if (i == 13) /* catalog # is null, so ignore it */
- X return;
- X
- X if ((fp = fopen(cdcatname, "w")) == NULL)
- X return;
- X fprintf(fp, "hash=%s\n", cdid);
- X fprintf(fp, "toc=%s\n", cdtoc);
- X fprintf(fp, "catalog=");
- X for (i = 0; i < 13; i++)
- X fprintf(fp, "%c", *data++ + '0');
- X fprintf(fp, "\n");
- X fclose(fp);
- X}
- X
- X/*
- X * This routine is called to write identification information in the
- X * .CDcatalognumber file. If there is a catalog number on the CD,
- X * this information is overwritten, but if there is no catalog number
- X * on the CD, the information written here can be used.
- X */
- static void
- nocatalog(CDSTATUS *cdstatus)
- X{
- X FILE *fp;
- X
- X if ((fp = fopen(cdcatname, "w")) == NULL)
- X return;
- X fprintf(fp, "hash=%s\n", cdid);
- X fprintf(fp, "toc=%s\n", cdtoc);
- X fprintf(fp, "tmsf=%d.%d.%d.%d\n", cdstatus->last, cdstatus->total_min,
- X cdstatus->total_sec, cdstatus->total_frame);
- X fclose(fp);
- X}
- X
- X/*
- X * Wait for an audio CD to be inserted into the player.
- X */
- static void
- waitforcd(void)
- X{
- X CDPLAYER *cdp;
- X CDSTATUS status;
- X
- X for (;;) {
- X for (;;) {
- X if ((cdp = CDopen(0, 0)) != 0)
- X break;
- X /* opening the CD player failed; wait a while */
- X /* and try again */
- X sginap(60);
- X }
- X
- X /* opening the CD player succeeded; now wait until the */
- X /* player is ready */
- X for (;;) {
- X if (!CDgetstatus(cdp, &status)) {
- X CDclose(cdp);
- X break;
- X }
- X if (status.state == CD_READY) {
- X if (!status.scsi_audio) {
- X fprintf(stderr, "cdsend: CD-ROM player does not support audio CD's\n");
- X CDclose(cdp);
- X exit(1);
- X }
- X CDclose(cdp);
- X return;
- X }
- X sginap(60);
- X }
- X sginap(60);
- X }
- X}
- X
- X/*
- X * This routine reads one whole CD and when it is finished, it ejects
- X * the CD.
- X */
- static void
- play(void)
- X{
- X CDPLAYER *cdp;
- X CDPARSER *parser;
- X CDFRAME buf[12];
- X CDSTATUS cdstatus;
- X FILE *fd;
- X int i, n, first = 1;
- X ALconfig c;
- X
- X waitforcd();
- X
- X stop_playing = 0;
- X
- X cdp = CDopen(0, 0);
- X if (cdp == 0)
- X return;
- X
- X CDgetstatus(cdp, &cdstatus);
- X if (cdtoc)
- X free(cdtoc);
- X if (cdid)
- X free(cdid);
- X cdtoc = db_get_TOC(cdp, &cdstatus);
- X cdid = db_get_id(cdp, &cdstatus);
- X
- X nocatalog(&cdstatus);
- X
- X if ((parser = CDcreateparser()) == 0) {
- X perror("CDcreateparser");
- X exit(1);
- X }
- X
- X ALgetparams(AL_DEFAULT_DEVICE, oldparams, 2L);
- X c = ALnewconfig();
- X ALsetwidth(c, AL_SAMPLE_16);
- X ALsetchannels(c, AL_STEREO);
- X port = ALopenport("cd", "w", c);
- X
- X CDaddcallback(parser, cd_audio, (CDCALLBACKFUNC) handleaudio, 0);
- X CDaddcallback(parser, cd_catalog, (CDCALLBACKFUNC) handlecatalog, 0);
- X
- X init_convert();
- X
- X while (!stop_playing) {
- X n = CDreadda(cdp, buf, 12);
- X if (first && n == 0) {
- X /* apparantly not an audio CD */
- X CDclose(cdp);
- X ALcloseport(port);
- X ALfreeconfig(c);
- X close(creat(cdcatname, 0666));
- X sginap(300);
- X return;
- X }
- X first = 0;
- X if (n < 0) {
- X perror("CDreadda");
- X exit(1);
- X }
- X if (n == 0)
- X break;
- X
- X for (i = 0; i < n && !stop_playing; i++)
- X CDparseframe(parser, &buf[i]);
- X }
- X
- X if (playaudio) {
- X ALsetparams(AL_DEFAULT_DEVICE, oldparams, 2L);
- X playaudio = 0;
- X }
- X
- X CDeject(cdp);
- X CDdeleteparser(parser);
- X CDclose(cdp);
- X ALcloseport(port);
- X ALfreeconfig(c);
- X close(creat(cdcatname, 0666));
- X}
- X
- main(int argc, char **argv)
- X{
- X int c;
- X int daemon = 0;
- X
- X sprintf(cdcatname, "%s/%s", getenv("HOME"), DEFCDCATNAME);
- X
- X while ((c = getopt(argc, argv, "c:npdl")) != EOF) {
- X switch (c) {
- X case 'c':
- X cdcatname = optarg;
- X break;
- X case 'n':
- X schedctl(NDPRI, 0, NDPNORMMAX);
- X break;
- X case 'd':
- X daemon = 1;
- X break;
- X case 'p':
- X silent = 0;
- X break;
- X case 'l':
- X linear = 1;
- X break;
- X }
- X }
- X
- X setuid(getuid());
- X
- X if (sigset(SIGINT, SIG_IGN) != SIG_IGN)
- X sigset(SIGINT, die);
- X sigset(SIGTERM, die);
- X sigset(SIGHUP, toggle);
- X sigset(SIGUSR1, eject);
- X
- X if (daemon)
- X for (;;)
- X play();
- X else
- X play();
- X die(0);
- X}
- END_OF_FILE
- if test 8872 -ne `wc -c <'cdsend.c'`; then
- echo shar: \"'cdsend.c'\" unpacked with wrong size!
- fi
- # end of 'cdsend.c'
- fi
- if test -f 'cdsend.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cdsend.h'\"
- else
- echo shar: Extracting \"'cdsend.h'\" \(166 characters\)
- sed "s/^X//" >'cdsend.h' <<'END_OF_FILE'
- X#include <sys/types.h>
- X#include <cdaudio.h>
- X
- X#define IN_RATE 44100
- X#define OUT_RATE 8000
- X
- void init_convert(void);
- void convert_audio_and_print(short *, int, int);
- END_OF_FILE
- if test 166 -ne `wc -c <'cdsend.h'`; then
- echo shar: \"'cdsend.h'\" unpacked with wrong size!
- fi
- # end of 'cdsend.h'
- fi
- if test -f 'convert.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'convert.c'\"
- else
- echo shar: Extracting \"'convert.c'\" \(2800 characters\)
- sed "s/^X//" >'convert.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include "cdsend.h"
- X
- X#define A 1
- X#define B 7
- X
- static int d;
- static int prev_i, cur_i;
- static int rate_i = IN_RATE, rate_o = OUT_RATE;
- static short outbuf[(CDDA_NUMSAMPLES/2)*OUT_RATE/IN_RATE + 1];
- X
- X#define ZEROTRAP /* turn on the trap as per the MIL-STD */
- X#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
- X#define CLIP 32635
- X
- static unsigned char
- st_linear_to_ulaw(int sample)
- X{
- X static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- X 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- X 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- X 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- X 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
- X int sign, exponent, mantissa;
- X unsigned char ulawbyte;
- X
- X /* Get the sample into sign-magnitude. */
- X sign = (sample >> 8) & 0x80; /* set aside the sign */
- X if (sign != 0)
- X sample = -sample; /* get magnitude */
- X if (sample > CLIP)
- X sample = CLIP; /* clip the magnitude */
- X
- X /* Convert from 16 bit linear to ulaw. */
- X sample = sample + BIAS;
- X exponent = exp_lut[( sample >> 7 ) & 0xFF];
- X mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
- X ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
- X#ifdef ZEROTRAP
- X if (ulawbyte == 0)
- X ulawbyte = 0x02; /* optional CCITT trap */
- X#endif
- X
- X return ulawbyte;
- X}
- X
- void
- init_convert(void)
- X{
- X d = -OUT_RATE;
- X prev_i = cur_i = 0;
- X}
- X
- void
- convert_audio_and_print(short *audio, int nsamples, int linear)
- X{
- X int cur_o;
- X short *outp = outbuf;
- X#if !defined(A) || !defined(B)
- X int ab = a + b;
- X#endif
- X int ld = d, lp = prev_i, lc = cur_i; /* local copy (register?) */
- X
- X#if !defined(A) || !defined(B)
- X /* some efficiency hacks */
- X ab *= 2;
- X b *= 2;
- X#endif
- X
- X for (;;) {
- X while (ld < 0) {
- X if (nsamples == 0) {
- X d = ld;
- X prev_i = lp;
- X cur_i = lc;
- X
- X if (linear) {
- X write(1, (char *) outbuf,
- X sizeof(short) * (outp - outbuf));
- X }
- X return;
- X }
- X lp = lc;
- X#if defined(A) && defined(B)
- X lc = (A * (audio[0] + audio[1]) + 2*B * lp) / (2*(A+B));
- X#else
- X /* depends on efficiency hacks */
- X lc = (a * (audio[0] + audio[1]) + b * lp) / ab;
- X#endif
- X nsamples--;
- X audio += 2;
- X ld += OUT_RATE;
- X }
- X#if IN_RATE < OUT_RATE
- X while (ld >= 0)
- X#endif
- X {
- X cur_o = (lp * ld + lc * (OUT_RATE - ld)) / OUT_RATE;
- X if (linear) {
- X *outp++ = cur_o;
- X } else {
- X /* not efficient at all */
- X putchar(st_linear_to_ulaw(cur_o));
- X }
- X ld -= IN_RATE;
- X }
- X }
- X}
- END_OF_FILE
- if test 2800 -ne `wc -c <'convert.c'`; then
- echo shar: \"'convert.c'\" unpacked with wrong size!
- fi
- # end of 'convert.c'
- fi
- if test -f 'db_get_TOC.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'db_get_TOC.c'\"
- else
- echo shar: Extracting \"'db_get_TOC.c'\" \(627 characters\)
- sed "s/^X//" >'db_get_TOC.c' <<'END_OF_FILE'
- X#include <string.h>
- X#include <sys/types.h>
- X#include <cdaudio.h>
- X
- X#define MAX_CATALOG (99*3+6+1)
- X
- const char *
- db_get_TOC( CDPLAYER *cdplayer, CDSTATUS *status )
- X{
- CDTRACKINFO info;
- int min, sec, i;
- char buf[MAX_CATALOG], *bufp = buf, *tmp;
- X
- X if (status->state == CD_NODISC || status->state == CD_ERROR)
- X return (NULL);
- X
- X sprintf( bufp, "%02d", status->last - status->first + 1 );
- X bufp += 2;
- X
- X for (i = status->first; i <= status->last; i++) {
- X CDgettrackinfo( cdplayer, i, &info );
- X sprintf( bufp, "%02d%02d", info.total_min, info.total_sec );
- X bufp += 4;
- X }
- X *bufp++ = '\0';
- X return (strdup( buf ));
- X}
- END_OF_FILE
- if test 627 -ne `wc -c <'db_get_TOC.c'`; then
- echo shar: \"'db_get_TOC.c'\" unpacked with wrong size!
- fi
- # end of 'db_get_TOC.c'
- fi
- if test -f 'db_get_id.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'db_get_id.c'\"
- else
- echo shar: Extracting \"'db_get_id.c'\" \(1806 characters\)
- sed "s/^X//" >'db_get_id.c' <<'END_OF_FILE'
- X#include <string.h>
- X#include <sys/types.h>
- X#include <cdaudio.h>
- X
- X#define DB_ID_NTRACKS 5
- X#define DB_ID_MAXLEN 20
- X
- X#define DBID_MAP_SIZE 66
- X
- static char dbid_int_map[DBID_MAP_SIZE] = {
- X '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- X 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- X 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- X 'U', 'V', 'W', 'X', 'Y', 'Z', '@', '_', '=', '+',
- X 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- X 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- X 'u', 'v', 'w', 'x', 'y', 'z',
- X};
- X
- X#define DBID_MAP(b,val) {\
- X register int v = (val);\
- X if (v>=DBID_MAP_SIZE) {\
- X sprintf(b, "%02d", v);\
- X b+= 2;\
- X }\
- X else *b++ = dbid_int_map[v];\
- X}
- X
- const char *
- db_get_id( CDPLAYER *cdplayer, CDSTATUS *status )
- X{
- char db_rtrn_buf[1024];
- CDTRACKINFO info;
- int min, sec, i;
- char *bufp = db_rtrn_buf, *tmp;
- int nCDTracks, nIDTracks;
- X
- X if (status->state == CD_NODISC || status->state == CD_ERROR)
- X return (NULL);
- X
- X nCDTracks = status->last - status->first + 1;
- X DBID_MAP( bufp, ((nCDTracks>>4)&0xf) );
- X DBID_MAP( bufp, (nCDTracks&0xf) );
- X
- X if ( nCDTracks < DB_ID_NTRACKS ) nIDTracks = nCDTracks;
- X else if (nCDTracks == DB_ID_NTRACKS ) nIDTracks = DB_ID_NTRACKS;
- X else {
- X nIDTracks = DB_ID_NTRACKS - 1;
- X for (min= 0, sec= 0,i = status->first ; i <= status->last ; i++ ) {
- X CDgettrackinfo( cdplayer, i, &info );
- X min+= info.total_min;
- X sec+= info.total_sec;
- X }
- X min+= sec/60;
- X sec = sec % 60;
- X DBID_MAP( bufp, min );
- X DBID_MAP( bufp, sec );
- X }
- X
- X for (i = 0; i < nIDTracks; i++) {
- X if (status->first+i <= status->last) {
- X CDgettrackinfo( cdplayer, status->first+i, &info );
- X DBID_MAP( bufp, info.total_min );
- X DBID_MAP( bufp, info.total_sec );
- X }
- X }
- X *bufp++ = '\0';
- X return (strdup( db_rtrn_buf ));
- X}
- END_OF_FILE
- if test 1806 -ne `wc -c <'db_get_id.c'`; then
- echo shar: \"'db_get_id.c'\" unpacked with wrong size!
- fi
- # end of 'db_get_id.c'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-