home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 9
/
FreshFishVol9-CD2.bin
/
bbs
/
disk
/
playcdda-1.1.lha
/
PlayCDDA
/
play.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-04
|
34KB
|
1,298 lines
/* play.c: */
#include "includes.h"
#define VERSION "1.1 (04.01.1994)"
#define HRDBLBF
#define CDDA_BUFSIZE 2368
#define SUBCHANNEL_SIZE 16
#define STD_BUFSIZE 2048
#define SENSE_LENGTH 32
#define AUDIO_BUFSIZE ((CDDA_BUFSIZE-SUBCHANNEL_SIZE)/g_compression_factor/4)
#define TOTAL_CDDA_BUFSIZE (g_buffers*2*CDDA_BUFSIZE)
#define TOTAL_AUDIO_BUFSIZE (g_buffers*2*AUDIO_BUFSIZE)
#define CDDA_STD_BUFSIZE (STD_BUFSIZE+SENSE_LENGTH)
typedef short t_bool;
typedef struct toc {
char reserved1;
unsigned char flags;
unsigned char track_number;
char reserved2;
long address;
} t_toc;
typedef enum dtype {UNKNOWNDRIVE = 0, TOSHIBA, APPLECD300} t_drivetype;
static char *TheVersion = "$VER: PlayCDDA " VERSION;
t_bool g_called_from_cli;
char g_scsi_device[80];
t_drivetype g_whatdrive = UNKNOWNDRIVE;
int g_scsi_id;
LONG g_memory_type = MEMF_CHIP;
UBYTE *g_cdda_base = NULL;
UBYTE *g_audio_base = NULL;
UBYTE *g_std_buf_base = NULL;
UBYTE *g_cdda_buf[2];
UBYTE *g_cdda_std_buf;
UBYTE *g_audio_buf[2];
struct MsgPort *g_cdda_port = NULL;
struct MsgPort *g_audio_port[2] = { NULL, NULL };
ULONG g_cdda_sigmask;
ULONG g_audio_sigmask[2];
#ifndef HRDBLBF
struct IOStdReq *g_scsireq = NULL;
t_bool g_outstanding_cdda_request = FALSE;
struct SCSICmd *g_scsicmd = NULL;
UBYTE *g_sense_data;
#else
struct IOStdReq *g_scsireq[2] = {NULL, NULL};
t_bool g_outstanding_cdda_request[2] = {FALSE, FALSE};
struct SCSICmd *g_scsicmd[2] = {NULL, NULL};
UBYTE *g_sense_data[2];
#endif
struct IOAudio *g_audioreq[2] = { NULL, NULL };
t_bool g_audio_device_open = FALSE;
long g_period;
int g_toc_length;
t_toc g_toc[100];
short g_volume = 1;
/* possible values for g_compression_factor: 2, 3, 4, 6, 7, 12, 14, 28, 49 */
unsigned short g_compression_factor = 2;
unsigned short g_buffers = 4;
/* user interface variables: */
#ifdef __SASC
extern struct Library *DOSBase;
#endif
struct Library *IconBase = NULL;
struct Library *IntuitionBase = NULL;
struct Library *GadToolsBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Screen *g_screen = NULL;
void *g_visual_info = NULL;
struct Window *g_window = NULL;
struct Gadget *g_glist = NULL;
t_bool g_bye = FALSE;
char g_track_str[3] = { 0, 0, 0 };
char g_index_str[3] = { 0, 0, 0 };
char g_time_str[6] = { 0, 0, ':', 0, 0, 0 };
unsigned char g_track, g_index;
unsigned char g_minute, g_seconds;
enum gadget_ids {
GID_SAMPLING_RATE = 21,
GID_BUFFERS,
GID_VOLUME,
GID_PREV,
GID_NEXT,
GID_START,
GID_STOP,
GID_TRACK,
GID_INDEX,
GID_TIME,
/* always last: */
GID_MAX
};
struct Gadget *g_gadgets[GID_MAX];
#ifdef __SASC
void __regargs __chkabort(void)
{
}
#endif
void Cleanup_User_Interface (void)
{
if (g_window)
CloseWindow (g_window);
if (g_glist)
FreeGadgets (g_glist);
if (g_visual_info)
FreeVisualInfo (g_visual_info);
if (g_screen)
UnlockPubScreen (NULL, g_screen);
if (GfxBase)
CloseLibrary ((struct Library *) GfxBase);
if (GadToolsBase)
CloseLibrary (GadToolsBase);
if (IntuitionBase)
CloseLibrary (IntuitionBase);
}
void Cleanup_Audio (void)
{
if (g_cdda_base) {
FreeMem (g_cdda_base, TOTAL_CDDA_BUFSIZE + 15);
g_cdda_base = NULL;
}
if (g_audio_base) {
FreeMem (g_audio_base, TOTAL_AUDIO_BUFSIZE + 15);
g_audio_base = NULL;
}
if (g_audio_device_open) {
CloseDevice ((struct IORequest *) g_audioreq[0]);
g_audio_device_open = FALSE;
}
if (g_audio_port[0]) {
DeleteMsgPort (g_audio_port[0]);
g_audio_port[0] = NULL;
}
if (g_audio_port[1]) {
DeleteMsgPort (g_audio_port[1]);
g_audio_port[1] = NULL;
}
if (g_audioreq[0]) {
FreeMem (g_audioreq[0], sizeof (struct IOAudio));
g_audioreq[0] = NULL;
}
if (g_audioreq[1]) {
FreeMem (g_audioreq[1], sizeof (struct IOAudio));
g_audioreq[1] = NULL;
}
}
void Cleanup (void)
{
#ifdef HRDBLBF
int i;
#endif
Cleanup_Audio ();
if (g_std_buf_base)
FreeMem (g_std_buf_base, CDDA_STD_BUFSIZE + 15);
#ifndef HRDBLBF
if (g_scsicmd)
FreeMem (g_scsicmd, sizeof (struct SCSICmd));
if (g_scsireq) {
if (g_scsireq->io_Device) {
if (g_outstanding_cdda_request) {
AbortIO ((struct IORequest *) g_scsireq);
WaitIO ((struct IORequest *) g_scsireq);
}
CloseDevice ((struct IORequest *) g_scsireq);
}
DeleteIORequest ((struct IORequest *) g_scsireq);
}
#else
for (i = 0; i < 2; i++) {
if (g_scsicmd[i])
FreeMem (g_scsicmd[i], sizeof (struct SCSICmd));
if (g_scsireq[i]) {
if (g_scsireq[i]->io_Device) {
if (g_outstanding_cdda_request[i]) {
AbortIO ((struct IORequest *) g_scsireq[i]);
WaitIO ((struct IORequest *) g_scsireq[i]);
}
CloseDevice ((struct IORequest *) g_scsireq[i]);
}
DeleteIORequest ((struct IORequest *) g_scsireq[i]);
}
}
#endif
if (g_cdda_port)
DeleteMsgPort (g_cdda_port);
Cleanup_User_Interface ();
if (IconBase)
CloseLibrary (IconBase);
}
void Fatal_Error (char *p_message, ...)
{
va_list arg;
static struct EasyStruct req = {
sizeof (struct EasyStruct),
0,
(UBYTE *) "PlayCDDA Error",
NULL,
(UBYTE *) "Abort"
};
va_start (arg, p_message);
if (IntuitionBase) {
req.es_TextFormat = (UBYTE *) p_message;
EasyRequestArgs (NULL, &req, NULL, arg);
} else if (g_called_from_cli) {
VPrintf ((UBYTE *) p_message, (LONG *) arg);
WriteChars ((UBYTE *) "\n", 1);
} else
Alert (0x0000CDDA);
va_end (p_message);
exit (1);
}
char *Open_User_Interface (void)
{
static struct TextAttr Topaz8 = { (UBYTE *) "topaz.font", 8, 0, 0, };
struct TextFont *font;
int i, j;
static char *labels[20] = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
"12", "13", "14", "15", "16", "17", "18", "19", "20"
};
static char *sampling_rate_labels[] = {
"22050 bps", /* 2 */
"14700 bps", /* 3 */
"11025 bps", /* 4 */
"7350 bps", /* 6 */
"6300 bps", /* 7 */
NULL
};
static char *buffers_labels[] = {
"2",
"4",
"8",
"16",
"32",
"64",
NULL
};
static char *volume_labels[] = {
"Low",
"Medium",
"High",
NULL
};
struct NewGadget ng;
struct Gadget *gad;
int topborder;
if (!(IntuitionBase = OpenLibrary ((UBYTE *) "intuition.library", 37)))
return "cannot open intuition.library";
if (!(GadToolsBase = OpenLibrary ((UBYTE *) "gadtools.library", 37)))
return "cannot open gadtools.library";
if (!(GfxBase = (struct GfxBase *)
OpenLibrary ((UBYTE *) "graphics.library", 37)))
return "cannot open graphics.library";
/* does the font exist? */
if (!(font = OpenFont (&Topaz8)))
return "cannot open topaz 8 font";
CloseFont (font);
if (!(g_screen = LockPubScreen (NULL)))
return "cannot lock default public screen";
if (!(g_visual_info = GetVisualInfo (g_screen, TAG_END)))
return "GetVisualInfo() failed";
gad = CreateContext (&g_glist);
topborder = g_screen->WBorTop + (g_screen->Font->ta_YSize + 1);
ng.ng_Width = 20;
ng.ng_Height = 12;
ng.ng_TextAttr = &Topaz8;
ng.ng_VisualInfo = g_visual_info;
ng.ng_Flags = 0;
for (i=0; i<5; i++)
for (j=0; j<4; j++) {
ng.ng_GadgetText = (UBYTE *) labels[i*4+j];
ng.ng_GadgetID = i*4 + j + 1;
ng.ng_LeftEdge = 10 + j * 24;
ng.ng_TopEdge = topborder + 2 + i * 16;
g_gadgets[ng.ng_GadgetID] = gad =
CreateGadget (BUTTON_KIND, gad, &ng,
GA_Disabled, TRUE,
TAG_END);
}
ng.ng_GadgetID = GID_PREV;
ng.ng_GadgetText = (UBYTE *) "Prev";
ng.ng_Width = 44;
ng.ng_LeftEdge = 10;
ng.ng_TopEdge = topborder + 2 + 5 * 16;
g_gadgets[ng.ng_GadgetID] =
gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_END);
ng.ng_GadgetID = GID_NEXT;
ng.ng_GadgetText = (UBYTE *) "Next";
ng.ng_LeftEdge = 58;
g_gadgets[ng.ng_GadgetID] =
gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_END);
ng.ng_GadgetID = GID_START;
ng.ng_GadgetText = (UBYTE *) "Start";
ng.ng_LeftEdge = 120;
ng.ng_TopEdge = topborder + 2 + 4 * 16;
ng.ng_Width = 120;
ng.ng_Height = 28;
g_gadgets[ng.ng_GadgetID] =
gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_END);
ng.ng_GadgetID = GID_STOP;
ng.ng_GadgetText = (UB