July 90 - ACCESSING CD-ROM AUDIO TRACKS FROM YOUR APPLICATION
ACCESSING CD-ROM AUDIO TRACKS FROM YOUR
APPLICATION
ERIC MUELLER
CD-ROM opens up the possibility of providing the user of your application with a new
dimension of sound feedback, in full digitally reproduced stereo. Coaxing the sound out
of the AppleCD S C® drive, however, is not as simple as prompting the user to "press
PLAY on your CD-ROM drive now." This article explains the intricacies of controlling
the audio functions of the AppleCD SC from an Apple II application.
Imagine how you might use CD-ROM audio tracks to make your software burst with
sound: language software that pronounces each lesson as it teaches it; reading programs
that speak words instead of just displaying them; almost any kind of program adapted
with audio cues for an audience with reading disabilities. CD-ROM is also the answer
for applications that require lengthy music tracks or background music that simply
won't fit on the program disk in a digitized format.
In this article, you'll learn about the capabilities of the AppleCD SC drive, and the
kinds of calls you can make to the drive to control the audio features. The article also
covers basic information about how audio tracks are stored on CD-ROM. (While the
primary focus of this article is the Apple II, this section applies to the Macintosh as
well.) Finally, it covers the specifics of playing audio tracks via the GS/OS® SCSI CD
driver and the five major audio control calls.
AN OVERVIEW OF THE AUDIO CAPABILITY
You make the AppleCD SC do your bidding by sending it the GS/OS device calls DStatus
andDControl via the GS/OS SCSI CD driver. These calls enable you to control all
features of the drive.
You get information about the contents of the disc in the drive and the current status of
the drive with two DStatus subcalls: ReadTOC and AudioStatus.
You control audio play with five DControl subcalls: AudioPlay, AudioPause,
AudioScan,AudioStop, and AudioSearch. These calls start and stop the disc from
spinning inside the AppleCD SC, and position the laser.
We'll look at each of these functions in greater detail in the sections that follow, and
illustrate them with code for a CD Remote classic desk accessory (CDA). You'll find
the complete source code on the Developer Essentials disc in Merlin 16+ format. This
code serves three purposes: first, it enables you to experiment with the AppleCD SC
drive and see how it responds to certain calls. Second, it documents the exact steps
necessary to make audio calls. Finally, you can modify and extend it with your own test
code.
TO COMMUNICATE WITH THE DRIVE
Your Apple II application can communicate with the AppleCD SC through calls built
into either the SmartPort or the GS/OS SCSI CD driver. Accessing the AppleCD SC's
audio features via the Smartport or from the Macintosh side of things is very well
documented, while documentation about using the GS/OS SCSI CD driver is not as
complete (yet). We'll focus here on how to access the AppleCD SC via GS/OS.
Issuing CD SC commands from your program is a two-step process: first you must
locate the drive with a DInfo call, and then you can use DStatus and DControl to
check the status and control the device. The control data you send will be parameter
lists for the audio calls; the status data you receive will be information about the disc
in the drive.
DINFO Locating the drive with DInfo is fairly straightforward: you step through
each of the available devices until you find one that has a deviceIDNum of $0007
(SCSI CD ROM drive). If yourDInfo call returns an error $11, that means that
you've hit the end of the device chain, and that no CD SC drive is hooked up.
Here is an example from the sample program of how to locate the attached AppleCD SC
drive:
FindCDRom
lda CDROMDev ;Have we found it before?
bne :leave ;Yes - leave now.
:look ;Start looking for drive.
jsl GSOS
dw DInfo ;Make GS/OS DInfo call.
adrl :devParm
bcs :err ;Leave if error.
lda devID ;Get device ID.
cmp #$0007 ;Is it a SCSI CD-ROM device?
beq :found ;Yes - found it.
inc devNum ;No - move to next device . . .
bra :look ;and keep looking.
:found lda devNum
sta CDROMDev
sta DCdevNum ;Store device number for all control calls.
sta DSdevNum ;Store device number for all status calls.
:leave clc ;Found it.
rts
:none ~WriteCString #:noCDRom
:1 jsr getKey
sec ;None found!
rts
:err cmp #$11 ;Error $11 - invalid device number?
beq :none ;Yes - no CD-ROM drive found!
~WriteCString #:error ;No - some other weird error.
bra :1
:error asc 0d'GS/OS error on DInfo call. Press any key to
;quit. ‘0700
:noCDRom asc 0d'No CD-ROM drive found. Press any key to
;quit. ‘0700
:devParm dw 8 ;Eight parameters.
devNum dw 1 ;Device number - start with 1.
adrl nameBuffer ;Pointer to buffer for device name.
dw 0 ;Characteristics.
dl 0 ;TotalBlocks.
dw 0 ;SlotNum.
dw 0 ;UnitNum.
dw 0 ;Version.
devID dw 0 ;Device ID: $0007 = SCSI CD-ROM.
nameBuffer dw 31 ;Max length.
ds 33 ;Storage for device name.
DSTATUS AND DCONTROL Once you've found the drive, exchanging information
with it is simply a matter of DStatus and DControl calls. DStatus enables you to
receive status data from the drive; DControl enables you to send control data to the
drive.
The main parameter table for DControl and DStatus contains a parameter count,
the device number you're working with, the control (or status) code, a pointer to the
command data, a request count (used for status calls), and a transfer count.
The command data information is a parameter list of 18 bytes (see Figure 1). The
first two are reserved and must be 0; the following byte is the SCSI command (which
is the same as the control/status code low byte). Next is a block of 11 bytes: these are
specific to each call. Finally, the command data parameter list ends with a long pointer
to another buffer, where SCSI data is returned from the status calls.
Figure 1 Command Data for DStatus and DControl
The following code from the sample program implements two handlers to make
DControl and DStatus calls:
* Make a DControl call - enter with control code in accumulator.
DoDControl
sta DCcode ;Store control code.
shortacc
sta controlData ;Store it in start of the parameter list.
longacc
jsl GSOS
dw DControl ;Make GS/OS DControl call.
adrl :devParm
jsr GDS ;Get device status & set new disc flag,
; if necessary . . .
rts ;and return with the call made.