home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 September (IDG) / Sep99.iso / Shareware World / Info / For Developers / PlayerPRO 5.2 Dev.Kit Mac / MADH Library 5.2 / MADLibrary Source / Effects.c < prev    next >
Encoding:
Text File  |  1999-06-22  |  14.9 KB  |  771 lines  |  [TEXT/CWIE]

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24. #include "RDriver.h"
  25. #include "RDriverInt.h"
  26.  
  27. #define LOW(para) ((para) & 15)
  28. #define HI(para) ((para) >> 4)
  29.  
  30. void StartPanning( Channel *ch);
  31.  
  32. void parse_slidevol(Channel *ch, Byte Arg)
  33. {
  34.     if ( HI( Arg) ) ch->volumerate = HI( Arg);
  35.     else ch->volumerate = -LOW( Arg);
  36. }
  37.  
  38. void CloseEffect( Channel *ch, short notUsed, MADDriverRec *intDriver)
  39. {
  40.     switch( ch->cmd)
  41.     {
  42.         default:
  43.         break;
  44.     
  45.         case arpeggioE:
  46.             if( ch->arpUse) 
  47.             {
  48.                 ch->period = ch->arp[ 0];
  49.                 ch->arpUse = false;
  50.             }
  51.         break;
  52.     
  53.         case skipE:
  54.         break;
  55.         
  56.         case fastskipE:
  57.         break;
  58.         
  59.         case downslideE:
  60.         break;
  61.         
  62.         case upslideE:
  63.         break;
  64.         
  65.         case vibratoE:
  66.         //    DebugStr("\pClose Vibrato");
  67.             ch->period = ch->periodOld;
  68.         break;
  69.         
  70.         case slidevolE:
  71.         break;
  72.         
  73.         case portamentoE:
  74.         break;
  75.         
  76.         case portaslideE:
  77.             ch->cmd = portamentoE;
  78.             CloseEffect( ch, 0, intDriver);
  79.             
  80.             ch->cmd = slidevolE;
  81.             CloseEffect( ch, 0, intDriver);
  82.             
  83.             ch->cmd = portaslideE;
  84.         break;
  85.         
  86.         case vibratoslideE:
  87.             ch->cmd = vibratoE;
  88.             CloseEffect( ch, 0, intDriver);
  89.             
  90.             ch->cmd = slidevolE;
  91.             CloseEffect( ch, 0, intDriver);
  92.             
  93.             ch->cmd = vibratoslideE;
  94.         break;
  95.         
  96.         case extendedE:
  97.             switch( HI( ch->arg))
  98.               {
  99.             case 6:
  100.                 
  101.             break;
  102.             }
  103.         break;
  104.     }
  105.     
  106.     ch->arg = 0;
  107.     ch->cmd = 0;
  108. }
  109.  
  110. void DoEffect( Channel *ch, short call, MADDriverRec *intDriver)
  111. {
  112. long offset;
  113.     
  114.     switch( ch->cmd)
  115.     {
  116.         default:
  117.             ch->cmd = 0;
  118.             ch->arg = 0;
  119.             return;
  120.         break;
  121.     
  122.         case arpeggioE:                        // OK
  123.             if( ch->arg != 0 && ch->arpUse == true)
  124.             {
  125.                 ch->arpindex++;
  126.                 if( ch->arpindex >= MAX_ARP) ch->arpindex = 0;
  127.                 
  128.                 ch->period = ch->arp[ ch->arpindex];
  129.             }
  130.         break;
  131.     
  132.         case skipE:                            // OK
  133.             if( call == intDriver->speed - 1)
  134.             {
  135.                 intDriver->endPattern = true;
  136.                 
  137.                 if( intDriver->JumpToNextPattern)
  138.                 {
  139.                     if( intDriver->PartitionReader != 0)
  140.                     {
  141.                         intDriver->PL++;
  142.                         intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  143.                     }
  144.                     
  145.                     intDriver->PartitionReader = HI( ch->arg) * 10 + LOW( ch->arg);
  146.                     
  147.                     if( intDriver->PL >= intDriver->curMusic->header->numPointers)
  148.                     {
  149.                         intDriver->PL = 0;
  150.                         intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  151.                         
  152.                         MADCleanDriver( intDriver);
  153.                         if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
  154.                         
  155.                         intDriver->musicEnd = true;
  156.                     }
  157.                 }
  158.                 else
  159.                 {
  160.                     intDriver->PartitionReader = 0;
  161.                 }
  162.                 ch->cmd = 0;
  163.                 ch->arg = 0;
  164.             }
  165.         break;
  166.         
  167.         case fastskipE:                        // OK
  168.             if( call == intDriver->speed - 1)
  169.             {
  170.                 intDriver->endPattern = true;
  171.                 
  172.                 if( intDriver->JumpToNextPattern)
  173.                 {
  174.                     if( intDriver->PL > ch->arg)        // Evite les boucles
  175.                     {
  176.                         intDriver->musicEnd = true;
  177.                         
  178.                         if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
  179.                     }
  180.                     
  181.                     intDriver->PL = ch->arg;
  182.                     intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  183.                 
  184.                     if( intDriver->PL >= intDriver->curMusic->header->numPointers)
  185.                     {
  186.                         intDriver->PL = 0;
  187.                         intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  188.                         
  189.                         MADCleanDriver( intDriver);
  190.                         if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
  191.                         
  192.                         intDriver->musicEnd = true;
  193.                     }
  194.                 }
  195.                 intDriver->PartitionReader = 0;
  196.                 ch->cmd = 0;
  197.                 ch->arg = 0;
  198.             }
  199.         break;
  200.         
  201.         case downslideE:                        // OK
  202.             if( intDriver->MODMode)
  203.             {
  204.             /*    if( ch->period > intDriver->MOD_MIN_PITCH)
  205.                     ch->period -= ch->slide*4;*/
  206.                 ch->period -= ch->slide*4;
  207.                 if( ch->period < intDriver->MOD_MIN_PITCH) ch->period = intDriver->MOD_MIN_PITCH;
  208.             }
  209.             else
  210.             {
  211.                 if( ch->period > intDriver->MIN_PITCH)
  212.                     ch->period -= ch->slide*4;
  213.             }
  214.         break;
  215.         
  216.         case upslideE:                            // OK
  217.             if( intDriver->MODMode)
  218.             {
  219.             /*    if( ch->period < intDriver->MOD_MAX_PITCH)
  220.                     ch->period += ch->slide*4;*/
  221.                 ch->period += ch->slide*4;
  222.                 if( ch->period > intDriver->MOD_MAX_PITCH) ch->period = intDriver->MOD_MAX_PITCH;
  223.             }
  224.             else
  225.             {
  226.                 if( ch->period < intDriver->MAX_PITCH)
  227.                     ch->period += ch->slide*4;
  228.             }
  229.         break;
  230.         
  231.         case vibratoE:
  232.         {
  233.             Byte q = (ch->viboffset>>2)&0x1f;
  234.             
  235.             switch( ch->vibtype)
  236.             {
  237.             case 0:
  238.                 offset = intDriver->vibrato_table[ q];
  239.             break;
  240.             
  241.             case 1:
  242.                 q<<=3;
  243.                 if(ch->viboffset<0) q=255-q;
  244.                 offset = q;
  245.             break;
  246.             
  247.             case 2:
  248.                 offset = 255;
  249.             break;
  250.             }
  251.             
  252.             offset *= ch->vibdepth;
  253.             offset >>= 7;
  254.             offset <<= 2;
  255.             
  256.             if( ch->viboffset >= 0) ch->period = ch->periodOld + offset;
  257.             else ch->period = ch->periodOld - offset;
  258.             
  259.             ch->viboffset += ch->vibrate;
  260.         }
  261.         break;
  262.         
  263.         case slidevolE:                        // OK
  264.             ch->vol += ch->volumerate;
  265.             
  266.             if( ch->vol < MIN_VOLUME) ch->vol = MIN_VOLUME;
  267.             else if( ch->vol > MAX_VOLUME) ch->vol = MAX_VOLUME;
  268.         break;
  269.         
  270.         case portamentoE:
  271.         //    if( ch->period == 0) MyDebugStr( __LINE__, __FILE__, "Goal");
  272.             if( ch->period != ch->pitchgoal)
  273.             {
  274.                 if (ch->period < ch->pitchgoal)
  275.                 {
  276.                     ch->period += ch->pitchrate*4;
  277.                     if( ch->period > ch->pitchgoal)
  278.                     {
  279.                         ch->cmd = 0;
  280.                         ch->arg = 0;
  281.                         ch->period = ch->pitchgoal;
  282.                     }
  283.                 }
  284.                 else if (ch->period > ch->pitchgoal)
  285.                 {
  286.                     ch->period -= ch->pitchrate*4;
  287.                     if( ch->period < ch->pitchgoal)
  288.                     {
  289.                         ch->cmd = 0;
  290.                         ch->arg = 0;
  291.                         ch->period = ch->pitchgoal;
  292.                     }
  293.                 }
  294.             }
  295.         break;
  296.         
  297.         case portaslideE:
  298.             ch->cmd = portamentoE;
  299.             DoEffect( ch, call, intDriver);
  300.             
  301.             ch->cmd = slidevolE;
  302.             DoEffect( ch, call, intDriver);
  303.             
  304.             ch->cmd = portaslideE;
  305.         break;
  306.         
  307.         case vibratoslideE:
  308.             ch->cmd = vibratoE;
  309.             DoEffect( ch, call, intDriver);
  310.             
  311.             ch->cmd = slidevolE;
  312.             DoEffect( ch, call, intDriver);
  313.             
  314.             ch->cmd = vibratoslideE;
  315.         break;
  316.  
  317.         case extendedE:
  318.             switch( HI( ch->arg))
  319.               {
  320.                 case 12:
  321.                     if( call >= LOW( ch->arg)) ch->vol = 0;
  322.                 break;
  323.                 
  324.                 case 9:
  325.                     if(LOW( ch->arg))
  326.                     {
  327.                         if( ch->trig == 0)
  328.                         {
  329.                             ch->curPtr    = ch->begPtr;
  330.                             StartPanning( ch);
  331.                             StartEnvelope( ch);
  332.                             
  333.                             ch->trig    = LOW( ch->arg);
  334.                         }
  335.                         ch->trig--;
  336.                     }
  337.                 break;
  338.                 
  339.                 case 6:
  340.                     if( call == intDriver->speed - 1)
  341.                     {
  342.                         if( LOW( ch->arg) == 0)        // Set Pattern loop
  343.                         {
  344.                             ch->PatternLoopE6 = intDriver->PartitionReader;
  345.                             ch->PatternLoopE6ID = intDriver->PL;
  346.                         }
  347.                         else
  348.                         {
  349.                             if( ch->PatternLoopE6Count == 0) ch->PatternLoopE6Count = LOW( ch->arg);
  350.                             else ch->PatternLoopE6Count--;
  351.                             
  352.                             if( ch->PatternLoopE6Count > 0)
  353.                             {
  354.                                 intDriver->PartitionReader = ch->PatternLoopE6-1;
  355.                                 intDriver->PL = ch->PatternLoopE6ID;
  356.                                 intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  357.                             }
  358.                         }
  359.                     }
  360.                 break;
  361.             }
  362.         break;
  363.     }
  364.     
  365. /*    if( call == intDriver->speed - 1)
  366.     {
  367.         ch->arg = 0;
  368.         ch->cmd = 0;
  369.     }*/
  370. }
  371.  
  372. void SetUpCmdEffect( Channel *ch, MADDriverRec *intDriver)
  373. {
  374.     short    vol = ch->volcmd;
  375.     short    volLO = vol & 0xf;
  376.     short    cmdCopy = ch->cmd;
  377.     short    argCopy = ch->arg;
  378.  
  379.     switch( vol >> 4)
  380.     {
  381.         case 0x8:
  382.             ch->cmd        = extendedE;
  383.             ch->arg        = 0xb0|volLO;
  384.  
  385.             SetUpEffect( ch, intDriver);
  386.         break;
  387.         
  388.         case 0x9:
  389.             ch->cmd        = extendedE;
  390.             ch->arg        = 0xa0|volLO;
  391.  
  392.             SetUpEffect( ch, intDriver);
  393.         break;
  394.         
  395.         case 0xa:                       // set vibrato speed
  396.             ch->cmd        = vibratoE;
  397.             ch->arg        = vol<<4;
  398.  
  399.             SetUpEffect( ch, intDriver);
  400.         break;
  401.  
  402.         case 0xb:                       // vibrato
  403.             ch->cmd        = vibratoE;
  404.             ch->arg        = volLO;
  405.  
  406.             SetUpEffect( ch, intDriver);
  407.         break;
  408.         
  409.         case 0xc:                       // panning
  410.             ch->cmd        = panningE;
  411.             ch->arg        = vol<<4;
  412.  
  413.             SetUpEffect( ch, intDriver);
  414.         break;
  415.         
  416.         case 0xf:                       // tone porta
  417.             ch->cmd        = portamentoE;
  418.             ch->arg        = vol<<4;
  419.  
  420.             SetUpEffect( ch, intDriver);
  421.         break;
  422.     }
  423.     
  424.     ch->cmd = cmdCopy;
  425.     ch->arg = argCopy;
  426. }
  427.  
  428. void SetUpEffect( Channel *ch, MADDriverRec *intDriver)
  429. {
  430. short     temp, note;
  431. long    aL;
  432.  
  433. if( ch->arg == 0)
  434. {
  435.     switch( ch->cmd)
  436.     {
  437.         case arpeggioE:
  438.         case nothingE:
  439.         case fastskipE:
  440.         case volumeE:
  441.         case panningE:
  442.         case skipE:
  443.         case extendedE:
  444.         case speedE:
  445.     //    case slidevolE:
  446.         break;
  447.         
  448.         default:
  449.             ch->arg = ch->oldArg[ ch->cmd];
  450.         break;
  451.     }
  452. }
  453. else ch->oldArg[ ch->cmd] = ch->arg;
  454.  
  455. switch( ch->cmd)
  456. {
  457.     case upslideE:                            // OK
  458.         if( ch->arg) ch->slide = ch->arg;
  459.     break;
  460.     
  461.     case downslideE:                        // OK
  462.         if( ch->arg) ch->slide = ch->arg;
  463.     break;
  464.  
  465.     case vibratoE:                            // OK
  466.         if( HI( ch->arg)) ch->vibrate = (ch->arg & 0xf0)>>2;    //HI( ch->arg);
  467.         else ch->vibrate = ch->oldVibrate;
  468.         
  469.         if( LOW( ch->arg)) ch->vibdepth = LOW( ch->arg);
  470.         else ch->vibdepth = ch->oldVibdepth;
  471.         
  472.         ch->oldVibdepth = ch->vibdepth;
  473.         ch->oldVibrate = ch->vibrate;
  474.         
  475.     //    ch->viboffset = 0;
  476.         ch->periodOld = ch->period;
  477.     break;
  478.     
  479.     case arpeggioE:                        // OK
  480.         if( ch->arg == 0) ch->arpUse = false;
  481.         else
  482.         {
  483.             long    inNote = ch->note;
  484.             
  485.             if( inNote == 0xFF) inNote = ch->noteOld;
  486.             
  487.             if( inNote != 0xFF)
  488.             {
  489.                 note = inNote + HI( ch->arg);
  490.                 if (note < NUMBER_NOTES) ch->arp[ 1] = GetOldPeriod( note, ch->fineTune, intDriver);
  491.                 
  492.                 note = inNote + LOW( ch->arg);
  493.                 if (note < NUMBER_NOTES) ch->arp[ 2] = GetOldPeriod( note, ch->fineTune, intDriver);
  494.                    
  495.                 ch->arpindex = 0;
  496.                 ch->arp[ 0] = ch->period;
  497.                 
  498.                 ch->arpUse = true;
  499.             }
  500.             else ch->arpUse = false;
  501.         }
  502.     break;
  503.     
  504.     case slidevolE:                        // OK
  505.         parse_slidevol( ch, ch->arg);
  506.     break;
  507.     
  508.     case extendedE:
  509.         switch( HI( ch->arg))
  510.         {
  511.             case 0:        // Turn On/Off filter
  512.             break;
  513.             
  514.             case 1:        // Fineslide up
  515.                 temp = LOW( ch->arg);
  516.                 ch->period -= temp*4;
  517.             //    ch->slide = temp;
  518.             break;
  519.             
  520.             case 2:        // Fineslide down
  521.                 temp = LOW( ch->arg);
  522.                 ch->period += temp*4;
  523.             //    ch->slide = temp;
  524.             break;
  525.             
  526.             case 3:        // Set glissando on/off
  527.                 
  528.             break;
  529.             
  530.             case 4:        // Set vibrato waveform
  531.                 switch( LOW( ch->arg))
  532.                 {
  533.                     case 0:
  534.                     case 4:
  535.                         ch->vibtype = 0;
  536.                     break;
  537.                     
  538.                     case 1:
  539.                     case 5:
  540.                         ch->vibtype = 1;
  541.                     break;
  542.                     
  543.                     case 2:
  544.                     case 6:
  545.                         ch->vibtype = 2;
  546.                     break;
  547.                     
  548.                     case 3:
  549.                     case 7:
  550.                         ch->vibtype = 0;
  551.                     break;
  552.                 }
  553.             break;
  554.             
  555.             case 5:        // Set finetune value
  556.             //    ch->fineTune    = finetune[ LOW( ch->arg)];
  557.             //    ch->period    = GetOldPeriod( ch->Amiga, ch->fineTune);
  558.             break;
  559.             
  560.             case 6:        // Loop pattern
  561.             break;
  562.             
  563.             case 7:        // Set tremolo waveform
  564.             break;
  565.             
  566.             case 8:        // Set Panning
  567.                 ch->pann = LOW( ch->arg);
  568.                 
  569.                 if(ch->pann<=8) ch->pann<<=4;
  570.                 else ch->pann*=17;
  571.                 
  572.                 ch->pann = ( (long) ch->pann * (long)  MAX_PANNING) / (long) 0xFF;
  573.                 
  574.                 if( ch->pann < 0) ch->pann = 0;
  575.                 else if( ch->pann > MAX_PANNING) ch->pann = MAX_PANNING;
  576.                 
  577.                 ch->PanningE8 = true;
  578.             break;
  579.             
  580.             case 9:
  581.                 if(LOW( ch->arg))
  582.                 {
  583.                     if( ch->trig == 0)
  584.                     {
  585.                         //ch->kick    = 1;
  586.                         ch->trig    = LOW( ch->arg);
  587.                     }
  588.                     ch->trig--;
  589.                 }
  590.             break;
  591.  
  592.             case 10:    // Fine volume slide up
  593.                 ch->vol += LOW( ch->arg);
  594.                 
  595.                 if( ch->vol < MIN_VOLUME) ch->vol = MIN_VOLUME;
  596.                 else if( ch->vol > MAX_VOLUME) ch->vol = MAX_VOLUME;
  597.             break;
  598.             
  599.             case 11:    // Fine volume slide down
  600.                 ch->vol -= LOW( ch->arg);
  601.                 
  602.                 if( ch->vol < MIN_VOLUME) ch->vol = MIN_VOLUME;
  603.                 else if( ch->vol > MAX_VOLUME) ch->vol = MAX_VOLUME;
  604.             break;
  605.             
  606.             case 12:    // Cut sample
  607.             break;
  608.             
  609.             case 13:    // Delay sample
  610.             break;
  611.             
  612.             case 14:    // Delay pattern
  613.                 intDriver->PatDelay = LOW( ch->arg) + 1;
  614.             break;
  615.             
  616.             case 15:    // Invert loop
  617.             break;
  618.         }
  619.  
  620.     break;
  621.     
  622.     case portamentoE:                // OK
  623.     {
  624.         long    inNote = ch->note;
  625.         
  626.         ch->pitchrate = ch->arg;
  627.         
  628.         if( inNote == 0xFF) inNote = ch->noteOld;
  629.         
  630.         if( inNote != 0xFF)
  631.         {
  632.             ch->pitchgoal = GetOldPeriod( inNote, ch->fineTune, intDriver);
  633.         }
  634.         else if( ch->pitchgoal == 0) ch->pitchgoal = ch->period;
  635.     }
  636.     break;
  637.     
  638.     case portaslideE:                // OK
  639.     {
  640.         long    inNote = ch->note;
  641.         
  642.         if( inNote == 0xFF) inNote = ch->noteOld;
  643.         
  644.         if( inNote != 0xFF)
  645.         {
  646.             ch->pitchgoal = GetOldPeriod( inNote, ch->fineTune, intDriver);
  647.         }
  648.         else if( ch->pitchgoal == 0) ch->pitchgoal = ch->period;
  649.         
  650.         parse_slidevol(ch, ch->arg);
  651.     }
  652.     break;
  653.     
  654.     case vibratoslideE:
  655.         ch->periodOld = ch->period;
  656.  
  657.            parse_slidevol(ch, ch->arg);
  658.     break;
  659.     
  660.     case speedE:
  661.         if( ch->arg < 32)        /** Setting de la speed + reset de la finespeed **/
  662.         {
  663.             if( ch->arg != 0) intDriver->speed = ch->arg;
  664.         }
  665.         else        /** Setting de finespeed **/
  666.         {
  667.             intDriver->finespeed = ch->arg;
  668.         }
  669.     break;
  670.             
  671.     case skipE:
  672.     break;
  673.     
  674.     case fastskipE:
  675.     break;
  676.     
  677.     case offsetE:
  678.         ch->curPtr = ch->begPtr;
  679.         
  680.         aL = ch->arg;
  681.         aL *= 256L;
  682.         
  683.         if( ch->amp == 16) aL *= 2;
  684.         if( ch->stereo == true) aL *= 2;
  685.         
  686.         ch->curPtr += aL;
  687.     break;
  688.     
  689.     case panningE:
  690.         ch->pann = ch->arg;
  691.         
  692.         ch->pann = ( (long) ch->pann * (long)  MAX_PANNING) / (long) 0xFF;
  693.         
  694.         if( ch->pann < 0) ch->pann = 0;
  695.         else if( ch->pann > MAX_PANNING) ch->pann = MAX_PANNING;
  696.     break;
  697.     
  698.     case volumeE:
  699.         ch->vol = ch->arg;
  700.         
  701.         if( ch->vol < MIN_VOLUME) ch->vol = MIN_VOLUME;
  702.         else if( ch->vol > MAX_VOLUME) ch->vol = MAX_VOLUME;
  703.     break;
  704.     }
  705. }
  706.  
  707. void DoVolCmd( Channel *ch, short call, MADDriverRec *intDriver)
  708. {
  709. short    vol = ch->volcmd;
  710. short    volLO = vol & 0xf;
  711.  
  712.     switch( vol >> 4)
  713.     {
  714.         case 0x6:                    // volslide down
  715.             ch->vol -= volLO;
  716.         
  717.             if( ch->vol < MIN_VOLUME) ch->vol = MIN_VOLUME;
  718.             else if( ch->vol > MAX_VOLUME) ch->vol = MAX_VOLUME;
  719.         break;
  720.  
  721.         case 0x7:                    // volslide up
  722.             ch->vol += volLO;
  723.         
  724.             if( ch->vol < MIN_VOLUME) ch->vol = MIN_VOLUME;
  725.             else if( ch->vol > MAX_VOLUME) ch->vol = MAX_VOLUME;
  726.         break;
  727.  
  728.         // volume-row fine volume slide is compatible with protracker
  729.         //   EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as
  730.         //  opposed to 'take the last sliding value'.
  731.         //
  732.  
  733.         case 0x8:                        // finevol down
  734.         break;
  735.  
  736.         case 0x9:                       // finevol up
  737.         break;
  738.         
  739.         case 0xa:                       // set vibrato speed
  740.         break;
  741.  
  742.         case 0xb:                       // vibrato
  743.         break;
  744.  
  745.         case 0xc:                       // set panning
  746.         break;
  747.  
  748.         case 0xd:                       // pann slide left
  749.             if(vol&0xf)
  750.             {
  751.                 ch->pann -= volLO/4;
  752.                 
  753.                 if( ch->pann < 0) ch->pann = 0;
  754.                 else if( ch->pann > MAX_PANNING) ch->pann = MAX_PANNING;
  755.             }
  756.             break;
  757.  
  758.         case 0xe:                       // pann slide right
  759.             if(vol&0xf)
  760.             {
  761.                 ch->pann += volLO/4;
  762.                 
  763.                 if( ch->pann < 0) ch->pann = 0;
  764.                 else if( ch->pann > MAX_PANNING) ch->pann = MAX_PANNING;
  765.             }
  766.         break;
  767.  
  768.         case 0xf:                       // tone porta
  769.         break;
  770.     }
  771. }