CDintro(3dm) CDintro(3dm)
CDintro - Introduction to the Silicon Graphics CD Audio Library (CD)
#include <sys/types.h>
#include <dmedia/cdaudio.h>
-lcdaudio -lmediad -lds
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);
}
Page 1
CDintro(3dm) CDintro(3dm)
exit(1);
}
Reading Digital Audio Data from a CD [Toc] [Back]
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);
}
Page 2
CDintro(3dm) CDintro(3dm)
exit(1);
}
Parsing and Understanding the Digital Audio Data [Toc] [Back]
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 deemphasized
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) {
Page 3
CDintro(3dm) CDintro(3dm)
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.
Page 4
CDintro(3dm) CDintro(3dm)
/usr/include/dmedia/cdaudio.h - header file
/usr/share/src/dmedia/cd+dat/* - CD, DAT example programs
/usr/lib/libcdaudio.a
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)
Mark Callow, Roger Chickering. Additions by Doug Cook.
PPPPaaaaggggeeee 5555 [ Back ]
|