CDintro(3dm)
CDintro - Introduction to the Silicon Graphics CD Audio Library (CD)
As shipped in IRIX 6.5.7. Unchanged since IRIX 6.5.
NAME CDintro - Introduction to the Silicon Graphics CD Audio Library (CD) SYNOPSIS #include <sys/types.h> #include <dmedia/cdaudio.h> -lcdaudio -lmediad -lds DESCRIPTION libcdaudio provides support for audio compact discs in the CD-ROM drive. The library has three sections: support for operating the CD-ROM drive as a player, support for locating and transferring digital audio data into computer memory, and support for parsing and understanding the content of that data. There is some overlap between the first two sections. libcdaudio controls the CD-ROM through the user level SCSI interface /dev/scsi using the facilities of dslib(3). Programs using libcdaudio must be linked with libmediad and dslib using the link option -lmediad -lds. Operating the CD-ROM as a CD Player The CD-ROM drive can be operated as a CD player delivering analog audio to the drive's headphone and stereo line out jacks. Relevant functions for this are: CDopen(3dm), CDclose(3dm), CDplay(3dm), CDplayabs(3dm), CDplaytrack(3dm), CDplaytrackabs(3dm), CDstop(3dm), CDgetstatus(3dm), CDgettrackinfo(3dm), CDeject(3dm), CDallowremoval(3dm), CDpreventremoval(3dm) and CDtogglepause(3dm) The following small program causes the CD-ROM drive with SCSI ID 7 to play, starting with the first track on the CD: #include <sys/types.h> #include <dmedia/cdaudio.h> main( ) { CDPLAYER *cd = CDopen("/dev/scsi/sc0d7l0", "r"); CDSTATUS status; if (cd && CDgetstatus(cd, &status)) { /* Make sure drive is loaded with an audio CD */ while (status.state != CD_READY) { sleep(5); CDgetstatus(cd, &status); } CDplay(cd, status.first, 1); CDclose(cd); exit(0); } exit(1); } Reading Digital Audio Data from a CD The special Silicon Graphics version of the Toshiba 3301 CD-ROM drive can transfer digital audio data across the SCSI bus into system memory. libcdaudio supports these data transfers. Relevant functions for this are: CDopen(3dm), CDbestreadsize(3dm), CDclose(3dm), CDgetstatus(3dm), CDgettrackinfo(3dm), CDreadda(3dm), CDseek(3dm), CDseektrack(3dm), CDseekblock(3dm), CDmsftoblock(3dm), CDmsftoframe(3dm), and CDtctoframe(3dm). CDseek(3dm), CDseekblock(3dm), and CDseektrack(3dm) allow a program to seek to any point on the CD in the manner of lseek(2). The following small program opens the CD-ROM found by inventorying the system and transfers all the audio data from the CD. If more than one CD-ROM drive is installed it will use the first drive found by getinvent(3). #include <sys/types.h> #include <dmedia/cdaudio.h> main() { CDPLAYER *cd = CDopen(0, "r"); CDSTATUS status; CDFRAME buf[12]; int n; if (cd && CDgetstatus(cd, &status)) { if (!status.scsi_audio) exit(1); /* Make sure drive is loaded with an audio CD */ while (status.state != CD_READY) { sleep(5); CDgetstatus(cd, &status); } for (;;) { n = CDreadda(cd, buf, 12); if (n < 0) { /* report error */ exit(1); } f (n == 0) /* We're at the end of the disc */ break; /* Do something with the data which is in buf */ } exit(0); } exit(1); } Parsing and Understanding the Digital Audio Data libcdaudio supports breaking down of the digital audio data into more manageable units. You should first read cdframe(4) for complete details of the format of a CDFRAME which is returned by CDreadda(3dm). The CDparser dissects the frame of data and for each data item it can execute a function in your code to which it passes the data. See CDaddcallback(3dm) for complete details of the callback functions. Relevant functions are: CDcreateparser(3dm), CDdeleteparser(3dm), CDaddcallback(3dm), CDparseframe(3dm), CDresetparser(3dm), CDremovecallback(3dm), CDdeleteparser(3dm), CDtimetoa(3dm), and CDsbtoa(3dm). To illustrate, we can expand on our previous example by having the parser call us back with the audio data which it will have byte-swapped and de- emphasized if the CD's pre-emphasis bit is turned on. #include <sys/types.h> #include <sigfpe.h> #include <dmedia/cdaudio.h> #include <dmedia/audio.h> ALport audioport; playaudio(void *arg, CDDATATYPES type, short *audio) { ALwritesamps(audioport, audio, CDDA_NUMSAMPLES); } main() { CDPLAYER *cd = CDopen(0, "r"); CDPARSER *cdp = CDcreateparser(); CDSTATUS status; CDFRAME buf[12]; int i, n; audioport = ALopenport("CD Test", "w", 0); /* Make sure we get sane underflow exception handling */ sigfpe_[_UNDERFL].repls = _ZERO; handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL); if (cdp) { CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0); } else exit(1); if (cd && CDgetstatus(cd, &status)) { if (!status.scsi_audio) exit(2); /* Make sure drive is loaded with an audio CD */ while (status.state != CD_READY) { sleep(5); CDgetstatus(cd, &status); } for (;;) { n = CDreadda(cd, buf, 12); if (n < 0) { /* report error */ exit(1); } if (n == 0) /* We're at the end of the disc */ break; for (i = 0; i < 12; i++) CDparseframe(cdp, &buf[i]); } exit(0); } exit(3); } In de-emphasis filtering floating point underflows are normal and expected. Thus underflows may happen when CDparseframe(3dm) is called if you have a cd_audio callback and the incoming data is pre-emphasized. IRIX' default underflow handling causes a trap to the kernel on each underflow followed by a software emulation of the calculation that produces a de-normalized result. The resulting value, when used in a subsequent calculation, can cause another underflow and kernel trap. The cycle repeats leading to a complete loss of performance to the point where the tape will not play in real time. A saner method of handling underflows in this case is to trap on the first one and replace the result with zero. Subsequent operations then do not cause traps, thus performance remains at an acceptable level. The two lines of code in the previous example referring to sigfpe set up this saner method of handling the exceptions. See sigfpe(3C) for more details. This code can't be put into the library because it affects global state for the program and the programmer may not always want this type of exception handling. They may want the correct slow result in some parts of their program. This example must be linked with -lfpe in addition to the libraries shown above. FILES /usr/include/dmedia/cdaudio.h - header file /usr/share/src/dmedia/cd+dat/* - CD, DAT example programs /usr/lib/libcdaudio.a SEE ALSO CDallowremoval(3dm), CDaddcallback(3dm), CDatomsf(3dm), CDatotime(3dm), CDbestreadsize(3dm), CDclose(3dm), CDcreateparser(3dm), CDdeleteparser(3dm), CDeject(3dm), CDframetomsf(3dm), CDframetotc(3dm), CDgetstatus(3dm), CDgettrackinfo(3dm), CDopen(3dm), CDparseframe(3dm), CDplay(3dm), CDplayabs(3dm), CDplaytrack(3dm), CDplaytrackabs(3dm), CDpreventremoval(3dm), CDreadda(3dm), CDremovecallback(3dm), CDresetparser(3dm), CDsbtoa(3dm), CDseek(3dm), CDseekblock(3dm), CDseektrack(3dm), CDtctoframe(3dm), CDtimetoa(3dm), CDtogglepause(3dm), ALintro(3dm), AFintro(3dm), DTintro(3dm), cdframe(4), dslib(3), sigfpe(3C) AUTHOR Mark Callow, Roger Chickering. Additions by Doug Cook.