home *** CD-ROM | disk | FTP | other *** search
/ ftp.4front-tech.com / ftp.4front-tech.com.tar / ftp.4front-tech.com / ossfree / snd-util-3.8.tar.gz / snd-util-3.8.tar / sndkit / mplay / main.c next >
C/C++ Source or Header  |  1997-02-25  |  5KB  |  301 lines

  1. #define DEB(stmt)    /* stmt    */    /* For debug printing */
  2. #define DEB2(stmt)    /* stmt */        /* For debug printing */
  3. #define DEB3(stmt)    stmt         /* For debug printing */
  4. #define DEB_ALWAYS(stmt)    stmt    /* Interesting things */
  5.  
  6. #define _INCLUDE_POSIX_SOURCE 1
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <fcntl.h>
  12. #include <sys/errno.h>
  13. #include <sys/soundcard.h>
  14.  
  15. #ifndef SOUND_VERSION
  16. #   error At least version 3.8 of sys/soundcard.h is required.
  17. #else
  18. #   if SOUND_VERSION < 0x0307f0
  19. #      error At least version 3.8 of sys/soundcard.h is required.
  20. #   endif
  21. #endif
  22.  
  23. extern int errno;
  24.  
  25. #include "mlib.h"
  26.  
  27. SEQ_DEFINEBUF(1024);
  28.  
  29. int seqfd;
  30. mlib_track *tracks[1024];
  31. int ntrks = 0;
  32. int dev = 0;
  33.  
  34. #ifndef OSSLIB
  35. void
  36. seqbuf_dump ()
  37. {
  38.   if (_seqbufptr)
  39.     if (write (seqfd, _seqbuf, _seqbufptr) == -1)
  40.       {
  41.     perror ("write /dev/music");
  42.     exit (-1);
  43.       }
  44.   _seqbufptr = 0;
  45. }
  46. #endif
  47.  
  48. void
  49. player()
  50. {
  51.         int i, track;
  52.         int prev_time = 0;
  53.     
  54.         int ptrs[1024] = {0};
  55.         unsigned char *ptr;
  56.         unsigned char *event;
  57.         int time, n = 0;
  58.  
  59. #if 1
  60.         for (track = 0;track<ntrks;track++)
  61.         for (i=0;i<128;i++)
  62.         {
  63.             if (tracks[track]->pgm_map[i] != -1)
  64.             {
  65.                n++;
  66.                SEQ_LOAD_GMINSTR(dev, i);
  67.             }
  68.             tracks[track]->pgm_map[i] = i;
  69.  
  70.             if (n == 0) /* No program changes. Assume pgm# 0 */
  71.                SEQ_LOAD_GMINSTR(dev, 0);
  72.  
  73.             if (tracks[track]->drum_map[i] != -1)
  74.                SEQ_LOAD_GMDRUM(dev, i);
  75.             tracks[track]->drum_map[i] = i;
  76.         }
  77.  
  78.         if (n == 0)    /* No program changes detected */
  79.            SEQ_LOAD_GMINSTR(dev, 0); /* Acoustic piano */
  80.  
  81.         SEQ_START_TIMER();
  82.         while (1)
  83.         {
  84.             int best = -1, best_time = 0x7fffffff;
  85.  
  86.             for (i=0;i<ntrks;i++)
  87.             if (ptrs[i] < tracks[i]->len)
  88.               {
  89.                 ptr = &(tracks[i]->events[ptrs[i]*12]);
  90.                 event = &ptr[4];
  91.                 time = *(int*)ptr;
  92.  
  93.                 if (time < best_time)
  94.                 {
  95.                     best = i;
  96.                     best_time = time;
  97.                 }
  98.               }
  99.  
  100.             if (best == -1) return;
  101.  
  102.             ptr = &(tracks[best]->events[ptrs[best]*12]);
  103.             event = &ptr[4];
  104.             time = *(int*)ptr;
  105.             ptrs[best]++;
  106.  
  107.             if (event[0] < 128)
  108.               {
  109.               }
  110.             else
  111.               {
  112.                     int j;
  113.  
  114.                   if (time > prev_time)
  115.                     {
  116.                         SEQ_WAIT_TIME(time);
  117.                         prev_time = time;
  118.                     }
  119.  
  120.                  if (event[0] == EV_SYSEX)
  121.                  {
  122.                       event[1] = dev;
  123.                  }
  124.  
  125.                    if ((event[0] & 0xf0) == 0x90)
  126.                     {
  127.                       event[1] = dev;
  128.  
  129.                       if (event[0] == EV_CHN_COMMON &&
  130.                          event[2] == MIDI_PGM_CHANGE)
  131.                         {
  132.                             event[4] = tracks[best]->pgm_map[event[4]];
  133.                         }
  134.                     }
  135.  
  136.                    _SEQ_NEEDBUF(8);
  137.                    memcpy(&_seqbuf[_seqbufptr], event, 8);
  138.                    _SEQ_ADVBUF(8);
  139.  
  140.               }
  141.         }
  142.  
  143. #endif
  144. }
  145.  
  146. int
  147. find_device(int default_dev)
  148. {
  149.   int i, n;
  150.   struct synth_info info;
  151.  
  152.   if (ioctl (seqfd, SNDCTL_SEQ_NRSYNTHS, &n) == -1)
  153.     {
  154.       perror ("/dev/music");
  155.       exit (-1);
  156.     }
  157.  
  158.   for (i = 0; i < n; i++)
  159.     {
  160.       info.device = i;
  161.  
  162.       if (ioctl (seqfd, SNDCTL_SYNTH_INFO, &info) == -1)
  163.     {
  164.       perror ("/dev/music");
  165.       exit (-1);
  166.     }
  167.  
  168.       if (info.synth_type == SYNTH_TYPE_SAMPLE
  169.       && info.synth_subtype == SAMPLE_TYPE_BASIC)
  170.       {
  171.       return i;
  172.       }
  173.     }
  174.  
  175.     return default_dev;
  176. }
  177.  
  178. void
  179. list_devices(void)
  180. {
  181.   int i, n;
  182.   struct synth_info info;
  183.  
  184.   if ((seqfd=open("/dev/music", O_RDWR, 0))==-1)
  185.   {
  186.       perror("/dev/music");
  187.       exit(-1);
  188.   }
  189.  
  190.   if (ioctl (seqfd, SNDCTL_SEQ_NRSYNTHS, &n) == -1)
  191.     {
  192.       perror ("/dev/music");
  193.       exit (-1);
  194.     }
  195.  
  196.   fprintf(stderr, "Possible device numbers (dev#) are:\n");
  197.   for (i = 0; i < n; i++)
  198.     {
  199.       info.device = i;
  200.  
  201.       if (ioctl (seqfd, SNDCTL_SYNTH_INFO, &info) == -1)
  202.     {
  203.       perror ("/dev/music");
  204.       exit (-1);
  205.     }
  206.  
  207.       fprintf(stderr, "\t%d: %s\n", i, info.name);
  208.     }
  209.  
  210. }
  211.  
  212. int main(int argc, char *argv[])
  213. {
  214.     mlib_desc *mdesc;
  215.     int was_last;
  216.     int tmp, argp=1;
  217.  
  218.     if (argc < 2)
  219.     {
  220.         fprintf(stderr, "Usage: %s [dev#] midifile\n", argv[0]);
  221.         list_devices();
  222.         exit(-1);
  223.     }
  224.  
  225.     if ((seqfd=open("/dev/music", O_RDWR, 0))==-1)
  226.       {
  227.           perror("/dev/music");
  228.           exit(-1);
  229.       }
  230.        
  231.     if (isdigit(argv[argp][0]))
  232.         dev = atoi(argv[argp++]);
  233.     else
  234.        dev = find_device(dev);
  235.  
  236. #ifdef OSSLIB
  237.     OSS_init(seqfd, 1024);
  238. #endif
  239.  
  240.     tmp=dev;
  241.     ioctl(seqfd, SNDCTL_FM_4OP_ENABLE, &tmp);
  242.  
  243. #if 0
  244.     tmp=dev;
  245.     ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &tmp);
  246. #endif
  247.  
  248.     if ((mdesc = mlib_open(argv[argp]))==NULL)
  249.     {
  250.         fprintf(stderr, "Can't open MIDI file %s: %s\n",
  251.             argv[argp], mlib_errmsg());
  252.         exit(-1);
  253.     }
  254.  
  255.     tmp = mdesc->hdr.division;
  256.     if (ioctl(seqfd, SNDCTL_TMR_TIMEBASE, &tmp)==-1)
  257.     {
  258.         perror("Set timebase");
  259.         exit(-1);
  260.     }
  261.  
  262.     tmp = 100;
  263.     if (ioctl(seqfd, SNDCTL_TMR_TEMPO, &tmp)==-1)
  264.     {
  265.         perror("Set tempo");
  266.         exit(-1);
  267.     }
  268.  
  269.     ntrks = 0;
  270.  
  271.     while ((tracks[ntrks]=mlib_loadtrack(mdesc, &was_last))!=NULL)
  272.     {
  273.         int i;
  274.  
  275.         DEB2(printf("Loaded track %03d: len = %d events, flags = %08x\n",
  276.             mdesc->curr_trk, tracks[ntrks]->len, tracks[ntrks]->flags));
  277.         ntrks++;
  278.     }
  279.  
  280.     if (!was_last)
  281.     {
  282.        fprintf(stderr, "%s: %s\n", argv[1], mlib_errmsg());
  283.        exit(-1);
  284.     }
  285.  
  286.     tmp = (int)mdesc->timesig;
  287.     /* printf("Setting timesig to %08x\n", tmp); */
  288.     if (ioctl(seqfd, SNDCTL_TMR_METRONOME, &tmp)==-1)
  289.     {
  290. /*        perror("Set metronome"); */
  291.     }
  292.  
  293.     player();
  294.     SEQ_DELTA_TIME(
  295.         mdesc->hdr.division*4);
  296.     SEQ_DUMPBUF();
  297.  
  298.     mlib_close(mdesc);
  299.     exit(0);
  300. }
  301.