home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / sonido / mod-0.000 / mod-0 / mod / effects.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-26  |  16.7 KB  |  679 lines

  1. /*
  2.  *  effects.c - Processes effects.
  3.  *
  4.  *  (C) 1994 Mikael Nordqvist (d91mn@efd.lth.se, mech@df.lth.se)
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/types.h>
  10.  
  11. #include "mod.h"
  12.  
  13. /* Variables used for processing effects */
  14.  
  15. extern struct mod_info M;
  16. extern struct options opt;
  17.  
  18. extern int songpos, linepos, tick, speed, tempo;
  19. extern double mod_time, tick_time;
  20. extern char song_end, restart_song;
  21. extern char is_first_ult_effect;
  22.  
  23. extern struct event *cur_event;
  24. extern struct voice V[MAX_VOICES];
  25. extern struct effects efx;
  26.  
  27. /* Tables */
  28.  
  29. extern short vibrato_tables[4][64];
  30. extern int periodtable[NR_OCTAVES*12];
  31.  
  32. /* Defines */
  33.  
  34. #define DOWN 1
  35. #define UP   2
  36.  
  37. #define NORMAL 0
  38. #define FINE   1
  39.  
  40. void check_tick0_efx(int v)
  41. {
  42.     int e, e2, tmp;
  43.     unsigned char a;
  44.     
  45.     /* Make sure V[v].note is set when we get a new note (and the note
  46.      * isn't a NOTE_OFF or an argument to the toneportamento-effect). Also
  47.      * take care of retriggering vibrato/tremolo-waveforms.
  48.      */
  49.     if(is_first_ult_effect && cur_event->note &&
  50.        cur_event->note != NOTE_OFF &&
  51.        cur_event->effect != EFX_PORTANOTE &&
  52.        cur_event->effect2 != EFX_PORTANOTE &&
  53.        cur_event->effect != EFX_PORTANOTEVOLSLIDE &&
  54.        cur_event->effect2 != EFX_PORTANOTEVOLSLIDE) {
  55.     if(V[v].real_period != V[v].period) {
  56.         efx.set_finepitch=1;
  57.     }
  58.     V[v].note=cur_event->note; /* Set V[v].note */
  59.     V[v].real_period=V[v].period=periodtable[V[v].note-BASE_NOTE];
  60.     if(V[v].vibrato_retrig)
  61.         V[v].vibrato_pos=0;
  62.     if(V[v].tremolo_retrig)
  63.         V[v].tremolo_pos=0;
  64.     }
  65.     
  66.     /* Reset pitch if we have an empty event, just like PT */
  67.     if(!cur_event->sample && !cur_event->note &&
  68.        !cur_event->effect && !cur_event->arg &&
  69.        !cur_event->effect2 && !cur_event->arg2) {
  70.     if(V[v].real_period != V[v].period) {
  71.         efx.set_finepitch=1;
  72.     }
  73.     V[v].real_period=V[v].period;
  74.     }
  75.  
  76.     /* The following effects are only checked on the first tick */
  77.     
  78.     e=cur_event->effect;
  79.     a=cur_event->arg;
  80.     switch(e) {
  81.       case EFX_PTSPEED:
  82.     if(a < 32 || opt.nobpm) /* Takes care of speed-0 too */
  83.         set_speed(a);
  84.     else
  85.         set_tempo(a);
  86.     break;
  87.       case EFX_SPEED:
  88.     set_speed(a);
  89.     break;
  90.       case EFX_TEMPO:
  91.     if(a >= 32)
  92.         set_tempo(a);  /* No tempo below 32 set */
  93.     break;
  94.       case EFX_BREAK:
  95.     efx.PBreakPos=(a&0x0f)+((a>>4)&0x0f)*10;
  96.     if(efx.PBreakPos > 63)
  97.         efx.PBreakPos=0;
  98.     efx.PosJumpFlag=1;
  99.     break;
  100.       case EFX_JUMP:
  101.     if(a <= songpos) { /* Jump backward */
  102.         restart_song=1;             /* Make sure play.c knows song ended */
  103.  
  104.         if(opt.loop_module || !opt.break_loops)
  105.         songpos=a-1; /* -1 as songpos++ is always done */
  106.         else
  107.         songpos=M.songlength;     /* Make sure song_end gets set */
  108.     }
  109.     else {
  110.         if(a <= M.songlength-1) /* Jump forward */
  111.         songpos=a-1; /* -1 as songpos++ is always done */
  112.         else {
  113.         restart_song=1;
  114.         songpos=M.songlength;     /* Make sure song_end gets set */
  115.         }
  116.     }
  117.  
  118.     efx.PBreakPos=0;
  119.     efx.PosJumpFlag=1;
  120.     break;
  121.  
  122.       case EFX_VOLUME:
  123.     V[v].volume=V[v].real_volume=MIN(a, M.volrange);
  124.     efx.set_volume=1;
  125.     break;
  126.       case EFX_SAMPLEOFFSET:    /* Why can't they all do it the same way :( */
  127.       case EFX_SAMPLEOFFSET_ULT:
  128.       case EFX_SAMPLEOFFSET_S3M:
  129.     if(a) {
  130.         if(e == EFX_SAMPLEOFFSET)
  131.         V[v].last_sampleoffset=a*256;
  132.         else if(e == EFX_SAMPLEOFFSET_S3M) {
  133.         V[v].last_sampleoffset=a*256;
  134.         if(M.sample[V[v].sample].looped &&
  135.            V[v].last_sampleoffset > M.sample[V[v].sample].repeat_end) {
  136.             /* Looplength */
  137.             tmp=M.sample[V[v].sample].repeat_end+1-
  138.             M.sample[V[v].sample].repeat_start;
  139.             /* Take loop into account */
  140.             V[v].last_sampleoffset=M.sample[V[v].sample].repeat_start+
  141.             (V[v].last_sampleoffset-
  142.              M.sample[V[v].sample].repeat_start)%tmp;
  143.         }
  144.         }
  145.         else {
  146.         /* Check for the '99' effect */
  147.         if(cur_event->effect2 == EFX_SAMPLEOFFSET) {
  148.             if(!is_first_ult_effect) /* Abort for second effect */
  149.             break;
  150.             V[v].last_sampleoffset=((a<<8)+cur_event->arg2)*4;
  151.         }
  152.         else
  153.             V[v].last_sampleoffset=a*1024;
  154.         }
  155.     }
  156.  
  157.     if(V[v].last_sampleoffset < M.sample[V[v].sample].length)
  158.         V[v].sampleoffset=V[v].last_sampleoffset;
  159.     else { 
  160.         /* An invalid offset silences the voice */
  161.         efx.kill_voice=1;
  162.     }
  163.     break;
  164.     
  165.     /* The following four effects only initialize toneportamento and
  166.      * vibrato for the ticks to come.
  167.      */
  168.       case EFX_PORTANOTE:
  169.     if(a) {
  170.         V[v].toneporta_speed=a*4;
  171.     }
  172.     if(M.format == MODFORMAT_S3M)
  173.         do_toneportamento(v);
  174.     /* Fall through */
  175.       case EFX_PORTANOTEVOLSLIDE:
  176.     if(cur_event->note && cur_event->note != NOTE_OFF) {
  177.         tmp=cur_event->note;
  178.         tmp=MIN(tmp, opt.high_note); /* Not too high. PT: B-3 */
  179.         tmp=MAX(tmp, opt.low_note);  /* Not too low . PT: C-1 */
  180.         V[v].period_goal=periodtable[tmp-BASE_NOTE];
  181.         efx.dont_trigger_note=1; /* Make sure note doesn't get played */
  182.     }
  183.     break;
  184.     
  185.       case EFX_VIBRATO:
  186.     tmp=a;
  187.     if(tmp&0x0f)
  188.         V[v].vibrato_amplitude=tmp&0x0f;
  189.     if((tmp>>4)&0x0f)
  190.         V[v].vibrato_speed=(tmp>>4)&0x0f;
  191.     /* Fall through */
  192.       case EFX_VIBRATOVOLSLIDE:
  193.     /* Nothing to do here when sliding volume */
  194.     break;
  195.     
  196.     /* In the protracker sources the following EFXs are checked on
  197.      * ALL ticks, but aborts if tick != 0. So we check'em here.
  198.      */
  199.         
  200.       case EFX_FINEVOLSLIDEUP:
  201.     V[v].last_volumeslidetype=FINE;
  202.     slide_volume(v, a, UP);
  203.     break;
  204.       case EFX_FINEVOLSLIDEDOWN:
  205.     V[v].last_volumeslidetype=FINE;
  206.     slide_volume(v, a, DOWN);
  207.     break;
  208.       case EFX_VOLSLIDECONTINUE:
  209.     if(V[v].last_volumeslidetype == FINE)
  210.         slide_volume(v, 0, 0);
  211.     break;
  212.       case EFX_FINEPORTAUP:
  213.     V[v].last_portamentotype=FINE;
  214.     do_set_portamento(v, a*4, UP);
  215.     break;
  216.       case EFX_FINEPORTADOWN:
  217.     V[v].last_portamentotype=FINE;
  218.     do_set_portamento(v, a*4, DOWN);
  219.     break;
  220.       case EFX_EXTRAFINEPORTAUP:
  221.     V[v].last_portamentotype=FINE;
  222.     do_set_portamento(v, a, UP);
  223.     break;
  224.       case EFX_EXTRAFINEPORTADOWN:
  225.     V[v].last_portamentotype=FINE;
  226.     do_set_portamento(v, a, DOWN);
  227.     break;
  228.       case EFX_PORTAUPCONTINUE:
  229.     if(V[v].last_portamentotype == FINE)
  230.         do_set_portamento(v, V[v].last_portamento, UP);
  231.     break;
  232.       case EFX_PORTADOWNCONTINUE:
  233.     if(V[v].last_portamentotype == FINE)
  234.         do_set_portamento(v, V[v].last_portamento, DOWN);
  235.     break;
  236.       case EFX_PATTERNDELAY:
  237.     efx.pattern_delay=a+1; /* +1 as we should  play current
  238.                 * line + arg EXTRA lines.
  239.                 */
  240.     break;
  241.  
  242.       case EFX_BALANCE:
  243.     M.panning[v]=a&0x0f;
  244.     efx.set_balance=1;
  245.     break;
  246.       case EFX_VIBDEPTH:    /* I _think_ this is what the ultradocs means */
  247.     if(a&0x0f)
  248.         V[v].vibrato_amplitude=a&0x0f;
  249.     break;
  250.  
  251.       default:
  252.     check_remaining_efx(v); /* Effects that always should be processed */
  253.     }
  254.  
  255.     /* Reset real period if needed. This is a real UGLY way to do it, but
  256.      * PT does it this way, and to make sure all cases get correct I just
  257.      * mimic it's behaviour.
  258.      * For ULTs we do this after the second effect has been processed.
  259.      * For S3Ms we do it before effect2 (volume/NULL) is processed (no harm).
  260.      */
  261.     if(M.format != MODFORMAT_ULT || !is_first_ult_effect) {
  262.     e2=cur_event->effect2;
  263.     if(e<=0x0f && e!=EFX_SAMPLEOFFSET && e!=EFX_JUMP && e!=EFX_BREAK &&
  264.        e!=EFX_PTSPEED && e!=EFX_SPEED && e!=EFX_TEMPO && e!=EFX_VOLUME &&
  265.        e2<=0x0f && e2!=EFX_SAMPLEOFFSET && e2!=EFX_JUMP && e2!=EFX_BREAK &&
  266.        e2!=EFX_PTSPEED && e2!=EFX_SPEED && e2!=EFX_TEMPO &&
  267.        e2!=EFX_VOLUME) {
  268.         if(V[v].real_period != V[v].period) {
  269.         V[v].real_period=V[v].period;
  270.         efx.set_finepitch=1;
  271.         }
  272.     }
  273.     }
  274. }
  275.  
  276.  
  277. /* These effects are checked on all ticks ticks except the first
  278.  * one on each line.
  279.  */
  280.  
  281. void check_efx(int v)
  282. {
  283.     int e, e2;
  284.     unsigned char a, tmp;
  285.  
  286.     e=cur_event->effect;
  287.     a=cur_event->arg;
  288.     switch(e) {
  289.       case EFX_ARPEGGIO:
  290.     if(!a)
  291.         break;
  292.     do_arpeggio(v, a);
  293.     break;
  294.  
  295.       case EFX_PORTAUP:
  296.     V[v].last_portamentotype=NORMAL;
  297.     do_set_portamento(v, a*4, UP);
  298.     break;
  299.       case EFX_PORTADOWN:
  300.     V[v].last_portamentotype=NORMAL;
  301.     do_set_portamento(v, a*4, DOWN);
  302.     break;
  303.       case EFX_PORTAUPCONTINUE:
  304.     if(V[v].last_portamentotype == NORMAL)
  305.         do_set_portamento(v, V[v].last_portamento, UP);
  306.     break;
  307.       case EFX_PORTADOWNCONTINUE:
  308.     if(V[v].last_portamentotype == NORMAL)
  309.         do_set_portamento(v, V[v].last_portamento, DOWN);
  310.     break;
  311.       case EFX_PORTANOTEVOLSLIDE:
  312.     V[v].last_volumeslidetype=NORMAL;
  313.     do_volumeslide(v, a);
  314.       case EFX_PORTANOTE:
  315.     do_toneportamento(v);
  316.     break;
  317.     
  318.       case EFX_VIBRATOVOLSLIDE:    
  319.     V[v].last_volumeslidetype=NORMAL;
  320.     do_volumeslide(v, a);
  321.       case EFX_VIBRATO:
  322.     do_vibrato(v);
  323.     break;
  324.     
  325.       case EFX_TREMOLO:
  326.     do_tremolo(v);
  327.     break;
  328.  
  329.       case EFX_VOLSLIDE:
  330.     V[v].last_volumeslidetype=NORMAL;
  331.     do_volumeslide(v, a);
  332.     break;
  333.       case EFX_VOLSLIDECONTINUE:
  334.     if(V[v].last_volumeslidetype == NORMAL)
  335.         slide_volume(v, 0, 0);
  336.     break;
  337.  
  338.       case EFX_RETRIGGER:
  339.     if(a && !(tick%a))
  340.         efx.retrig_note=1;
  341.     break;
  342.       case EFX_RETRIGGERVOLSLIDE: /* S3M's retrigger */
  343.     if(a && !(tick%(a&0x0f))) {
  344.         efx.retrig_note=1;
  345.         tmp=(a>>4)&0x0f;
  346.         switch(tmp) {
  347.           case 1: case 2: case 3: case 4: case 5:
  348.         slide_volume(v, 1<<(tmp-1), DOWN);
  349.         break;
  350.           case 9: case 10: case 11: case 12: case 13:
  351.         slide_volume(v, 1<<(tmp-9), UP);
  352.         break;
  353.           case 6:
  354.         slide_volume(v, V[v].volume-V[v].volume*2/3, DOWN);
  355.         break;
  356.           case 7:
  357.         slide_volume(v, V[v].volume-V[v].volume/2, DOWN);
  358.         break;
  359.           case 14:
  360.         slide_volume(v, V[v].volume-V[v].volume*3/2, UP);
  361.         break;
  362.           case 15:
  363.         slide_volume(v, V[v].volume-V[v].volume*2, UP);
  364.         break;
  365.           case 8:
  366.           case 0:
  367.         }
  368.     }
  369.     break;
  370.     
  371.       case EFX_TREMOR: /* As close as I get w/o more docs */
  372.     tmp=((a>>4)&0x0f)+(a&0x0f);
  373.     if(tmp) {
  374.         if((tick%tmp) == ((a>>4)&0x0f))
  375.         V[v].real_volume=0;
  376.         else if(!(tick%tmp))
  377.         V[v].real_volume=V[v].volume;
  378.         if(V[v].volume != V[v].real_volume)
  379.         efx.set_volume=1;
  380.     }
  381.     break;
  382.       default:
  383.     check_remaining_efx(v);
  384.     }
  385.  
  386.     /* Reset real period if needed. This is a real UGLY way to do it, but
  387.      * PT does it this way, and to make sure all cases get correct I just
  388.      * mimic it's behaviour.
  389.      * For ULTs we do this after the second effect has been processed.
  390.      */
  391.     if(M.format != MODFORMAT_ULT || !is_first_ult_effect) {
  392.     e2=cur_event->effect2;
  393.     if(e<=0x0f && e!=EFX_ARPEGGIO && e!=EFX_PORTAUP && e!=EFX_PORTADOWN &&
  394.        e!=EFX_PORTANOTE && e!=EFX_PORTANOTEVOLSLIDE && e!=EFX_VIBRATO &&
  395.        e!=EFX_VIBRATOVOLSLIDE &&
  396.        e!=EFX_PORTAUPCONTINUE && e!= EFX_PORTADOWNCONTINUE &&/* S3M only */
  397.        e2<=0x0f && e2!=EFX_ARPEGGIO && e2!=EFX_PORTAUP &&
  398.        e2!=EFX_PORTANOTE && e2!=EFX_PORTANOTEVOLSLIDE && e2!=EFX_VIBRATO &&
  399.        e2!=EFX_VIBRATOVOLSLIDE && e2!=EFX_PORTADOWN) {
  400.         if(V[v].real_period != V[v].period) {
  401.         V[v].real_period=V[v].period;
  402.         efx.set_finepitch=1;
  403.         }
  404.     }
  405.     }
  406. }
  407.  
  408.  
  409. /* This function checks and updates the effects that should be checked on
  410.  * every tick.
  411.  */
  412.  
  413. void check_remaining_efx(int v)
  414. {
  415.     char tmp;
  416.     unsigned char a;
  417.  
  418.     a=cur_event->arg;
  419.     switch(cur_event->effect) {
  420.       case EFX_GLISSANDO:
  421.     V[v].glissando=a;
  422.     break;
  423.       case EFX_VIBWAVEFORM:
  424.     V[v].vibrato_waveform=a&0x03;
  425.     V[v].vibrato_retrig=(~a)&0x04;
  426.     break;
  427.       case EFX_TREMWAVEFORM:
  428.     V[v].tremolo_waveform=a&0x03;
  429.     V[v].tremolo_retrig=(~a)&0x04;
  430.     break;
  431.  
  432.       case EFX_FINETUNE:
  433.     tmp=a;
  434.     tmp=(tmp > 7 ? tmp|0xf0 : tmp);
  435.     if(V[v].finetune != tmp) { /* Only set it if it's changed */
  436.         V[v].finetune=tmp;  /* Store as signed char */
  437.         efx.set_finepitch=1;
  438.     }
  439.     break;
  440.       case EFX_LOOP:
  441.     /* Note: This EFX cannot be moved to the tick #0 block as
  442.      * it should be processed even if we have EFX_PATTERNDELAY.
  443.      * Not too nice, but PT does it this way...
  444.      */
  445.     if(tick)
  446.         break;
  447.     
  448.     if(!a)
  449.         V[v].loopstartpos=linepos-1; /* -1 as linepos++ is always done */
  450.     else {
  451.         if(!V[v].loopcount) {
  452.         V[v].loopcount=a;
  453.         efx.PBreakPos=V[v].loopstartpos;
  454.         efx.PBreakFlag=1;
  455.         }
  456.         else {
  457.         if(--V[v].loopcount) {
  458.             efx.PBreakPos=V[v].loopstartpos;
  459.             efx.PBreakFlag=1;
  460.         }
  461.         }
  462.     }
  463.     break;
  464.       case EFX_NOTECUT:
  465.     if(tick == a) {
  466.         V[v].volume=V[v].real_volume=0;
  467.         efx.set_volume=1;
  468.     }
  469.     break;
  470.       case EFX_NOTEDELAY:
  471.     /* A notedelay of 0 causes note not to be played at all */
  472.     if(a) {
  473.         if(!tick)  /* Prevent note-trigger on tick #0 if arg>0 */
  474.         efx.dont_trigger_note=1;
  475.         else if(tick == a)
  476.         efx.retrig_note=1; /* Make sure note gets played when arg>0 */
  477.     }
  478.     break;
  479.     
  480.       case EFX_UNUSED2:
  481.       case EFX_FILTER:       /* No sense to implement a LP-filter on a GUS */
  482.       case EFX_INVERTEDLOOP: /* Not feasible to implement on a GUS         */
  483.     break;
  484.  
  485.       default: /* Do nothing for other effects */
  486.     }
  487. }
  488.  
  489.  
  490. void set_speed(int s)
  491. {
  492.     if(!s) {  /* Speed 0 handling */
  493.     if(opt.speed0stop) { /* stop song */
  494.         restart_song=1;
  495.         songpos=M.songlength;
  496.         efx.PosJumpFlag=1; /* These needed to get song_end set */
  497.         efx.PBreakPos=0;
  498.     }
  499.     }
  500.     else
  501.     speed=s;
  502. }
  503.  
  504.  
  505. void set_tempo(int t)
  506. {
  507.     tempo=t;
  508.     tick_time=250.0/tempo;
  509. }
  510.  
  511.  
  512. void do_arpeggio(int v, int arg)
  513. {
  514.     int note;
  515.     
  516.     switch(tick%3) {
  517.       case 0:
  518.     V[v].real_period=V[v].period;
  519.     break;
  520.       case 1:
  521.     note=period2note(V[v].period)+((arg>>4)&0x0f);
  522.     /* Only change pitch if we don't go too high. PT: B-3 */
  523.     if(note <= opt.high_note) {
  524.         V[v].real_period=periodtable[note-BASE_NOTE];
  525.     }
  526.     break;
  527.       case 2:
  528.     note=period2note(V[v].period)+(arg&0x0f);
  529.     /* Only change pitch if we don't go too high. PT: B-3 */
  530.     if(note <= opt.high_note) {
  531.         V[v].real_period=periodtable[note-BASE_NOTE];
  532.     }
  533.     }
  534.     efx.set_finepitch=1;
  535. }
  536.  
  537.  
  538. void do_volumeslide(int v, unsigned char arg)
  539. {
  540.     if(M.format != MODFORMAT_S3M) { /* PT checks UP before DOWN */
  541.     if(arg&0xf0)
  542.         slide_volume(v, (arg>>4)&0x0f, UP); /* Slide volume up   */
  543.     else
  544.         slide_volume(v, arg&0x0f, DOWN);   /* Slide volume down */
  545.     }
  546.     else { /* ST3 checks DOWN before UP */
  547.     if(arg&0x0f)
  548.         slide_volume(v, arg&0x0f, DOWN);   /* Slide volume down */
  549.     else
  550.         slide_volume(v, (arg>>4)&0x0f, UP); /* Slide volume up   */
  551.     }
  552. }
  553.  
  554. void slide_volume(int v, int amount, char dir)
  555. {
  556.     if(dir == DOWN)
  557.     amount=-amount;
  558.     
  559.     if(M.format == MODFORMAT_S3M) { /* S3M's use 0 as last value */
  560.     if(!amount)
  561.         amount=V[v].last_volumeslide;
  562.     else
  563.         V[v].last_volumeslide=amount;
  564.     }
  565.     
  566.     V[v].volume=V[v].real_volume=MAX(MIN(M.volrange, V[v].volume+amount), 0);
  567.     efx.set_volume=1;
  568. }
  569.  
  570. void do_set_portamento(int v, int amount, char dir)
  571. {
  572.     int per;
  573.  
  574.     if(M.format == MODFORMAT_S3M)
  575.     V[v].last_portamento=amount;
  576.  
  577.     if(dir == UP)
  578.     amount=-amount;
  579.     
  580.     per=V[v].period+amount;
  581.     
  582.     /* No too high or too low */
  583.     per=MAX(per, periodtable[opt.high_note-BASE_NOTE]);
  584.     per=MIN(per, periodtable[opt.low_note-BASE_NOTE]);
  585.  
  586.     V[v].period=V[v].real_period=per;
  587.     efx.set_finepitch=1;
  588. }
  589.  
  590.  
  591. void do_toneportamento(int v)
  592. {
  593.     if(!V[v].period_goal)
  594.     return;
  595.     
  596.     if(V[v].period_goal > V[v].period) {
  597.     V[v].period+=V[v].toneporta_speed;
  598.     if(V[v].period >= V[v].period_goal) {
  599.         V[v].period=V[v].period_goal;
  600.         V[v].period_goal=0;
  601.     }
  602.     }
  603.     else {
  604.     V[v].period-=V[v].toneporta_speed;
  605.     if(V[v].period <= V[v].period_goal) {
  606.         V[v].period=V[v].period_goal;
  607.         V[v].period_goal=0;
  608.     }
  609.     }
  610.     
  611.     /* Modify pitch to closest note if we have glissando on */
  612.     if(V[v].glissando)
  613.     V[v].real_period=periodtable[period2note(V[v].period)-BASE_NOTE];
  614.     else
  615.     V[v].real_period=V[v].period;
  616.     
  617.     efx.set_finepitch=1;
  618. }
  619.  
  620.  
  621. void do_vibrato(int v)
  622. {
  623.     if(V[v].period < 20)
  624.     error("ARHGH2: %d\n", V[v].period);
  625.  
  626.     V[v].real_period=V[v].period+(
  627.     (vibrato_tables[V[v].vibrato_waveform][V[v].vibrato_pos/4]
  628.      *V[v].vibrato_amplitude)/128)*4; /* /64 on old trackers */
  629.     /* The *4 above is because X-2 => X-4 */
  630.  
  631.     if(V[v].real_period < 20)
  632.     error("ARHGH: %d\n", V[v].real_period);
  633.     
  634.     V[v].vibrato_pos=(V[v].vibrato_pos+V[v].vibrato_speed*4)%256;
  635.     
  636.     efx.set_finepitch=1;
  637. }
  638.  
  639. /* Tremolo is scaled with M.volrange */
  640.  
  641. void do_tremolo(int v)
  642. {
  643.     V[v].real_volume=V[v].volume+
  644.     ((vibrato_tables[V[v].tremolo_waveform][V[v].tremolo_pos/4]
  645.      *V[v].tremolo_amplitude)/64)*M.volrange/64;
  646.     V[v].real_volume=MAX(MIN(V[v].real_volume, M.volrange), 0);
  647.     
  648.     V[v].tremolo_pos=(V[v].tremolo_pos+V[v].tremolo_speed*4)%256;
  649. }
  650.  
  651.  
  652. void set_pitch(int v)
  653. {
  654.     int note, period, noteperiod, note_m1_period;
  655.  
  656.     period=V[v].real_period;                 /* period to bend to  */
  657.     note=period2note(period);                /* "closest" note     */
  658.  
  659.  
  660.     noteperiod=periodtable[note-BASE_NOTE];  /* period of note     */
  661.     if(noteperiod == period) { /* Right on a note */
  662.     V[v].pitchbend=(note-V[v].note)*100;
  663.     return;
  664.     }
  665.  
  666.     /* The following is always safe because of the above test */
  667.     note_m1_period=periodtable[note-1-BASE_NOTE]; /* period of (note-1) */
  668.  
  669.     if(note < V[v].note) {
  670.     V[v].pitchbend=(note-V[v].note)*100-
  671.         ((period-noteperiod)*100)/(note_m1_period-noteperiod);
  672.     }
  673.     else {
  674.     V[v].pitchbend=(note-V[v].note-1)*100+
  675.         ((note_m1_period-period)*100)/
  676.         (note_m1_period-noteperiod);
  677.     }
  678. }
  679.