Atarium: Audioprogrammierung per Dcntl()

Anfang Mai: Fez-A-Bit-Zeit. Auch dieses Jahr hatten sich auf der Veranstaltung in Berlin-Wuhlheide viele, aber eben nicht alle Firmen aus der deutschen ATARI-Szene eingefunden. Im Kinosaal konnte man sich in Ruhe allerlei interessante Neuentwicklungen wie den Jaguar mit Tempest 2000 oder die Linux-Portierung für TT und Falcon ansehen. Über letztere werden wir sicherlich in Zukunft öfter berichten. Man kann auf jeden Fall davon ausgehen, daß man schon in wenigen Monaten damit prima wird arbeiten können.

In den Ausstellungsräumen herrschte dagegen drangvolle Enge. Wer auf der Suche nach einem Schnäppchen war, konnte hier vieles entdecken (ATARI 7800er-Spielkonsole mit Ballblazer-Modul: 65 DM. Im Freien lachte die Sonne, und so war es kein Wunder, daß man so manchen Aussteller öfter beim Erfrischungsstand traf als am „Arbeitsplatz“.

Fazit: „Ersatzmessen“ sind für die Händler allemal interessant: sie können mit Messeangeboten mal wieder das Geschäft so richtig ankurbeln Insgesamt täte es der Branche aber sicherlich gut, wenn die Anstrengungen etwas besser gebündelt würden und dann wirklich alle verbliebenen Firmen zu einer etwas größeren Veranstaltung kommen würden. Dabei wäre es sicherlich nicht falsch, einen etwas zentraler gelegenen Ort zu finden.

Auf jeden Fall steht fest, daß das CD-ROM seinen Durchbruch geschafft hat. An jedem zweiten Stand gingen CDs über den Tisch, darunter bereits die zweite Shareware-Sammlung von Bernd Lohrum. Bei den Laufwerken dominieren zur Zeit die SCSI-Lösungen, zumal die Preise dafür immer weiter fallen. Die Firma Gellermann & Fellmuth aus Berlin zeigte dennoch auf, daß man auch die besonders günstigen Geräte von Mitsumi am ATARI zum Laufen bringen kann (per interner TOS-Steckkarte oder - ohne Eingriff ins Gerät - über die parallele Schnittstelle). Compo hingegen nutzt dafür den ROM-Port. Man wird sehen, welche dieser Lösungen am Ende einen hinlänglichen Preisunterschied zur SCSI-Lösung bringt.

Womit wir wieder beim Thema CD-ROM-Programmierung angelangt wären. Im letzten Heft hatte ich ja bereits die MetaDOS-Aufrufe zur Audioprogrammierung dokumentiert. Diesen Monat folgt nun die „modernere“ Variante über die MetaDOS-Funktion Metaioctl() bzw. die GEMDOS-Funktionen Dcntl() und Fcntl(). Die einzelnen Funktionen und Datenstrukturen lehnen sich an das Programmierinterface von SunOS (SUNs Unix-Ver-sion) an. SUN wiederum hat sich bei den meisten Details sinnvollerweise an dem orientiert, was SCSI-CD-ROMs ohnehin an Informationen von sich geben. Damit sind die Audiofunktionen erheblich flexibler und leistungsfähiger als das, was ATARI ursprünglich im Rahmen der Meta-DOS-XBIOS-Funktionen vorgesehen hatte. Die hier vorgestellten Definitionen sind soweit wie möglich kompatibel, so daß man C-Programme, die etwas mit dem CD-ROM anstellen, sehr leicht portieren kann.

Bevor ich mich den einzelnen Funktionen zuwende, soll noch darauf eingegangen werden, welche Treiber dieses Interface unterstützen. ATARIs CDARGEN.BOS kennt die Funktion Metaoctl() gar nicht. ISO9660F.DOS hingegen benutzt eine der Funktionen, um Multisession-CDs unterstützen zu können. Damit reicht es, den BOS-Treiber durch einen leistungsfähigeren zu ersetzen, um Multisession-Betrieb möglich zu machen. Ab MetaDOS-Version 2.40 unterstützt ISO9660F.DOS auch die GEMDOS-Funktion Dcntl(), in der die Funktion direkt an die Metaioctl()-Funktion des zuständigen BOS-Treibers weitergereicht wird.

Die hier dokumentierten Opcodes werden bereits von den BOS-Treibern zweier Hersteller unterstützt: CD-Tool (Hard & Soft, für alle handelsüblichen Laufwerke an ACSI oder SCSI) und die Treiber für die bereits oben erwähnten Interfaces der Gellermann & Fellmuth GbR.

.CDROMREADOFFSET liefert die Blocknummer der neuesten Session einer CD zurück (wenn es sich bei der eingelegten CD um keine Multisession-CD handelt, sollte man also eine Null zurückgeliefert bekommen). ATARIs ISO9660F. DOS verwendet diesen Wert, um das „richtige“ Verzeichnis zu finden.

CDROMPAUSE unterbricht das aktuelle Audio-Kommando, CDROMRESUME setzt es fort.

CDROMPLAYMSF startet die Audiowiedergabe. Dazu übergibt man einen Zeiger auf eine cdrom_msf-Struktur, in die Anfangs- und Endzeitpunkt in MSF-Notation eingetragen sind. CDROMPLAYTRKIND tut dasselbe, nur übergibt man hier eine cdrom_ti-Struktur, in der Start-und Endposition in Track/Index-Schreibweise eingetragen sind. Bei den meisten Audio-CDs aus dem POP-Bereich sind die Tracks nicht weiter eingeteilt. Viele Klassik-CDs haben aber auch innerhalb der Tracks noch eine feinere Einteilung in „Indices“. Achtung: nicht jedes CD-ROM kann gezielt Indizes ungleich Eins ansteuern!

Mit CDROMREADTOCHDR und CD-ROMREADTOCENTRY kann man sich Informationen über den Aufbau der CD beschaffen. Dabei füllt CDROMREADTOCHDR eine cdrom_tochdr-Struktur aus, in der der erste und letzte Track der CD eingetragen werden. Mit CDROMREADTOCENTRY kann man dann genauere Informationen über die einzelnen Tracks erfragen. CDROM_LEAD OUT (0xAA) dient dabei als spezielle Track-Nummer, die Auskunft über das „Ende“ der CD gibt und beispielsweise dazu gebraucht wird, die Länge des letzten Tracks zu berechnen.

Die cdrom_tocentry-Struktur besteht aus Eingabedaten (die vor dem Aufruf initialisiert werden müssen) und Ausgabedaten. cdte_track enthält die Track-Nummer, cdte_format die Konstante CDROM_LBA oder CDROM_MSF (je nachdem, ob man die Ausgabewerte im LBA- oder MSF-Format haben will).

CDROMSTOP stoppt das Laufwerk (wird von Hard&Softs CPX-Modul „Stop & Lock“ benutzt). CDROM START startet es wieder und zieht dazu nötigenfalls die Schublade wieder ein. CDROMEJECT fährt die Schublade aus.

CDROMVOLCTRL und CDROM AUDIOCTRL machen es möglich, die Lautstärken und Kanalzuordnungen der einzelnen Audiokanäle zu verändern. Dabei ist die Funktion CDROMAUDIOCTRL flexibler, weil sie es ermöglicht, auch die aktuellen Einstellungen zu erfragen (dazu in der cdrom_audioctrl-Stmktur den Wert set auf Null setzen). Bei CDROMVOLCTRL hingegen ist dies nicht vorgesehn, dafür ist die Funktion aber zum entsprechenden SunOS-Aufruf kompatibel. Achtung: das Verstellen der Lautstärke ist nicht bei allen Geräten möglich!

CDROMPREVENTREMOVAL und CDROMALLOWREMOVAL sperrt den Auswurf des Geräts bzw. gibt ihn wieder frei. Dies kann nützlich sein, wenn das CD-ROM an einem öffentlich zugänglichen Ort steht und man dem CD-Klau Vorbeugen will. Diese Funktionen werden ebenfalls von Hard&Softs CPX-Modul „Stop&Lock“ benutzt.

Neben den eigentlich PCM-Daten enthält eine Audio-CD noch einige „Subchannels“. Der Q-Channel kann dabei die aktuelle Position (das sind die Daten, die ein CD-Player als aktuelle Zeit anzeigt), einen Mediencode und einen Trackcode enthalten. Diese Informationen können über die Opcodes CDROMSUBCHNL, CDROMGETMCN und CDROMGETT1SRC abgefragt werden.

CDROMSUBCHNL liefert in der cdrom_subchnl-Struktur die aktuellen Positionsdaten sowie den Audiostalus zurück. Achtung: mit dem Eingabeparameter cdsc_format legt man fest, ob man die Track-Adressen im MF- oder LBA-Format sehen will. cdsc_audiostatus ist entweder eine der fünf Konstanten (siehe Abbildung) oder Null, wenn diese Information nicht verfügbar ist. cdsc_adr und cdsc_ctrl haben dieselben Werte wie bei den Inhaltsverzeichnisfunktionen, cdsc_trk und cdsc_ind geben die aktuelle Track- und Indexnummer an. cdsc_absaddr und cdsc_reladdr schließlich zeigen die absolute Position bzw. die relative Position innerhalb des Lieds an.

Haben Sie sich schon mal darüber gewundert, daß bei manchen Audio-CDs unmittelbar vor dem Liedanfang die relative Uhr rückwärts läuft? Das ist genau der in cdsc_reladdr angegebene Wert!

CDROMGETMCN liefert die „Media Catalog Number“ zurück. Rein theoretisch sollte dies eine schöne Möglichkeit sein, jede CD einwandfrei zu identifizieren, ln der Praxis findet man diese Angabe leider auf den allerwenigsten CDs.

Übrigens: daß auf Audio-CDs irgendwo Interpreten und Titel gespeichert sind, ist wirklich nur ein Gerücht. Leider!

Der „Track International Stanard Recording Code" soll eine eindeutige Kennzeichnung für einzelne Tracks darstellen. In der Praxis konnte ich leider keine CD mit dieser Information finden.

Die Aufrufe CDROMREADMODEI, CDROMREADMODE2 und CDROMREADDA dienen dem Lesen von Sektoren in einem spezifischen Format. Als Parameter wird ein Zeiger auf eine cdrom_read-Struktur übergeben. Modus-1-Sektoren sind 2048 Bytes groß und werden auf „normalen“ CD-ROMs benutzt. Modus-2-Sektoren werden bei XA-CDs verwendet und enthalten 2336 Bytes (zum Beispiel: Photo-CD ohne Fehlerkorrektur oder Video-CD). Die DA-Sektoren von Audio-CDs sind 2352 Bytes groß und enthalten pro Sektor 588 Samples im 16-Bit-Stereo-PCM-Format. Wiederum Achtung: nicht alle CD-ROMs können alle diese Sektortypen lesen, und nicht alle Treiber bieten solche Funktionen an.

Damit wäre unser Exkurs in die CD-ROM-Programmierung vorläufig beendet. Mal sehen, was es in zwei Monaten nach der Sommerpause für Neuigkeiten gibt: zumindest eine neue MiNT-Version sollte dann eigentlich verfügbar sein!

/*
    CD-ROM Fcntl()s and structures
    (c)1994 by MAXON-Computer
    Autor: Julian F. Reschke.
*/

#ifndef CDROMIO H
#define _CDROMIO_H

#ifndef BYTE
#define BYTE unsigned char
#endif

typedef union
{
    struct {
        BYTE reserved, minute, second, frame;
    } msf;
    long lba;
} cd_ad;

/* Data structures used */

struct cdrom_msf
{
    BYTE cdmsf_minO; /* Start minute */
    BYTE cdmsf_secO; /* Start second */
    BYTE cdmsf_frameO; /* Start frame */
    BYTE cdmsf_min1; /* end minute */
    BYTE cdmsf_sec1; /* end second */
    BYTE cdmsf_frame1; /* end frame */
};

struct cdrom_ti
{
    BYTE cdti_trk0; /* Start track */
    BYTE cdti_ind0; /* Start index */
    BYTE cdti_trk; /* end track */
    BYTE cdti_ind1; /* end index */
};

struct cdrom_tochdr
{
    BYTE cdth_trk0; /* Start track */
    BYTE cdth_trk1; /* end track */
};

struct cdrom_tocentry
{
    /* input Parameters */

    /* track number or CDROM_LEADOUT */
    BYTE cdte_track;
    /* CDROM_LBA or CDROM_MSF */
    BYTE cdte_format;

    /* output Parameters */ 

    /* the SUBQ channel encodes 0: nothing,
    1: Position data, 2: MCN, 3: ISRC,
    else: reserved */
    unsigned cdte_adr:4;

    /* bit 0: audio with pre-emphasis.
    bit 1: digital copy permitted.
    bit 2: data track.
    bit 3: four channel */
    unsigned cdte_ctrl:4;

    /* currently not set */
    BYTE cdte_datamode;
    /* track Start */
    cd_ad dte_addr;
};

struct cdrom_subchnl
{
    /* input Parameters */

    /* CDROM_MSF or CDROM_LBA */
    BYTE cdsc_format;

    /* output Parameters */

    BYTE cdsc_audiostatus; /* see below */
    unsigned cdsc_resvd: 8; /* reserved */
    unsigned cdsc_adr: 4; /* see above */
    unsigned cdsc_ctrl: 4; /* see above */
    BYTE cdsc_trk; /* current track */
    BYTE cdsc_ind; /* current index */
    cd_ad cdsc_absaddr; /* absolute address */
    cd_ad cdsc_reladdr; /* track rel. addr. */
};

struct cdrom_mcn
{
    BYTE mcn_audiostatus; /* see above */
    /* Media catalog number as ASCII String */
    BYTE mcn_mcn[23];
};

struct cdrom_tisrc
{
    /* input Parameters */

    BYTE tisrc_track; /* track number */

    /* output Parameters */

    BYTE tisrc_audiostatus; /* see above */
    /* Track International Standard
    Recording Code (ASCII) */
    BYTE tisrc_tisrc[23];
};

struct cdrom_volctrl
{
    BYTE channel0; /* volume level 0..255 */
    BYTE channel1;
    BYTE channel2;
    BYTE channel3;
};

struct cdrom_audioctrl
{
    /* input Parameters */

    short set; /* 0 == inquire only */

    /* input/output Parameters */

    struct {
        BYTE selection;
        BYTE volume;
    } channel[4];
};

struct cdrom_read
{
    long cdread_lba; /* address */
    char *cdread_bufaddr; /* buffer pointer */
    long cdread_buflen; /* byte count */
};

/* CD-ROM address types */

#define CDROM_LBA 0x01
#define CDROM_MSF 0x02

/* SUB Q control bits */

#define CDROM_AUDIO_EMPHASIS 0x01
#define CDROM_COPY_PERMITTED 0x02
#define CDROM_DATA_TRACK 0x04
#define CDROM_FOUR_CHANNEL 0x08

/* The leadout track is always OxAA, regardless
of # of tracks on disc */

#define CDROM_LEADOUT 0xAA

/* return value from READ SUBCHANNEL DATA */

/* audio Status not supported */
#define CDROM_AUDIO_INVALID 0x00
/* audio play Operation in progress */
#define CDROM_AUDIO_PLAY 0x11
/* audio play Operation paused */
#define CDROM_AUDIO_PAUSED 0x12
/* audio play successfully completed */
#define CDROM_AUDIO_COMPLETED 0x13
/* audio play stopped due to error */
#define CDROM_AUDIO_ERROR 0x14
/* no current audio Status to return */
#define CDROM_AUDIO_NO_STATUS 0x5

/* CD-ROM Fcntl opcodes */

/* Get block number of first sector in last
Session of a multisession CD. Argument points to
a LONG. Used by Atari's iso9660f.dos */
#define CDROMREADOFFSET (('C'«8)10x00)

/* Pause audio Operation */
#define CDROMPAUSE (('C'«8)|0x01)

/* Resume audio Operation */

#define CDROMRESUME (('C'«8)|0x02)

/* Play audio. Argument points to cdrom_msf structure */

#define CDROMPLAYMSF    (('C'«8)|0x03)

/* Play audio. Argument points to cdrom_ti structure */

#define CDROMPLAYTRKIND (('C'«8)|0x04)

/* Read header of table of contents. Argument points to cdrom_tochdr structure */

#define CDROMREADTOCHDR (('C'«8)|0x05)

/* Read a toc entry. Argument points to cdrom_tocentry structure */

#define CDROMREADTOCENTRY   (('C'«8)|0x06)

/* Stopsspindle motor */

#define CDROMSTOP   (('C'«8)|0x07)

/* Starts spindle motor */

#define CDROMSTART  (('C'«8)|0x08)

/* Eject medium */

#define CDROMEJECT  (('C'«8)|0x09)

/* Sets audio playback volume. Argument points to cdrom_volctrl structure. Only for compatibility 
to Unix drivers, see also CDROMAUDIOCTRL */
#define CDROMVOLCTRL    (('C'«8)|0x0a)

/* Read subchannel Information. Argument points to cdrom_subchnl structure. */

#define CDROMSUBCHNL    (('C'« 8)|0x0b)

/* Read Mode 2 or 1 sectors. Argument points to cdrom_read structure. Blocks have either 2336 or 2048 bytes. */

#define CDROMREADMODE2  (('C'«8)|0x0c)
#define CDROMREADMODE1  (('C'«8)|0x0d)

/* Lock eject mechanism */
#define CDROMPREVENTREMOVAL (('C'«8)|0x0e)

/* Unlock eject mechanism */
#define CDROMALLOWRMOVAL    (('C'«8)|0x0f)

/* Control audio settings. Argument points to cdrom_audioctrl structure */
#define CDROMAUDIOCTRL  (('C'«8)|0x10)

/* Read Digital Audio (red book) sectors. Argument points to cdrom_read structure. Blocks have 2352 bytes. */
#define CDROMREADDA (('C'«8)|0x11)

/* Read media catalog number. Argument points to cdromjncn structure */
#define CDROMGETMCN (('C'«8)|0x13)

/* Read track international Standard recording code. Argument points to cdrom_tisrc structure */
#define CDROMGETTISRC   (('C'«8)|0x14)

#endif _CDROMIO_H


Julian F. Reschke


Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]