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 / dsp / str / strplay.c < prev   
C/C++ Source or Header  |  1980-01-01  |  13KB  |  515 lines

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #ifdef __STDC__
  5. #include <string.h>
  6. #else /* __STDC__ */
  7. #include <strings.h>
  8. #endif /* __STDC__ */
  9. #include <sys/types.h>
  10.  
  11. #include <sys/soundcard.h>
  12. #include "str.h"
  13.  
  14. extern int audio;
  15. extern unsigned char *audiobuf;
  16. extern int abuf_ptr;
  17. extern int abuf_size;
  18.  
  19. extern char *command;
  20. extern int quiet_mode, verbose_mode;
  21. extern int mute[4];
  22. extern int dsp_stereo;
  23. extern int dsp_samplesize;
  24. extern long dsp_speed;
  25.  
  26. extern FILE *fp;
  27.  
  28. static int VSYNC;    /* number of sample bytes to output in 1/50 sec */
  29.  
  30. static int notes, channel, vsync, bytes, pat_num;    /* loop variables */
  31. static int note, pat;
  32. static int end_pattern;
  33.  
  34. /* song data and parameters */
  35. static int speed;
  36. static char songlength, songrepeat, tune[128];
  37. static int nvoices;
  38. static Voice voices[32];
  39. static char num_patterns;
  40. static Pattern patterns[128];
  41. static Channel ch[4];
  42.  
  43. /* table for generating pitches */
  44. static int step_table[1024];
  45.  
  46. /* sine wave table for the vibrato effect */
  47. static int sin_table[] = {
  48.     0x00, 0x18, 0x31, 0x4A, 0x61, 0x78, 0x8D, 0xA1,
  49.     0xB4, 0xC5, 0xD4, 0xE0, 0xEB, 0xF4, 0xFA, 0xFD,
  50.     0xFF, 0xFD, 0xFA, 0xF4, 0xEB, 0xE0, 0xD4, 0xC5,
  51.     0xB4, 0xA1, 0x8D, 0x78, 0x61, 0x4A, 0x31, 0x18
  52. };
  53.  
  54. /* period table for notes C0-B2, used for arpeggio effect */
  55. static int periods[] = {
  56.     0x358, 0x328, 0x2FA, 0x2D0, 0x2A6, 0x280,
  57.     0x25C, 0x23A, 0x21A, 0x1FC, 0x1E0, 0x1C5,
  58.     0x1AC, 0x194, 0x17D, 0x168, 0x153, 0x140,
  59.     0x12E, 0x11D, 0x10D, 0x0FE, 0x0F0, 0x0E2,
  60.     0x0D6, 0x0CA, 0x0BE, 0x0B4, 0x0AA, 0x0A0,
  61.     0x097, 0x08F, 0x087, 0x07F, 0x078, 0x071
  62. };
  63.  
  64. /* skip n bytes of file f - stdin has no fseek */
  65. void 
  66. byteskip(f, n)
  67. FILE *f;
  68. int n;
  69. {
  70.     while(n--)
  71.     fgetc(f);
  72. }
  73.  
  74. /* get string of length <len> from file f */
  75. char *
  76. getstring(f, len)
  77. FILE *f;
  78. int len;
  79. {
  80.     static char s[256];
  81.     int i;
  82.  
  83.     for(i = 0; i < len; i++) {
  84.     if((s[i] = fgetc(f)) == '\1')
  85.         s[i] = '\0';        /* bug fix for some few modules */
  86.     if(s[i] < 32 && s[i]) {
  87.         fprintf(stderr, "This is not a string. Wrong format?\n");
  88.         exit(EXIT_FAILURE);
  89.     }
  90.     }
  91.     s[len] = '\0';
  92.  
  93.     return s;
  94. }
  95.  
  96. void 
  97. audioput(c)
  98. int c;
  99. {
  100.     audiobuf[abuf_ptr++] = c;
  101.     if(abuf_ptr >= ABUF_SIZE) {
  102.     if(write(audio, audiobuf, abuf_ptr) == -1) {
  103.         perror("audio_write");
  104.         exit(EXIT_FAILURE);
  105.     }
  106.     abuf_ptr = 0;
  107.     }
  108. }
  109.  
  110. void
  111. audioput16(c)
  112. int c;
  113. {
  114.     audiobuf[abuf_ptr++] = c & 0xFF;
  115.     audiobuf[abuf_ptr++] = c >> 8;
  116.     if((abuf_ptr + 1) >= ABUF_SIZE) {
  117.     if(write(audio, audiobuf, abuf_ptr) == -1) {
  118.         perror("audio_write");
  119.         exit(EXIT_FAILURE);
  120.     }
  121.     abuf_ptr = 0;
  122.     }
  123. }
  124.  
  125. void
  126. play_song()
  127. {
  128.     int i;
  129.  
  130.     /* set up pitch table:
  131.      * 3576872 is the base clock frequency of the Amiga's Paula chip,
  132.      * the pitch i is the number of cycles between outputting two samples.
  133.      * => i / 3576872 is the delay between two bytes
  134.      * => our_freq * i / 3576872 is our delay.
  135.      * The 65536 are just there for accuracy of integer operations (<< 16).
  136.      */
  137.     step_table[0] = 0;
  138.     for(i = 1; i < 1024; i++)
  139.     step_table[i] = (int) (((3575872.0 / dsp_speed) / i) * 65536.0);
  140.  
  141.     /* VSYNC is the number of bytes in 1/50 sec
  142.      * computed as freq * (1 / 50).
  143.      */
  144.     VSYNC = (dsp_speed + 25) / 50;    /* with round */
  145.  
  146.     /* read song name */
  147.     if(quiet_mode)
  148.     byteskip(fp, 20);
  149.     else
  150.     printf("Module : %s\n\n", getstring(fp, 20));
  151.  
  152.     /* determine number of voices from command name */
  153.     nvoices = strstr(command, "15") == NULL? 31: 15;
  154.  
  155.     /* read in the sample information tables */
  156.     voices[0].length = 0;
  157.     for(i = 1; i <= nvoices; i++) {
  158.     /* sample name */
  159.     if(quiet_mode)
  160.         byteskip(fp, 22);
  161.     else if(nvoices == 15)
  162.         printf("%6d : %s\n", i, getstring(fp, 22));
  163.     else {
  164.         printf("%6d : %22s", i, getstring(fp, 22));
  165.         if(!(i & 1))
  166.         printf("\n");
  167.     }
  168.     /* the sample length and repeat data are stored as numbers of words,
  169.      * we want the number of bytes << 16.
  170.      */
  171.     voices[i].length = (fgetc(fp) << 25) | (fgetc(fp) << 17);
  172.     fgetc(fp);
  173.     if((voices[i].volume = fgetc(fp)) > 64)
  174.         voices[i].volume = 64;
  175.     voices[i].rep_start = (fgetc(fp) << 25) | (fgetc(fp) << 17);
  176.     voices[i].rep_end = (fgetc(fp) << 25) | (fgetc(fp) << 17);
  177.     if(voices[i].rep_end <= 4 << 16)
  178.         voices[i].rep_end = 0;
  179.     else {
  180.         voices[i].rep_end += voices[i].rep_start;
  181.         if(voices[i].rep_end > voices[i].length)
  182.         voices[i].rep_end = voices[i].length;
  183.     }
  184.     }
  185.  
  186.     /* read sequence data: length and repeat position */
  187.     songlength = fgetc(fp);
  188.     songrepeat = fgetc(fp);
  189.     if(songrepeat > songlength)        /* this is often buggy in modules */
  190.     songrepeat = 0;
  191.  
  192.     /* read in the sequence and determine the number of patterns
  193.      * by looking for the highest pattern number.
  194.      */
  195.     num_patterns = 0;
  196.     for(i = 0; i < 128; i++) {
  197.     tune[i] = fgetc(fp);
  198.     if(tune[i] > num_patterns)
  199.         num_patterns = tune[i];
  200.     }
  201.     num_patterns++;            /* pattern numbers begin at 0 */
  202.  
  203.     /* skip over sig in new modules (usually M.K.).
  204.      * note: this sig could be used for determining whether the module
  205.      * is of an old type (15 samples max) or new (up to 31 samples)
  206.      */
  207.     if(nvoices == 31)
  208.     byteskip(fp, 4);
  209.  
  210.     /* read in the patterns.
  211.      * Each pattern consists of 64 lines,
  212.      * each containing data for the four voices.
  213.      */
  214.     for(pat_num = 0; pat_num < num_patterns; pat_num++)
  215.     for(notes = 0; notes < 64; notes++)
  216.         for(channel = 0; channel < 4; channel++) {
  217.         note = (fgetc(fp) << 8) | fgetc(fp);
  218.         patterns[pat_num].sample[notes][channel] = (note >> 8) & 0x10;
  219.         patterns[pat_num].period[notes][channel] =
  220.             MIN(note & 0xFFF, 1023);
  221.         note = (fgetc(fp) << 8) | fgetc(fp);
  222.         patterns[pat_num].sample[notes][channel] |= note >> 12;
  223.         patterns[pat_num].effect[notes][channel] = (note >> 8) & 0xF;
  224.         patterns[pat_num].params[notes][channel] = note & 0xFF;
  225.         }
  226.  
  227.     /* store each sample as an array of char */
  228.     for(i = 1; i <= nvoices; i++)
  229.     if(voices[i].length) {
  230.         if((voices[i].info = malloc(voices[i].length >> 16)) == NULL) {
  231.         fprintf(stderr, "%s: can't allocate memory\n", command);
  232.         exit(EXIT_FAILURE);
  233.         }
  234.         fread(voices[i].info, 1, voices[i].length >> 16, fp);
  235.         if(voices[i].rep_end)
  236.         voices[i].length = voices[i].rep_end;
  237.         voices[i].rep_start -= voices[i].length;
  238.     }
  239.  
  240.     /* initialize global and channel replay data */
  241.     speed = 6;
  242.     for(i = 0; i < 4; i++) {
  243.     ch[i].pointer = 0;
  244.     ch[i].step = 0;
  245.     ch[i].volume = 0;
  246.     ch[i].pitch = 0;
  247.     }
  248.  
  249.     if(!quiet_mode)
  250.     if(verbose_mode)
  251.         printf("\n");
  252.     else {
  253.         printf("\nPosition (%d):", songlength);
  254.         fflush(stdout);
  255.     }
  256.  
  257.  
  258.     /*******************************/
  259.     /* Here begins the replay part */
  260.     /*******************************/
  261.  
  262.     for(pat_num = 0; pat_num < songlength; pat_num++) {
  263.     pat = tune[pat_num];
  264.  
  265.     if(!quiet_mode)
  266.         if(verbose_mode)
  267.         printf("   --------------+--------------+--------------+-----"
  268.             "---------  %02X (%02X) = %02X\n", pat_num,
  269.             songlength, pat);
  270.         else {
  271.         printf("\r\t\t%3d", pat_num);
  272.         fflush(stdout);
  273.         }
  274.  
  275.     end_pattern = FALSE;
  276.     for(notes = 0; notes < 64; notes++) {
  277.         int samp, pitch, cmd, para;
  278.         Channel *curch;
  279.  
  280.         if(!quiet_mode && verbose_mode)
  281.         printf("%02X ", notes);
  282.  
  283.         curch = ch;
  284.         for(channel = 0; channel < 4; channel++, curch++) {
  285.         samp = patterns[pat].sample[notes][channel];
  286.         pitch = patterns[pat].period[notes][channel];
  287.         cmd = patterns[pat].effect[notes][channel];
  288.         para = patterns[pat].params[notes][channel];
  289.  
  290.         if(verbose_mode && !quiet_mode)
  291.             if(pitch)
  292.             printf("  %03X %2X %X%02X%s", pitch, samp, cmd, para,
  293.                 channel == 3? "\n": "  |");
  294.             else
  295.             printf("  --- %2X %X%02X%s", samp, cmd, para,
  296.                 channel == 3? "\n": "  |");
  297.  
  298.         if(mute[channel]) {
  299.             if(cmd == 0x0B || cmd == 0x0D || cmd == 0x0F)
  300.             switch(cmd) {
  301.             case 0xB:            /* Pattern jump */
  302.                 end_pattern = TRUE;
  303.                 pat_num = (para & 0xF) + (10 * (para >> 4));
  304.                 break;
  305.             case 0xD:            /* Pattern break */
  306.                 end_pattern = TRUE;
  307.                 break;
  308.             case 0xF:            /* Set speed */
  309.                 speed = para;
  310.                 break;
  311.             }
  312.             continue;
  313.         }
  314.  
  315.         /* if a sample number is given, it is loaded and the note
  316.          * is restarted
  317.          */
  318.         if(samp) {
  319.             curch->samp = samp;
  320.             /* load new instrument */
  321.             curch->volume = voices[samp].volume;
  322.         }
  323.  
  324.         if(samp || (pitch && cmd != 3)) {
  325.             if(pitch)
  326.             curch->pitch = curch->arp[0] = pitch;
  327.             curch->pointer = 0;
  328.             curch->viboffs = 0;
  329.         }
  330.  
  331.         /* by default there is no effect */
  332.         curch->doarp = FALSE;
  333.         curch->doslide = FALSE;
  334.         curch->doporta = FALSE;
  335.         curch->dovib = FALSE;
  336.         curch->doslidevol = FALSE;
  337.  
  338.         switch(cmd) {            /* Do effects */
  339.         case 0:                /* Arpeggio */
  340.             if(para) {
  341.             for(i = 0; i < 36 && periods[i] > curch->arp[0]; i++);
  342.             if(i + (para >> 4) < 36 && i + (para & 0xF) < 36) {
  343.                 curch->doarp = TRUE;
  344.                 curch->arp[0] = periods[i];
  345.                 curch->arp[1] = periods[i + (para >> 4)];
  346.                 curch->arp[2] = periods[i + (para & 0xF)];
  347.             }
  348.             }
  349.             break;
  350.         case 1:                /* Portamento up */
  351.             curch->doslide = TRUE;
  352.             if(para)
  353.             curch->slide = -para;
  354.             break;
  355.         case 2:                /* Portamento down */
  356.             curch->doslide = TRUE;
  357.             if(para)
  358.             curch->slide = para;
  359.             break;
  360.         case 3:                /* Note portamento */
  361.             curch->doporta = TRUE;
  362.             if(para)
  363.             curch->portarate = para;
  364.             if(pitch)
  365.             curch->pitchgoal = pitch;
  366.             break;
  367.         case 4:                /* Vibrato */
  368.             curch->dovib = TRUE;
  369.             if(para) {
  370.             curch->vibspeed = (para >> 2) & 0x3C;
  371.             curch->vibamp = para & 0xF;
  372.             }
  373.             break;
  374.         case 0xA:            /* Volume slide */
  375.             curch->doslidevol = TRUE;
  376.             if(para) {
  377.             if(!(para & 0xF0))
  378.                 curch->volslide = -para;
  379.             else
  380.                 curch->volslide = (para >> 4);
  381.             }
  382.             break;
  383.         case 0xB:            /* Pattern jump */
  384.             end_pattern = TRUE;
  385.             pat_num = (para & 0xF) + (10 * (para >> 4));
  386.             break;
  387.         case 0xC:            /* Set volume */
  388.             curch->volume = MIN(para, 64);
  389.             break;
  390.         case 0xD:            /* Pattern break */
  391.             end_pattern = TRUE;
  392.             break;
  393.         case 0xF:            /* Set speed */
  394.             speed = para;
  395.             break;
  396.         default:
  397.             /* printf(" [%d][%d] ", cmd, para); */
  398.             break;
  399.         }
  400.         }
  401.  
  402.         {
  403.         register Channel *curch;
  404.         register Voice *curv;
  405.  
  406.         for(vsync = 0; vsync < speed; vsync++) {
  407.  
  408.             ch[0].step = step_table[ch[0].pitch];
  409.             ch[1].step = step_table[ch[1].pitch];
  410.             ch[2].step = step_table[ch[2].pitch];
  411.             ch[3].step = step_table[ch[3].pitch];
  412.  
  413.             for(bytes = 0; bytes < VSYNC; bytes++) {
  414.             int byte[2] = { 0, 0 };
  415.  
  416.             curch = ch;
  417.             for(channel = 0; channel < 4; channel++, curch++) {
  418.                 if(!curch->samp || mute[channel])
  419.                 continue;
  420.  
  421.                 curv = &voices[(int) curch->samp];
  422.  
  423.                 /* test for end of sample */
  424.                 if(curch->pointer >= curv->length)
  425.                 if(!curv->rep_end)
  426.                     continue;
  427.                 else
  428.                     curch->pointer += curv->rep_start;
  429.  
  430.                 /* mix samples.
  431.                  * the sample is read and multiplied by the volume
  432.                  */
  433.                 if(curch->pointer < curv->length)
  434.                 /* in stereo, channels 1 & 3 and 2 & 4 are mixed
  435.                  * seperately
  436.                  */
  437.                 byte[channel & dsp_stereo] += (int)
  438.                     ((curv->info[curch->pointer >> 16]) *
  439.                     ((int) curch->volume << 2));
  440.                 /* advance the sample pointer */
  441.                 curch->pointer += curch->step;
  442.             }
  443.  
  444.             /* output sample */
  445.             if(dsp_samplesize == 8) {
  446.                 if(dsp_stereo) {
  447.                 byte[0] >>= 9;
  448.                 audioput(byte[0] + 128);
  449.                 byte[1] >>= 9;
  450.                 audioput(byte[1] + 128);
  451.                 } else
  452.                 audioput((byte[0] >> 10) + 128);
  453.             } else {
  454.                 if(dsp_stereo) {
  455.                 audioput16(byte[0] >> 1);
  456.                 audioput16(byte[1] >> 1);
  457.                 } else
  458.                 audioput16(byte[0] >> 2);
  459.             }
  460.             }
  461.  
  462.             /* Do end of vsync */
  463.             if(vsync == 0)
  464.             continue;
  465.             curch = ch;
  466.             for(channel = 0; channel < 4; channel++, curch++) {
  467.             if(mute[channel])
  468.                 continue;
  469.             if(curch->doarp)
  470.                 curch->pitch = curch->arp[vsync % 3];
  471.             else if(curch->doslide) {
  472.                 curch->arp[0] += curch->slide;
  473.                 curch->arp[0] = MIN(curch->arp[0], 1023);
  474.                 curch->arp[0] = MAX(curch->arp[0], 113);
  475.                 curch->pitch = curch->arp[0];
  476.             } else if(curch->doporta) {
  477.                 if(curch->arp[0] < curch->pitchgoal) {
  478.                 curch->arp[0] += curch->portarate;
  479.                 if(curch->arp[0] > curch->pitchgoal)
  480.                     curch->arp[0] = curch->pitchgoal;
  481.                 } else if(curch->arp[0] > curch->pitchgoal) {
  482.                 curch->arp[0] -= curch->portarate;
  483.                 if(curch->arp[0] < curch->pitchgoal)
  484.                     curch->arp[0] = curch->pitchgoal;
  485.                 }
  486.                 curch->pitch = curch->arp[0];
  487.             } else if(curch->dovib) {
  488.                 if(curch->viboffs & 0x80)
  489.                 curch->pitch = curch->arp[0] - ((sin_table
  490.                     [(curch->viboffs >> 2) & 0x1F] *
  491.                     curch->vibamp) >> 6);
  492.                 else
  493.                 curch->pitch = curch->arp[0] + ((sin_table
  494.                     [(curch->viboffs >> 2) & 0x1F] *
  495.                     curch->vibamp) >> 6);
  496.                 curch->viboffs += curch->vibspeed;
  497.             } else if(curch->doslidevol) {
  498.                 curch->volume += curch->volslide;
  499.                 if(curch->volume < 0)
  500.                 curch->volume = 0;
  501.                 else if(curch->volume >= 64)
  502.                 curch->volume = 64;
  503.             }
  504.             }
  505.         }
  506.         }
  507.         if(end_pattern == 1)
  508.         break;
  509.     }
  510.     }
  511.  
  512.     if(!quiet_mode)
  513.     printf("\n");
  514. }
  515.