home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / disk / cdrom / playcdda / play.c < prev    next >
C/C++ Source or Header  |  1993-12-21  |  25KB  |  977 lines

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