home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / disk / playcdda-1.1.lha / PlayCDDA / play.c < prev    next >
C/C++ Source or Header  |  1994-01-04  |  34KB  |  1,298 lines

  1. /* play.c: */
  2.  
  3. #include "includes.h"
  4.  
  5. #define VERSION "1.1 (04.01.1994)"
  6.  
  7. #define HRDBLBF
  8.  
  9. #define CDDA_BUFSIZE 2368
  10. #define SUBCHANNEL_SIZE 16
  11. #define STD_BUFSIZE 2048
  12. #define SENSE_LENGTH 32
  13. #define AUDIO_BUFSIZE ((CDDA_BUFSIZE-SUBCHANNEL_SIZE)/g_compression_factor/4)
  14. #define TOTAL_CDDA_BUFSIZE (g_buffers*2*CDDA_BUFSIZE)
  15. #define TOTAL_AUDIO_BUFSIZE (g_buffers*2*AUDIO_BUFSIZE)
  16. #define CDDA_STD_BUFSIZE (STD_BUFSIZE+SENSE_LENGTH)
  17.  
  18. typedef short t_bool;
  19.  
  20. typedef struct toc {
  21.   char reserved1;
  22.   unsigned char flags;
  23.   unsigned char track_number;
  24.   char reserved2;
  25.   long address;
  26. } t_toc;
  27.  
  28. typedef enum dtype {UNKNOWNDRIVE = 0, TOSHIBA, APPLECD300} t_drivetype;
  29.  
  30. static char *TheVersion = "$VER: PlayCDDA " VERSION;
  31.  
  32. t_bool g_called_from_cli;
  33. char g_scsi_device[80];
  34. t_drivetype g_whatdrive = UNKNOWNDRIVE;
  35. int g_scsi_id;
  36. LONG g_memory_type = MEMF_CHIP;
  37. UBYTE *g_cdda_base = NULL;
  38. UBYTE *g_audio_base = NULL;
  39. UBYTE *g_std_buf_base = NULL;
  40. UBYTE *g_cdda_buf[2];
  41. UBYTE *g_cdda_std_buf;
  42. UBYTE *g_audio_buf[2];
  43. struct MsgPort *g_cdda_port = NULL;
  44. struct MsgPort *g_audio_port[2] = { NULL, NULL };
  45. ULONG g_cdda_sigmask;
  46. ULONG g_audio_sigmask[2];
  47. #ifndef HRDBLBF
  48. struct IOStdReq *g_scsireq = NULL;
  49. t_bool g_outstanding_cdda_request = FALSE;
  50. struct SCSICmd *g_scsicmd = NULL;
  51. UBYTE *g_sense_data;
  52. #else
  53. struct IOStdReq *g_scsireq[2] = {NULL, NULL};
  54. t_bool g_outstanding_cdda_request[2] = {FALSE, FALSE};
  55. struct SCSICmd *g_scsicmd[2] = {NULL, NULL};
  56. UBYTE *g_sense_data[2];
  57. #endif
  58. struct IOAudio *g_audioreq[2] = { NULL, NULL };
  59. t_bool g_audio_device_open = FALSE;
  60. long g_period;
  61. int g_toc_length;
  62. t_toc g_toc[100];
  63. short g_volume = 1;
  64. /* possible values for g_compression_factor: 2, 3, 4, 6, 7, 12, 14, 28, 49 */
  65. unsigned short g_compression_factor = 2;
  66. unsigned short g_buffers = 4;
  67.  
  68. /* user interface variables: */
  69.  
  70. #ifdef __SASC
  71. extern struct Library *DOSBase;
  72. #endif
  73. struct Library *IconBase = NULL;
  74. struct Library *IntuitionBase = NULL;
  75. struct Library *GadToolsBase = NULL;
  76. struct GfxBase *GfxBase = NULL;
  77. struct Screen *g_screen = NULL;
  78. void *g_visual_info = NULL;
  79. struct Window *g_window = NULL;
  80. struct Gadget *g_glist = NULL;
  81. t_bool g_bye = FALSE;
  82. char g_track_str[3] = { 0, 0, 0 };
  83. char g_index_str[3] = { 0, 0, 0 };
  84. char g_time_str[6] = { 0, 0, ':', 0, 0, 0 };
  85. unsigned char g_track, g_index;
  86. unsigned char g_minute, g_seconds;
  87.  
  88. enum gadget_ids {
  89.   GID_SAMPLING_RATE = 21,
  90.   GID_BUFFERS,
  91.   GID_VOLUME,
  92.   GID_PREV,
  93.   GID_NEXT,
  94.   GID_START,
  95.   GID_STOP,
  96.   GID_TRACK,
  97.   GID_INDEX,
  98.   GID_TIME,
  99.  
  100.   /* always last: */
  101.   GID_MAX
  102. };
  103.  
  104. struct Gadget *g_gadgets[GID_MAX];
  105.  
  106. #ifdef __SASC
  107. void __regargs __chkabort(void)
  108. {
  109. }
  110. #endif
  111.  
  112. void Cleanup_User_Interface (void)
  113. {
  114.   if (g_window)
  115.     CloseWindow (g_window);
  116.   if (g_glist)
  117.     FreeGadgets (g_glist);
  118.   if (g_visual_info)
  119.     FreeVisualInfo (g_visual_info);
  120.   if (g_screen)
  121.     UnlockPubScreen (NULL, g_screen);
  122.   if (GfxBase)
  123.     CloseLibrary ((struct Library *) GfxBase);
  124.   if (GadToolsBase)
  125.     CloseLibrary (GadToolsBase);
  126.   if (IntuitionBase)
  127.     CloseLibrary (IntuitionBase);
  128. }
  129.  
  130. void Cleanup_Audio (void)
  131. {
  132.   if (g_cdda_base) {
  133.     FreeMem (g_cdda_base, TOTAL_CDDA_BUFSIZE + 15);
  134.     g_cdda_base = NULL;
  135.   }
  136.   if (g_audio_base) {
  137.     FreeMem (g_audio_base, TOTAL_AUDIO_BUFSIZE + 15);
  138.     g_audio_base = NULL;
  139.   }
  140.   if (g_audio_device_open) {
  141.     CloseDevice ((struct IORequest *) g_audioreq[0]);
  142.     g_audio_device_open = FALSE;
  143.   }
  144.   if (g_audio_port[0]) {
  145.     DeleteMsgPort (g_audio_port[0]);
  146.     g_audio_port[0] = NULL;
  147.   }
  148.   if (g_audio_port[1]) {
  149.     DeleteMsgPort (g_audio_port[1]);
  150.     g_audio_port[1] = NULL;
  151.   }
  152.   if (g_audioreq[0]) {
  153.     FreeMem (g_audioreq[0], sizeof (struct IOAudio));
  154.     g_audioreq[0] = NULL;
  155.   }
  156.   if (g_audioreq[1]) {
  157.     FreeMem (g_audioreq[1], sizeof (struct IOAudio));
  158.     g_audioreq[1] = NULL;
  159.   }
  160. }
  161.  
  162. void Cleanup (void)
  163. {
  164. #ifdef HRDBLBF
  165.   int i;
  166. #endif
  167.  
  168.   Cleanup_Audio ();
  169.  
  170.   if (g_std_buf_base)
  171.     FreeMem (g_std_buf_base, CDDA_STD_BUFSIZE + 15);
  172. #ifndef HRDBLBF
  173.   if (g_scsicmd)
  174.     FreeMem (g_scsicmd, sizeof (struct SCSICmd));
  175.   if (g_scsireq) {
  176.     if (g_scsireq->io_Device) {
  177.       if (g_outstanding_cdda_request) {
  178.         AbortIO ((struct IORequest *) g_scsireq);
  179.         WaitIO ((struct IORequest *) g_scsireq);
  180.       }
  181.       CloseDevice ((struct IORequest *) g_scsireq);
  182.     }
  183.     DeleteIORequest ((struct IORequest *) g_scsireq);
  184.   }
  185. #else
  186.   for (i = 0; i < 2; i++) {
  187.     if (g_scsicmd[i])
  188.       FreeMem (g_scsicmd[i], sizeof (struct SCSICmd));
  189.     if (g_scsireq[i]) {
  190.       if (g_scsireq[i]->io_Device) {
  191.     if (g_outstanding_cdda_request[i]) {
  192.       AbortIO ((struct IORequest *) g_scsireq[i]);
  193.       WaitIO ((struct IORequest *) g_scsireq[i]);
  194.     }
  195.     CloseDevice ((struct IORequest *) g_scsireq[i]);
  196.       }
  197.       DeleteIORequest ((struct IORequest *) g_scsireq[i]);
  198.     }
  199.   }
  200. #endif
  201.   if (g_cdda_port)
  202.     DeleteMsgPort (g_cdda_port);
  203.  
  204.   Cleanup_User_Interface ();
  205.   
  206.   if (IconBase)
  207.     CloseLibrary (IconBase);
  208. }
  209.  
  210. void Fatal_Error (char *p_message, ...)
  211. {
  212.   va_list arg;
  213.  
  214.   static struct EasyStruct req = {
  215.     sizeof (struct EasyStruct),
  216.     0,
  217.     (UBYTE *) "PlayCDDA Error",
  218.     NULL,
  219.     (UBYTE *) "Abort"
  220.   };
  221.  
  222.   va_start (arg, p_message);
  223.   if (IntuitionBase) {
  224.     req.es_TextFormat = (UBYTE *) p_message;
  225.     EasyRequestArgs (NULL, &req, NULL, arg);
  226.   } else if (g_called_from_cli) {
  227.     VPrintf ((UBYTE *) p_message, (LONG *) arg);
  228.     WriteChars ((UBYTE *) "\n", 1);
  229.   } else
  230.     Alert (0x0000CDDA);
  231.  
  232.   va_end (p_message);
  233.  
  234.   exit (1);
  235. }
  236.  
  237. char *Open_User_Interface (void)
  238. {
  239.   static struct TextAttr Topaz8 = { (UBYTE *) "topaz.font", 8, 0, 0, };
  240.   struct TextFont *font;
  241.   int i, j;
  242.   static char *labels[20] = {
  243.     "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
  244.     "12", "13", "14", "15", "16", "17", "18", "19", "20"
  245.   };
  246.   static char *sampling_rate_labels[] = {
  247.     "22050 bps",  /* 2 */
  248.     "14700 bps",  /* 3 */
  249.     "11025 bps",  /* 4 */
  250.     "7350 bps",   /* 6 */
  251.     "6300 bps",   /* 7 */
  252.     NULL
  253.   };
  254.   static char *buffers_labels[] = {
  255.     "2",
  256.     "4",
  257.     "8",
  258.     "16",
  259.     "32",
  260.     "64",
  261.     NULL
  262.   };
  263.   static char *volume_labels[] = {
  264.     "Low",
  265.     "Medium",
  266.     "High",
  267.     NULL
  268.   };
  269.   struct NewGadget ng;
  270.   struct Gadget *gad;
  271.   int topborder;
  272.  
  273.   if (!(IntuitionBase = OpenLibrary ((UBYTE *) "intuition.library", 37)))
  274.     return "cannot open intuition.library";
  275.   if (!(GadToolsBase = OpenLibrary ((UBYTE *) "gadtools.library", 37)))
  276.     return "cannot open gadtools.library";
  277.   if (!(GfxBase = (struct GfxBase *)
  278.       OpenLibrary ((UBYTE *) "graphics.library", 37)))
  279.     return "cannot open graphics.library";
  280.  
  281.   /* does the font exist? */
  282.   if (!(font = OpenFont (&Topaz8)))
  283.     return "cannot open topaz 8 font";
  284.   CloseFont (font);
  285.  
  286.   if (!(g_screen = LockPubScreen (NULL)))
  287.     return "cannot lock default public screen";
  288.  
  289.   if (!(g_visual_info = GetVisualInfo (g_screen, TAG_END)))
  290.     return "GetVisualInfo() failed";
  291.  
  292.   gad = CreateContext (&g_glist);
  293.  
  294.   topborder = g_screen->WBorTop + (g_screen->Font->ta_YSize + 1);
  295.  
  296.   ng.ng_Width = 20;
  297.   ng.ng_Height = 12;
  298.   ng.ng_TextAttr = &Topaz8;
  299.   ng.ng_VisualInfo = g_visual_info;
  300.   ng.ng_Flags = 0;
  301.  
  302.   for (i=0; i<5; i++)
  303.     for (j=0; j<4; j++) {
  304.       ng.ng_GadgetText = (UBYTE *) labels[i*4+j];
  305.       ng.ng_GadgetID = i*4 + j + 1;
  306.       ng.ng_LeftEdge = 10 + j * 24;
  307.       ng.ng_TopEdge = topborder + 2 + i * 16;
  308.       g_gadgets[ng.ng_GadgetID] = gad =
  309.         CreateGadget (BUTTON_KIND, gad, &ng,
  310.           GA_Disabled, TRUE,
  311.           TAG_END);
  312.     }
  313.  
  314.   ng.ng_GadgetID = GID_PREV;
  315.   ng.ng_GadgetText = (UBYTE *) "Prev";
  316.   ng.ng_Width = 44;
  317.   ng.ng_LeftEdge = 10;
  318.   ng.ng_TopEdge = topborder + 2 + 5 * 16;
  319.   g_gadgets[ng.ng_GadgetID] =
  320.     gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_END);
  321.   
  322.   ng.ng_GadgetID = GID_NEXT;
  323.   ng.ng_GadgetText = (UBYTE *) "Next";
  324.   ng.ng_LeftEdge = 58;
  325.   g_gadgets[ng.ng_GadgetID] =
  326.     gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_END);
  327.  
  328.   ng.ng_GadgetID = GID_START;
  329.   ng.ng_GadgetText = (UBYTE *) "Start";
  330.   ng.ng_LeftEdge = 120;
  331.   ng.ng_TopEdge = topborder + 2 + 4 * 16;
  332.   ng.ng_Width = 120;
  333.   ng.ng_Height = 28;
  334.   g_gadgets[ng.ng_GadgetID] =
  335.     gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_END);
  336.  
  337.   ng.ng_GadgetID = GID_STOP;
  338.   ng.ng_GadgetText = (UB