home *** CD-ROM | disk | FTP | other *** search
/ Mods Anthology 4 / Music-AmigaModsAnthology-4of4-Psychodk.mcsteam.iso / Tools / PC / SIDPLAY.UNX / sidgui.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-02  |  19.7 KB  |  695 lines

  1. #include <stdlib.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4.  
  5. #include <iostream.h>
  6. #include <iomanip.h>
  7. #include <fstream.h>
  8.  
  9. #include <sys/ioctl.h>
  10. #ifdef linux
  11.  #include <linux/soundcard.h>
  12. #elif defined(__FreeBSD__)
  13.  #include <machine/soundcard.h>
  14. #elif defined(sun) && defined(sparc)
  15.  #include <sun/audioio.h>
  16.  //#include <sun/dbriio.h>
  17. #elif define (sgi)
  18.  #include <errno.h>
  19.  #include <audio.h>
  20.  #include <dmedia/audio.h>
  21. #endif
  22.  
  23. #include "mytypes.h"
  24. #include "sidtune.h"
  25. #include "6581.h"
  26.  
  27. extern "C" {
  28.  #include "forms.h"
  29.  #include "gui.h"
  30. }
  31. #include "list.h"
  32. #include <string.h>
  33.  
  34.  
  35.  
  36.  
  37. // before compiling the RCS distribution, consider doing
  38. // a 'co -kv sidplay.cxx' to substitute the keyword string
  39. #define version "1.7"
  40. #if defined(linux) || defined(__FreeBSD__) 
  41.  #define AUDIO "/dev/dsp"
  42. #elif defined(sun) && defined(sparc)
  43.  #define AUDIO "/dev/audio"
  44. #endif
  45.  
  46. #define TXT_TITLE 1
  47. #define ERR_NOT_ENOUGH_MEMORY 4
  48. #define ERR_SYNTAX 5
  49. #define ERR_IOCTL 6
  50.  
  51.  
  52. #define FLAG_PLAYSID 1
  53. #define FLAG_FORCENTSC 2
  54.  
  55. byte globalflags = 0;
  56.  
  57.  
  58. void error( char*, char* );
  59. void printtext( int );
  60.  
  61. ubyte* samplebufferptr;
  62.  
  63.  
  64. sidtune *mysid=NULL;
  65.  
  66. sidemuconfig sidcfg;
  67.  
  68.  
  69.  
  70.  
  71. /*****************************************************************/
  72. /*                 GUI Stuff                                     */
  73. /*****************************************************************/
  74.  
  75.  
  76. // bitmaps for some of the buttons
  77.  
  78. #define stop_width 10
  79. #define stop_height 9
  80. static unsigned char stop_bits[] = {
  81.   0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00,
  82.   0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, };
  83.  
  84. #define play_width 10
  85. #define play_height 9
  86. static unsigned char play_bits[] = {
  87.   0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x3c, 0x00, 0xfc, 0x00, 0x3c, 0x00,
  88.   0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, };
  89.  
  90. #define pause_width 10
  91. #define pause_height 9
  92. static unsigned char pause_bits[] = {
  93.   0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00,
  94.   0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, };
  95.  
  96. #define nextsong_width 10
  97. #define nextsong_height 9
  98. static unsigned char nextsong_bits[] = {
  99.   0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xec, 0x00, 0xfc, 0x00, 0xec, 0x00,
  100.   0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, };
  101.  
  102. #define prevsong_width 10
  103. #define prevsong_height 9
  104. static unsigned char prevsong_bits[] = {
  105.   0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0xdc, 0x00, 0xfc, 0x00, 0xdc, 0x00,
  106.   0x94, 0x00, 0x00, 0x00, 0x00, 0x00, };
  107.  
  108. FD_SIDPlay *gui;
  109. char *filename;
  110. #define NOBUTTONS 0
  111. #define PLAY  1
  112. #define STOP  2
  113. #define PAUSE 4
  114. #define PREVSONG  8
  115. #define NEXTSONG  16
  116. #define REMOVE 32
  117. #define NEXT 64
  118. unsigned int buttons_active;
  119.  
  120. void SetActiveButtons(unsigned int active){
  121.   if (active&PLAY){fl_activate_object(gui->play); fl_set_object_color(gui->play,FL_BITMAPBUTTON_COL1,FL_BITMAPBUTTON_COL2);}
  122.   else{fl_deactivate_object(gui->play);fl_set_object_color(gui->play,FL_INACTIVE_COL,FL_BITMAPBUTTON_COL2);}
  123.   if (active&STOP){fl_activate_object(gui->stop); fl_set_object_color(gui->stop,FL_BITMAPBUTTON_COL1,FL_BITMAPBUTTON_COL2);}
  124.   else{fl_deactivate_object(gui->stop);fl_set_object_color(gui->stop,FL_INACTIVE_COL,FL_BITMAPBUTTON_COL2);}
  125.   if (active&PAUSE){fl_activate_object(gui->pause); fl_set_object_color(gui->pause,FL_BITMAPBUTTON_COL1,FL_BITMAPBUTTON_COL2);}
  126.   else{fl_deactivate_object(gui->pause);fl_set_object_color(gui->pause,FL_INACTIVE_COL,FL_BITMAPBUTTON_COL2);}
  127.   if (active&PREVSONG){fl_activate_object(gui->prevsong); fl_set_object_color(gui->prevsong,FL_BITMAPBUTTON_COL1,FL_BITMAPBUTTON_COL2);}
  128.   else{fl_deactivate_object(gui->prevsong);fl_set_object_color(gui->prevsong,FL_INACTIVE_COL,FL_BITMAPBUTTON_COL2);}
  129.   if (active&NEXTSONG){fl_activate_object(gui->nextsong); fl_set_object_color(gui->nextsong,FL_BITMAPBUTTON_COL1,FL_BITMAPBUTTON_COL2);}
  130.   else{fl_deactivate_object(gui->nextsong);fl_set_object_color(gui->nextsong,FL_INACTIVE_COL,FL_BITMAPBUTTON_COL2);}
  131.   if (active&NEXT){fl_activate_object(gui->next); fl_set_object_color(gui->next,FL_BUTTON_COL1,FL_BUTTON_COL2);}
  132.   else{fl_deactivate_object(gui->next);fl_set_object_color(gui->next,FL_INACTIVE_COL,FL_BUTTON_COL2);}
  133.   if (active&REMOVE){fl_activate_object(gui->remove);fl_set_object_color(gui->remove,FL_BUTTON_COL1,FL_BUTTON_COL2);}
  134.   else{fl_deactivate_object(gui->remove);fl_set_object_color(gui->remove,FL_INACTIVE_COL,FL_BUTTON_COL2);}
  135.   buttons_active=active;
  136. }
  137.  
  138. List<char *>  playlist;
  139.  
  140. void PatchGUI(){
  141.   fl_set_bitmapbutton_data(gui->play,play_width,play_height,play_bits);
  142.   fl_set_bitmapbutton_data(gui->stop,stop_width,stop_height,stop_bits);
  143.   fl_set_bitmapbutton_data(gui->pause,pause_width,pause_height,pause_bits);
  144.   fl_set_bitmapbutton_data(gui->nextsong,nextsong_width,nextsong_height,nextsong_bits);
  145.   fl_set_bitmapbutton_data(gui->prevsong,prevsong_width,prevsong_height,prevsong_bits);
  146. }
  147.  
  148. char *BaseNameOfFilename(char *s){
  149.   
  150.   int count=0,last_slash_pos=-1;
  151.   while(s[count]!='\0'){
  152.     if(s[count]=='/')
  153.       last_slash_pos=count;
  154.     count++;
  155.   }
  156.   return &s[last_slash_pos+1];
  157. }
  158.  
  159.  
  160.  
  161.  
  162. void PlaylistAdd(FL_OBJECT *fl_obj, long data){
  163.   char *filename;
  164.   
  165.   filename=fl_show_fselector("Load",getenv("SIDSONGPATH"),"*","");
  166.   if (filename!=NULL){
  167.     char *tmpstring=(char *)malloc(strlen(filename)+1);
  168.     strcpy(tmpstring,filename);
  169.     //tmpstring[strlen(filename)]='\0';
  170.     playlist.GotoEnd();
  171.     playlist.Insert(tmpstring);
  172.     fl_addto_browser(gui->playlist,BaseNameOfFilename(tmpstring));
  173.     
  174.     //playlist.Print();
  175.   }
  176. }
  177.  
  178. void PlaylistRemove(FL_OBJECT *fl_obj, long data){
  179.   int line=fl_get_browser(gui->playlist);
  180.   if(line!=0){
  181.     fl_delete_browser_line(gui->playlist,line);
  182.     playlist.GotoIndex(line-1);
  183.     playlist.Delete();
  184.     
  185.     SetActiveButtons(buttons_active&(PLAY|STOP|PREVSONG|NEXTSONG|PAUSE));
  186.     
  187.     //playlist.Print();
  188.   }
  189. }
  190.  
  191.  
  192. #define STOPPED 0
  193. #define PLAYING 1
  194. #define PAUSED 2
  195. int player_state=STOPPED;
  196.  
  197. void Stop(FL_OBJECT *fl_obj,long data){
  198.   if (player_state==PLAYING || player_state==PAUSED)
  199.     player_state=STOPPED;
  200.   
  201.   SetActiveButtons(buttons_active&(NEXT|REMOVE)|PLAY);
  202.   if (mysid->returncurrentsong()>1) SetActiveButtons(buttons_active|PREVSONG);
  203.   if (mysid->returncurrentsong()<mysid->returnnumberofsongs()) SetActiveButtons(buttons_active|NEXTSONG);
  204.   if (data==0){
  205.     mysid->initializesong(mysid->returncurrentsong());
  206.   }
  207. }
  208. char *my_itoa(unsigned int i,char *str){
  209.   unsigned int ten=100;
  210.   int j=0;
  211.   while(ten>0){
  212.     if(i/ten == 0 && j==0);
  213.     else{
  214.       str[j++]=(i/ten)+'0';
  215.       i=i-(i/ten)*ten;
  216.     }
  217.     ten=ten/10;
  218.   }
  219.   if (j==0) str[j++]='0';
  220.   str[j]=0;
  221.   return str;
  222. }
  223.  
  224. char *SongOfSongs(int songnr,int songs,char *str){
  225.   my_itoa(songnr,str);
  226.   int sl=strlen(str);
  227.   str[sl]='/';
  228.   my_itoa(songs,str+sl+1);
  229.   return str;
  230. }
  231.  
  232. void Play(FL_OBJECT *fl_obj, long data){
  233.   // if this is a new song or it was stopped then load it and init player
  234.   //mysid->initializesong(mysid->returncurrentsong());
  235.   SetActiveButtons(buttons_active&(NEXT|REMOVE)|STOP|PAUSE);
  236.   
  237.   if (mysid->returncurrentsong()>1) SetActiveButtons(buttons_active|PREVSONG);
  238.   if (mysid->returncurrentsong()<mysid->returnnumberofsongs()) SetActiveButtons(buttons_active|NEXTSONG);
  239.   
  240.   player_state=PLAYING;
  241. }
  242.  
  243. void PrevSong(FL_OBJECT *fl_obj, long data){
  244.   mysid->initializesong(mysid->returncurrentsong()-1);
  245.   
  246.   fl_addto_form(gui->SIDPlay);
  247.   fl_delete_object(gui->song);
  248.   fl_free_object(gui->song);
  249.   char sos[10];
  250.   gui->song = fl_add_box(FL_DOWN_BOX,280,116,254,22,SongOfSongs(mysid->returncurrentsong(),mysid->returnnumberofsongs(),sos));
  251.   fl_set_object_color(gui->song,FL_MCOL,FL_COL1);
  252.   fl_end_form();
  253.   
  254.   SetActiveButtons(buttons_active&(PLAY|STOP|PAUSE|NEXT|REMOVE));
  255.   if (mysid->returncurrentsong()>1) SetActiveButtons(buttons_active|PREVSONG);
  256.   if (mysid->returncurrentsong()<mysid->returnnumberofsongs()) SetActiveButtons(buttons_active|NEXTSONG);
  257. }
  258.  
  259. void NextSong(FL_OBJECT *fl_obj, long data){
  260.   mysid->initializesong(mysid->returncurrentsong()+1);
  261.   fl_addto_form(gui->SIDPlay);
  262.   fl_delete_object(gui->song);
  263.   fl_free_object(gui->song);
  264.   char sos[10];
  265.   gui->song = fl_add_box(FL_DOWN_BOX,280,116,254,22,SongOfSongs(mysid->returncurrentsong(),mysid->returnnumberofsongs(),sos));
  266.   fl_set_object_color(gui->song,FL_MCOL,FL_COL1);
  267.   fl_end_form();
  268.   
  269.   SetActiveButtons(buttons_active&(PLAY|STOP|PAUSE|NEXT|REMOVE));
  270.   if (mysid->returncurrentsong()>1) SetActiveButtons(buttons_active|PREVSONG);
  271.   if (mysid->returncurrentsong()<mysid->returnnumberofsongs()) SetActiveButtons(buttons_active|NEXTSONG);
  272. }
  273.  
  274. void Pause(FL_OBJECT *fl_obj, long data){
  275.    player_state=PAUSED;
  276.    SetActiveButtons(buttons_active&(NEXT|REMOVE)|PLAY|STOP);
  277.  }
  278.  
  279. void SelectSong(FL_OBJECT *fl_obj,long data){
  280.    //Stop(NULL,1);
  281.   int selected=fl_get_browser(fl_obj);
  282.   if(selected!=0){
  283.     playlist.GotoIndex(selected-1);
  284.     filename=playlist.Get();
  285.   }
  286.   char sos[10]="";
  287.   // delete old sidtune
  288.   if (mysid!=NULL)
  289.     delete mysid;
  290.   // load new sidtune
  291.   mysid=new sidtune(filename);
  292.   // handle errors
  293.   if (!*mysid) {
  294.     fl_show_message(mysid->returnstatusstring(),"The song will be removed from the list.",""); 
  295.     PlaylistRemove(gui->remove,0);
  296.  
  297.     SetActiveButtons(NOBUTTONS);
  298.     player_state=STOPPED;
  299.   }
  300.   else{
  301.     if ( globalflags & FLAG_PLAYSID )
  302.       mysid->setplaysidflag( TRUE );
  303.     if ( globalflags & FLAG_FORCENTSC )
  304.       mysid->setforcentsc( TRUE );
  305.     mysid->initializesong(mysid->returnstartsong());
  306.     SongOfSongs(mysid->returncurrentsong(),mysid->returnnumberofsongs(),sos);
  307.     
  308.     if (player_state==PAUSED || player_state==STOPPED){
  309.       player_state=STOPPED;
  310.       SetActiveButtons(REMOVE|NEXT|PLAY);
  311.     }
  312.     else
  313.       SetActiveButtons((buttons_active&(PLAY|STOP|PAUSE))|REMOVE|NEXT);
  314.     if (mysid->returncurrentsong()>1) SetActiveButtons(buttons_active|PREVSONG);
  315.     if (mysid->returncurrentsong()<mysid->returnnumberofsongs()) SetActiveButtons(buttons_active|NEXTSONG);
  316.   }
  317.   // update display
  318.   fl_addto_form(gui->SIDPlay);
  319.   fl_delete_object(gui->title);
  320.   fl_delete_object(gui->author);
  321.   fl_delete_object(gui->copyright);
  322.   fl_delete_object(gui->song);
  323.   fl_free_object(gui->title);
  324.   fl_free_object(gui->author);
  325.   fl_free_object(gui->copyright);
  326.   fl_free_object(gui->song);
  327.   gui->title=fl_add_box(FL_DOWN_BOX,280,208,254,22,mysid->returnnameinfo());
  328.   gui->author = fl_add_box(FL_DOWN_BOX,280,176,254,22,mysid->returnauthorinfo());
  329.   gui->copyright = fl_add_box(FL_DOWN_BOX,280,146,254,22,mysid->returncopyrightinfo());
  330.   gui->song = fl_add_box(FL_DOWN_BOX,280,116,254,22,sos);
  331.   fl_set_object_color(gui->song,FL_MCOL,FL_COL1);
  332.   
  333.   fl_set_object_color(gui->author,FL_MCOL,FL_COL1);
  334.   fl_set_object_color(gui->copyright,FL_MCOL,FL_COL1);
  335.   fl_set_object_color(gui->title,FL_MCOL,FL_COL1);
  336.   
  337.   fl_end_form();
  338.   
  339. }
  340.  
  341. void NextInList(FL_OBJECT *fl_obj,long data){
  342.   int current=fl_get_browser(gui->playlist);
  343.   int max=fl_get_browser_maxline(gui->playlist);
  344.   if (max==0 || current==0) return;
  345.   if (current<max){
  346.     fl_select_browser_line(gui->playlist,current+1);
  347.   }
  348.   else{
  349.     fl_select_browser_line(gui->playlist,1);
  350.   }
  351.   SelectSong(gui->playlist,0);
  352. }
  353.  
  354.  
  355.  
  356.  
  357.  
  358. /*****************************************************************/
  359.  
  360.  
  361. int main(int argc, char *argv[])
  362. {
  363.   // title
  364.   printtext(TXT_TITLE);
  365.   
  366.   //
  367.   ubyte infile = 0;
  368.   
  369.   // defaults
  370.   udword frequency = 22050;
  371.   uword channels = SIDEMU_MONO;
  372.   
  373.   uword fragments = 2;
  374.   uword fragsizebase = 10;
  375.   
  376.   // parse command line arguments
  377.   for ( int a = 1; a < argc; a++)  
  378.   {
  379.     if ( argv[a][0] == '-')  
  380.       {
  381.     // reading from stdin
  382.     if ( strlen(argv[a]) == 1 )
  383.       {    
  384.         if ( infile == 0 )
  385.           {
  386.             infile = a;
  387.             break;
  388.           }
  389.         else 
  390.           printtext(ERR_SYNTAX);
  391.       }
  392.     switch ( argv[a][1] )
  393.       {
  394.       case 'a':
  395.         globalflags |= FLAG_PLAYSID;
  396.         break;
  397.       case 'b':
  398.         if ( argv[a][2] == 'n' )  
  399.           {
  400.         fragments = (unsigned)atoi(argv[a]+3);
  401.         if (( fragments < 2 ) || ( fragments > 255 )) fragments = 2;
  402.           }
  403.         else if ( argv[a][2] == 's' )  
  404.           {
  405.         fragsizebase = (unsigned)atoi(argv[a]+3);
  406.         if (( fragsizebase < 7 ) || ( fragsizebase > 17 )) fragsizebase = 14;
  407.           }
  408.         break;
  409.       case 'f':
  410.         frequency = (udword)atol(argv[a]+2);
  411.         break;
  412.       case 'h':
  413.         printtext(ERR_SYNTAX);
  414.         break;
  415.       case 'n':
  416.         globalflags |= FLAG_FORCENTSC;
  417.         break;
  418.       default:
  419.         printtext(ERR_SYNTAX);
  420.         break;
  421.       }
  422.       }
  423.     else  
  424.       {
  425.     // filename argument
  426.     if ( infile == 0 )  infile = a;
  427.     else printtext(ERR_SYNTAX);
  428.       }
  429.   }
  430.  
  431. // --- Begin of VoxWare dependent initialization part ---
  432.   
  433. #if defined(linux) || defined(__FreeBSD__)
  434.   int audiohd = open(AUDIO, O_WRONLY, 0);
  435.   if ( audiohd == -1 )
  436.     { 
  437.       cerr << "ERROR: Cannot open audio device " << AUDIO << endl;
  438.       exit (-1);
  439.     }
  440.   
  441.   int dsp_samplesize = 8;
  442.   if ( ioctl(audiohd, SNDCTL_DSP_SAMPLESIZE, &dsp_samplesize) == -1 )  printtext(ERR_IOCTL);
  443.   
  444.   int dsp_stereo = 0;
  445.   if ( ioctl(audiohd, SNDCTL_DSP_STEREO, &dsp_stereo ) == -1 )  printtext(ERR_IOCTL);
  446.   
  447.   int dsp_speed = frequency;
  448.   if ( ioctl(audiohd, SNDCTL_DSP_SPEED, &dsp_speed ) == -1 )  printtext(ERR_IOCTL);
  449.   
  450.   // N fragments of size (2 ^ S) bytes
  451.   //              NNNNSSSS
  452.   // int frag = 0x0004000e;
  453.   int frag = ( fragments << 16 ) + fragsizebase;
  454.   ioctl(audiohd, SNDCTL_DSP_SETFRAGMENT, &frag);
  455.   
  456.   int frag_size;
  457.   ioctl(audiohd, SNDCTL_DSP_GETBLKSIZE, &frag_size);
  458.   cout << "Buffers      : " << fragments 
  459.        << "\nBuffersize   : " << (udword)(1 << fragsizebase) << "\n";
  460.   
  461.   if (( samplebufferptr = new ubyte[frag_size]) == 0 )  printtext(ERR_NOT_ENOUGH_MEMORY);
  462.   
  463.   // --- SunOS 4.1.4 with dbri driver dependent part ---
  464. #elif defined(sparc) && defined(sun)
  465.   
  466.   int audiohd = open(AUDIO, O_WRONLY, 0);
  467.   if ( audiohd == -1 )
  468.     { 
  469.       cerr << "ERROR: Cannot open audio device " << AUDIO << endl;
  470.     exit (-1);
  471.     }
  472.   int hwdevice;
  473.   if ( ioctl( audiohd, AUDIO_GETDEV, &hwdevice ) == (-1))  printtext( ERR_IOCTL );
  474.   if ( hwdevice != AUDIO_DEV_SPEAKERBOX )
  475.     {
  476.     cerr << "ERROR: Speakerbox not enabled" << endl;
  477.     exit(-1);
  478.   }
  479.   
  480.   // choose the nearest possible frequency
  481.   uword dbrifreqs[] = 
  482.     {
  483.       8000, 9600, 11025, 16000, 18900, 22050, 32000, 37800, 44100, 48000, 0
  484.       };
  485.   int dbrifsel = 0;
  486.   int dbrifreqdiff = 100000;
  487.   int dbrifrequency = frequency;
  488.   do
  489.     {  
  490.       int dbrifreqdiff2 = frequency - dbrifreqs[dbrifsel];
  491.       dbrifreqdiff2 < 0 ? dbrifreqdiff2 = 0 - dbrifreqdiff2 : dbrifreqdiff2 += 0;
  492.       if ( dbrifreqdiff2 < dbrifreqdiff )  
  493.     {
  494.       dbrifreqdiff = dbrifreqdiff2;
  495.       dbrifrequency = dbrifreqs[dbrifsel];
  496.     }
  497.       dbrifsel++;
  498.   }  while ( dbrifreqs[dbrifsel] != 0 );
  499.   frequency = dbrifrequency;
  500.   
  501.   int dsp_samplesize = 16;
  502.   
  503.   audio_info myaudio_info;
  504.   if ( ioctl( audiohd, AUDIO_GETINFO, &myaudio_info ) == (-1))  printtext(ERR_IOCTL);
  505.   AUDIO_INITINFO( &myaudio_info );
  506.   myaudio_info.play.sample_rate = frequency;
  507.   if ( channels == SIDEMU_MONO )  myaudio_info.play.channels = 1;
  508.   else if ( channels == SIDEMU_STEREO )  myaudio_info.play.channels = 2;
  509.   myaudio_info.play.precision = dsp_samplesize;
  510.   myaudio_info.play.encoding = AUDIO_ENCODING_LINEAR;
  511.   myaudio_info.output_muted = 0;
  512.   if ( ioctl( audiohd, AUDIO_SETINFO, &myaudio_info ) == (-1))  printtext(ERR_IOCTL);
  513.   
  514.   int bufsize = frequency;
  515.   if (( samplebufferptr = new ubyte[bufsize]) == 0 )  printtext(ERR_NOT_ENOUGH_MEMORY);
  516.   
  517.   // --- Silicon Graphics dependent part
  518.   
  519. #elif defined(sgi)
  520.   ALport audio;
  521.   ALconfig config;
  522.   
  523.   long chpars[] = {AL_OUTPUT_RATE, 0};
  524.   
  525.   // Frequency
  526.   
  527.   chpars[1] = frequency;
  528.   ALsetparams(AL_DEFAULT_DEVICE, chpars, 2);
  529.   ALgetparams(AL_DEFAULT_DEVICE, chpars, 2);
  530.   config = ALnewconfig();
  531.  
  532.   // Set sample format
  533.   
  534.   ALsetsampfmt(config, AL_SAMPFMT_TWOSCOMP);
  535.   
  536.   // Mono output
  537.   
  538.   ALsetchannels(config, AL_MONO);
  539.   
  540.   // 8-bit samplesize
  541.  
  542.   ALsetwidth(config, AL_SAMPLE_8);
  543.   
  544.   // Allocate an audio port
  545.   
  546.   if((audio = ALopenport("SIDPLAY sound", "w", config)) == NULL) {
  547.     oserror();
  548.     exit(1);
  549.   }
  550.   
  551.   // Allocate sound buffers
  552.   int bufsize = frequency;
  553.   ALsetqueuesize(config, bufsize);
  554.   
  555.   if (( samplebufferptr = new ubyte[bufsize]) == 0 )  printtext(ERR_NOT_ENOUGH_MEMORY);
  556. #endif /* SGI part */
  557.   
  558.   cout << "Frequency    : " << dec << sidcfg.setfrequency( frequency ) << " Hz" << endl;
  559.   if ( dsp_samplesize != sidcfg.setbitspersample( dsp_samplesize ))
  560.     {
  561.       cerr << "SIDEMU: Not capable of requested sample precision" << endl;
  562.       exit(-1);
  563.     }
  564. #if defined(linux) || defined(__FreeBSD__)
  565.   if ( SIDEMU_UNSIGNED_PCM != sidcfg.setsampleformat( SIDEMU_UNSIGNED_PCM ))
  566. #elif defined(sun) && defined(sparc)
  567.     if ( SIDEMU_SIGNED_PCM != sidcfg.setsampleformat( SIDEMU_SIGNED_PCM ))
  568. #elif defined(sgi)
  569.       if ( SIDEMU_SIGNED_PCM != sidcfg.setsampleformat( SIDEMU_SIGNED_PCM ))
  570. #else
  571. #error Have to set sampleformat 
  572. #endif    
  573.     {
  574.       cerr << "SIDEMU: Not capable of requested sample encoding" << endl;
  575.       exit(-1);
  576.     }
  577. #if defined(linux) || defined(__FreeBSD__)
  578.   //if ( SIDEMU_STEREO != sidcfg.setchannels( SIDEMU_STEREO ))
  579.   //{
  580.   //    cerr << "SIDEMU: Not capable of requested number of channels" << endl;
  581.   //  exit(-1);
  582.   //}
  583. #endif    
  584.   if ( sidemuinit( sidcfg ) == FALSE )  
  585.     {
  586.       cerr << "SIDEMU: Unable to allocate enough memory" << endl;
  587.       exit(-1);
  588.     }
  589.   sidemureset( sidcfg );
  590.   
  591.   // start the GUI
  592.   fl_initialize(argv[0],"SIDPLAY",0,0,&argc,argv);
  593.   gui=create_form_SIDPlay();
  594.   PatchGUI();
  595.   fl_show_form(gui->SIDPlay,FL_PLACE_GEOMETRY,FL_FULLBORDER,"SIDPLAY 1.7");
  596.   SetActiveButtons(NOBUTTONS);
  597.   
  598.   
  599.  
  600.   //  mysid->initializesong(mysid->returncurrentsong());
  601.   
  602.   
  603.  
  604.   //cout << "Playing, press ^C to stop ...\n" << flush;
  605.   while(1){
  606.     while(player_state==STOPPED || player_state==PAUSED)
  607.       fl_check_forms();
  608.     while ( player_state==PLAYING )
  609.       {
  610.     fl_check_forms();
  611.     if(player_state==STOPPED || player_state==PAUSED) break;
  612.     
  613. #if defined(linux) || defined(__FreeBSD__)
  614.     sidemufillbuffer( sidcfg, *mysid, samplebufferptr, frag_size );
  615.     write( audiohd, samplebufferptr, frag_size );
  616. #elif defined(sparc) && defined(sun)
  617.     sidemufillbuffer( sidcfg, *mysid, samplebufferptr, bufsize );
  618.     write( audiohd, samplebufferptr, bufsize );
  619. #elif defined(sgi)
  620.     sidemufillbuffer( sidcfg, *mysid, samplebufferptr, bufsize );
  621.     ALwritesamps( audio, samplebufferptr, bufsize );
  622. #endif    
  623.       }
  624.   }
  625.   
  626.   // will possibly never come this far  
  627. #if defined(linux) || defined(__FreeBSD__)
  628.   close(audiohd);
  629. #elif defined(sparc) && defined(sun)
  630.   close(audiohd);
  631. #elif defined(sgi)
  632.   ALcloseport(audio);
  633.   ALfreeconfig(config);
  634. #endif
  635.   delete(samplebufferptr);
  636.   return(0);
  637. }
  638.  
  639.  
  640. void error(char* s1, char* s2 = "")
  641. {
  642.   cerr << "ERROR: " << s1 << ' ' << "'" << s2 << "'\n";
  643.   exit(-1);
  644. }
  645.  
  646.  
  647. void printtext(int number)
  648. {
  649.   switch (number)  
  650.   {
  651.    case TXT_TITLE:
  652. #ifdef __FreeBSD__
  653.       cout << endl << "SIDPLAY/FreeBSD";
  654. #elif defined(linux)
  655.       cout << endl << "SIDPLAY/Linux";
  656. #elif defined(sun)
  657.       cout << endl << "SIDPLAY/SunOS";
  658. #elif defined(sgi)
  659.       cout << endl << "SIDPLAY/SGI";
  660. #else
  661.       cout << endl << "SIDPLAY";
  662. #endif      
  663.       cout << "   Music player and C64 SID chip emulator   Version " << version << endl
  664.            << "Copyright (c) 1995,1996 Michael Schwendt   All rights reserved." << endl
  665.            << "Internet e-mail: 3schwend@informatik.uni-hamburg.de" << endl;
  666. #if defined(sgi)
  667.       cout << "Ported by <aagero@aage.aage.priv.no>" << endl;
  668. #else 
  669.       cout << endl;
  670. #endif    
  671.       cout << "GUI by Brian Nielsen <norman@iesd.auc.dk>" << endl << endl;
  672.       break;
  673.     case ERR_NOT_ENOUGH_MEMORY:
  674.       cerr << "ERROR: Not enough memory\n";
  675.       exit(-1);
  676.     case ERR_SYNTAX:
  677.       cout << " Syntax: SIDGUI [-<commands>]\n"
  678.            << " commands: -h       display this screen\n"
  679.            << "           -f<num>  set frequency in Hz (default: 22050)\n"
  680.            << "           -a       improve PlaySID compatibility (read the docs !)\n"
  681.            << "           -bn<num> set number of audio buffers to use\n"
  682.            << "           -bs<num> set size 2^<num> of audio buffers\n\n";
  683.       exit(-1);
  684.     case ERR_IOCTL:
  685.       cerr << "IOCTL: Could not set up sound device properly\n";
  686.       exit(-1);
  687.     default:
  688.       cerr << "ERROR: Internal system error\n";
  689.       exit(-1);
  690.   }
  691. }
  692.  
  693.  
  694.  
  695.