home *** CD-ROM | disk | FTP | other *** search
/ Amiga Dream 59 / CDDream59.ISO / BeOs / Sound / Intel / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Interrupt.c < prev    next >
Text File  |  1999-01-02  |  34KB  |  1,371 lines

  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. #ifdef _MIDIHARDWARE_
  28. #include "OMS.h"
  29. #endif
  30.  
  31. void SampleMIDI( Channel *curVoice, short channel, short curN, MADDriverRec *intDriver);
  32. void ApplyFilters( MADDriverRec *intDriver);
  33. void ApplySurround( MADDriverRec *intDriver);
  34.  
  35. /*long DoVolPanning( short whichChannel, Channel *ch, MADDriverRec *intDriver)    // MAX = 64
  36. {
  37.     // Compute Volume !
  38.     long pannValue;
  39.     long temp = ( (long) ch->vol * (long) ch->volEnv * (long) ch->volFade) /( 64L*32767L );
  40.     
  41.     if( !intDriver->Active[ ch->ID]) return 0;
  42.     
  43.     if( intDriver->curMusic != 0L) temp = (temp * (long) intDriver->curMusic->header->chanVol[ ch->ID]) / MAX_VOLUME;
  44.     else temp = 64;
  45.     
  46.     // Compute Panning
  47.     
  48.     if( whichChannel != 3)
  49.     {
  50.         pannValue = ch->pannEnv;
  51.         
  52.         if( whichChannel == 1) pannValue = MAX_PANNING - pannValue;
  53.         
  54.         temp = (temp * pannValue) / MAX_PANNING;
  55.     }
  56.     
  57.     // Vol Global
  58.     
  59.     temp = (temp * intDriver->VolGlobal) / (MAX_VOLUME + 20);
  60.     
  61.     if( temp > 64) temp = 64;
  62.     
  63.     return temp;
  64. }*/
  65.  
  66. long DoVolPanning256( short whichChannel, Channel *ch, MADDriverRec *intDriver)    // MAX = 256
  67. {
  68.     // Compute Volume !
  69.     long pannValue;
  70.     long temp = ( (long) ch->vol * (long) ch->volEnv * (long) ch->volFade) /( 16L*32767L );
  71.     
  72.     if( !intDriver->Active[ ch->ID]) return 0;
  73.     
  74.     if( intDriver->curMusic != 0L) temp = (temp * (long) intDriver->curMusic->header->chanVol[ ch->ID]) / MAX_VOLUME;
  75.     else temp = 256;
  76.     
  77.     // Compute Panning
  78.     
  79.     if( whichChannel != 3)
  80.     {
  81.         pannValue = ch->pannEnv;
  82.         
  83.         if( whichChannel == 1) pannValue = MAX_PANNING - pannValue;
  84.         
  85.         temp = (temp * pannValue) / MAX_PANNING;
  86.     }
  87.     
  88.     // Vol Global
  89.     
  90.     temp = (temp * intDriver->VolGlobal) / (MAX_VOLUME + 20);
  91.     
  92.     if( temp > 256) temp = 256;
  93.     
  94.     return temp;
  95. }
  96.  
  97. void MADCleanDriver( MADDriverRec *intDriver)
  98. {
  99.     short        i, x;
  100.  
  101.     for( i = 0; i < MAXTRACK; i++)
  102.     {
  103.         intDriver->chan[i].ID        = i;
  104.         
  105.         intDriver->chan[i].begPtr     = 0L;
  106.         intDriver->chan[i].maxPtr     = 0L;
  107.         intDriver->chan[i].curPtr     = 0L;
  108.         intDriver->chan[i].sizePtr     = 0L;
  109.         
  110.         intDriver->chan[i].amp        = 8;
  111.  
  112.         intDriver->chan[i].loopBeg     = 0;
  113.         intDriver->chan[i].loopSize    = 0;
  114.         
  115.         intDriver->chan[i].ins         = 0;
  116.         intDriver->chan[i].insOld     = 0;
  117.  
  118.         intDriver->chan[i].fineTune = NOFINETUNE;
  119.  
  120.         intDriver->chan[i].note        = 0xFF;
  121.         intDriver->chan[i].noteOld    = 0xFF;
  122.  
  123.         
  124.         intDriver->chan[i].period    = GetOldPeriod( 40, NOFINETUNE, intDriver);
  125.         intDriver->chan[i].periodOld= GetOldPeriod( 40, NOFINETUNE, intDriver);
  126.         
  127.         intDriver->chan[i].vol        = 64;
  128.         intDriver->chan[i].cmd        = 0;
  129.         intDriver->chan[i].arg        = 0;
  130.         
  131.         for( x = 0; x < MAX_ARP; x++) intDriver->chan[i].arp[ x] = 0;
  132.         intDriver->chan[i].arpindex = 0;
  133.         intDriver->chan[i].arpUse = false;
  134.         
  135.         intDriver->chan[i].viboffset    = 0;
  136.         intDriver->chan[i].vibdepth     = 0;
  137.         intDriver->chan[i].vibrate         = 0;
  138.         intDriver->chan[i].vibtype         = 0;
  139.         intDriver->chan[i].slide         = 0;
  140.         intDriver->chan[i].pitchgoal     = 0;
  141.         intDriver->chan[i].pitchrate     = 0;
  142.         intDriver->chan[i].volumerate     = 0;
  143.         intDriver->chan[i].samplePtr     = 0L;
  144.         intDriver->chan[i].volcmd        = 0L;
  145.         
  146.         for( x = 0; x < 16; x++) intDriver->chan[ i].oldArg[ x] = 0;
  147.         
  148.         intDriver->chan[i].KeyOn        = false;
  149.         intDriver->chan[i].a            = 0;
  150.         intDriver->chan[i].b            = 1;
  151.         intDriver->chan[i].p            = 0;
  152.         intDriver->chan[i].volEnv        = 64;
  153.         intDriver->chan[i].volFade        = 32767;
  154.         intDriver->chan[i].lAC            = 0;
  155.         
  156.         intDriver->chan[i].lastWordR        = 0;
  157.         intDriver->chan[i].lastWordL        = 0;
  158.         intDriver->chan[i].curLevelL        = 0;
  159.         intDriver->chan[i].curLevelR        = 0;
  160.         intDriver->chan[i].prevPtr        = 0;
  161.         intDriver->chan[i].prevVol0        = 1;
  162.         intDriver->chan[i].prevVol1        = 1;
  163.         
  164.         intDriver->chan[i].loopType    = eClassicLoop;
  165.         intDriver->chan[i].pingpong    = false;
  166.         
  167.         intDriver->chan[i].preOff            = 0xFFFFFFFF;
  168.         intDriver->chan[i].preVal2        = 0;
  169.         intDriver->chan[i].preVal2R        = 0;
  170.         
  171.         intDriver->chan[i].spreVal2        = 0;
  172.         intDriver->chan[i].spreVal2R    = 0;
  173.         
  174.         intDriver->chan[i].preVal            = 0;
  175.         intDriver->chan[i].spreVal        = 0;
  176.         
  177.         intDriver->chan[i].RemoverWorking        = false;
  178.         intDriver->chan[i].TICKREMOVESIZE        = 1;
  179.     }
  180.     
  181.     intDriver->BufCounter = 0;    intDriver->BytesToGenerate = 0;
  182.     
  183.     for( i = 0; i < MAXTRACK; i++) intDriver->TrackLineReading[ i] = true;
  184. }
  185.  
  186. long Interpolate(long p,long p1,long p2,long v1,long v2)
  187. {
  188.     long dp,dv,di;
  189.  
  190.     if( p1 == p2) return v1;
  191.  
  192.     dv=v2-v1;
  193.     dp=p2-p1;
  194.     di=p-p1;
  195.  
  196.     return v1 + ((long)(di*dv) / dp);
  197. }
  198.  
  199. long InterpolateEnv(long p, EnvRec *a,EnvRec *b)
  200. {
  201.     if( p < a->pos) return a->val;
  202.     return(Interpolate(p,a->pos,b->pos,a->val,b->val));
  203. }
  204.  
  205. void ProcessFadeOut( Channel *ch, MADDriverRec *intDriver)
  206. {
  207.     if( intDriver->curMusic != 0L)
  208.     {
  209.         if( !ch->KeyOn)
  210.         {
  211.             ch->volFade -= intDriver->curMusic->fid[ ch->ins].volFade;
  212.             if( ch->volFade < 0)
  213.             {
  214.                 ch->volFade     = 0;
  215.                 ch->loopBeg     = 0;
  216.                 ch->loopSize     = 0;
  217.             }
  218.         }
  219.     }
  220. }
  221.  
  222. void ProcessEnvelope( Channel *ch, MADDriverRec *intDriver)
  223. {
  224.     long        v;
  225.     InstrData    *curIns;
  226.     
  227.     ch->volEnv = 64;
  228.     if( ch->ins < 0) return;
  229.     if( ch->samplePtr != 0L) return;
  230.     curIns = &intDriver->curMusic->fid[ ch->ins];
  231.     if( curIns->volSize <= 0) return;
  232.     
  233.     if( curIns->volType & EFON)
  234.     {
  235.         //  active? -> copy variables
  236.         
  237.         Byte     a,b;
  238.         short    p;
  239.         
  240.         a=ch->a;
  241.         b=ch->b;
  242.         p=ch->p;
  243.         
  244.         if( curIns->volSize == 1)        // Just 1 point !
  245.         {
  246.             v = curIns->volEnv[a].val;
  247.             p = curIns->volEnv[a].pos;
  248.         }
  249.         else
  250.         {
  251.             v = InterpolateEnv( p, &curIns->volEnv[a], &curIns->volEnv[b]);
  252.  
  253.             if((curIns->volType & EFSUSTAIN) && ch->KeyOn && a==curIns->volSus && p==curIns->volEnv[a].pos){
  254.             }
  255.             else{
  256.                 p++;
  257.                 
  258.                 if(p >= curIns->volEnv[b].pos)
  259.                 {
  260.                     a=b; b++;
  261.                     
  262.                     if(curIns->volType & EFLOOP)
  263.                     {
  264.                         if(b > curIns->volEnd)
  265.                         {
  266.                             a=curIns->volBeg;
  267.                             b=a+1;
  268.                             p=curIns->volEnv[a].pos;
  269.                         }
  270.                     }
  271.                     else
  272.                     {
  273.                         if(b >= curIns->volSize)
  274.                         {
  275.                             b--;
  276.                             p--;
  277.                         }
  278.                     }
  279.                 }
  280.             }
  281.         }
  282.         
  283.         ch->a=a;
  284.         ch->b=b;
  285.         ch->p=p;
  286.         
  287.         ch->volEnv = v;
  288.     }
  289. }
  290.  
  291. void ProcessPanning( Channel *ch, MADDriverRec *intDriver)
  292. {
  293.     long        v;
  294.     InstrData    *curIns;
  295.     
  296.     ch->pannEnv = ch->pann;
  297.     if( ch->ins < 0) return;
  298.     if( ch->samplePtr != 0L) return;
  299.     curIns = &intDriver->curMusic->fid[ ch->ins];
  300.     if( curIns->pannSize <= 0) return;
  301.     
  302.     if( curIns->pannType & EFON)
  303.     {
  304.         //  active? -> copy variables
  305.         
  306.         Byte     aa,bb;
  307.         short    pp;
  308.         
  309.         aa = ch->aa;
  310.         bb = ch->bb;
  311.         pp = ch->pp;
  312.         
  313.         if( curIns->pannSize == 1)        // Just 1 point !
  314.         {
  315.             v = curIns->pannEnv[ aa].val;
  316.             pp = curIns->pannEnv[ aa].pos;
  317.         }
  318.         else
  319.         {
  320.             v = InterpolateEnv( pp, &curIns->pannEnv[ aa], &curIns->pannEnv[ bb]);
  321.  
  322.             pp++;
  323.             
  324.             if(pp >= curIns->pannEnv[bb].pos)
  325.             {
  326.                 aa=bb; bb++;
  327.                 
  328.                 if(curIns->pannType & EFLOOP)
  329.                 {
  330.                     if(bb > curIns->pannEnd)
  331.                     {
  332.                         aa=curIns->pannBeg;
  333.                         bb=aa+1;
  334.                         pp=curIns->pannEnv[aa].pos;
  335.                     }
  336.                 }
  337.                 else
  338.                 {
  339.                     if(bb >= curIns->pannSize)
  340.                     {
  341.                         bb--;
  342.                         pp--;
  343.                     }
  344.                 }
  345.             }
  346.         }
  347.         ch->aa=aa;
  348.         ch->bb=bb;
  349.         ch->pp=pp;
  350.         
  351.         ch->pannEnv = v;
  352.     }
  353. }
  354.  
  355. void StartEnvelope( Channel *ch)
  356. {
  357.     ch->p=0;
  358.     ch->a=0;
  359.     ch->b=1;
  360. }
  361.  
  362. void StartPanning( Channel *ch)
  363. {
  364.     ch->pp=0;
  365.     ch->aa=0;
  366.     ch->bb=1;
  367. }
  368.  
  369. long GetOldPeriod( short note, long c2spd, MADDriverRec *intDriver)
  370. {
  371.     unsigned long     period, n,o;
  372.     
  373.     if( note == 0xFF) return 4242;
  374.     if( note == 0xFE) return 4242;
  375.     
  376. //if(!c2spd) DebugStr("\pNo c2spd");
  377.     if(!c2spd) return 4242;
  378.     
  379.   if( note < 0) note = 0;
  380.     
  381.     n = note%12;
  382.     o = note/12;
  383.     
  384.     period = (unsigned long) ((unsigned long) ( 8363UL * ((unsigned long) intDriver->lib->mytab[ n]) ) >> o ) / (unsigned long) c2spd;
  385.     
  386.     if( period == 0L) period = 7242;
  387.     
  388.     return period;
  389.  
  390. //    return( getlogperiod( note, c2spd));
  391.  
  392. //    period = GetFreq2( getlinearperiod( note, c2spd)) * AMIGA_CLOCKFREQ2;
  393. //    return( period);
  394. }
  395.  
  396. void ReadNote( Channel *curVoice, Cmd *theNoteCmd, MADDriverRec *intDriver)
  397. {
  398. Cmd            intCmd = *theNoteCmd;
  399.  
  400. /********************************************/
  401. /*        EXTRA small positionning          */
  402. /********************************************/
  403.  
  404. if( intCmd.cmd == 0x0E && (intCmd.arg >> 4) == 0x0D)
  405. {
  406.     if( intDriver->smallcounter == 0 && !curVoice->GEffect)
  407.     {
  408.         curVoice->GEffect     = true;
  409.         curVoice->GPat         = intDriver->Pat;
  410.         curVoice->GReader     = intDriver->PartitionReader;
  411.     }
  412.     
  413.     if( intDriver->smallcounter >= (intCmd.arg & 0x0F))
  414.     {
  415.         curVoice->GEffect = false;        // <- Continue - Play note NOW !
  416.     }
  417.     else return;                        // <- Do it later
  418. }
  419. else curVoice->GEffect = false;            // <- Continue
  420.  
  421. /********************************************/
  422. /* Play a sample sound in priority to music */
  423. /********************************************/
  424. if( curVoice->samplePtr != 0L) return;
  425.  
  426. /********************************************/
  427.  
  428. /********************************************/
  429. /*        Read command and compute it       */
  430. /********************************************/
  431. else if( intCmd.ins != 0 || (intCmd.note != 0xFF && intCmd.note != 0xFE))
  432. {
  433.     /********************************/
  434.     /* PrÄpare les notes manquantes */
  435.     /********************************/
  436.     
  437.     /********************************/
  438.     
  439.     if( intCmd.note == 0xFF)
  440.     {
  441.         if( intCmd.ins == curVoice->insOld)        // RESET ONLY VOLUME
  442.         {
  443.             if(intCmd.cmd != volumeE && intCmd.ins != 0)
  444.             {
  445.                 if( curVoice->samp < intDriver->curMusic->fid[ intCmd.ins].numSamples)
  446.                 {
  447.                     sData    *curData;
  448.                     
  449.                     curData                        = intDriver->curMusic->sample[ intDriver->curMusic->fid[ intCmd.ins].firstSample + curVoice->samp];
  450.                     
  451.                     curVoice->vol             = curData->vol;
  452.                     if( curVoice->vol > MAX_VOLUME) curVoice->vol = MAX_VOLUME;
  453.                   curVoice->volFade        = 32767;
  454.               }
  455.             }
  456.         }
  457.         else intCmd.note            = curVoice->noteOld;
  458.     }
  459.     else curVoice->noteOld         = intCmd.note;
  460.     
  461.     /********************************/
  462.     
  463.     if( intCmd.ins == 0)         { intCmd.ins                    = curVoice->insOld;}
  464.     else                                         { curVoice->insOld         = intCmd.ins; }
  465.         
  466.     /********************************/
  467.     
  468.     
  469.     
  470.     
  471.     if( intCmd.ins != 0 && (intCmd.note != 0xFF && intCmd.note != 0xFE))
  472.     {
  473.         sData    *curData;
  474.         short    ins, samp;
  475.         
  476.         /**** INSTRUMENT ****/
  477.         
  478.         ins                        = intCmd.ins - 1;        if( ins >= MAXINSTRU) ins = MAXINSTRU-1;
  479.         samp                    = intDriver->curMusic->fid[ ins].what[ intCmd.note];
  480.         
  481.         if( intDriver->DriverSettings.driverMode == MIDISoundDriver)
  482.         {
  483.             curVoice->ins            = ins;
  484.         }
  485.         
  486.         if( samp < intDriver->curMusic->fid[ ins].numSamples)
  487.         {
  488.             curData                        = intDriver->curMusic->sample[ intDriver->curMusic->fid[ ins].firstSample + samp];
  489.             curVoice->ins            = ins;
  490.             curVoice->amp            = curData->amp;
  491.             curVoice->stereo    = curData->stereo;
  492.             curVoice->samp        = samp;
  493.             curVoice->loopType= curData->loopType;
  494.             
  495.             /**** RESET NOTE ****/
  496.             if( intCmd.cmd != portamentoE && intCmd.cmd != portaslideE)
  497.             {
  498.                 curVoice->prevPtr        = 0L;
  499.                 curVoice->maxPtr         = curVoice->curPtr = curVoice->begPtr = curData->data;
  500.                 curVoice->maxPtr         += curData->size;
  501.                 curVoice->sizePtr        = curData->size;
  502.                 curVoice->lAC                = 0;
  503.                 curVoice->pingpong    = false;
  504.                 curVoice->preOff        = 0xFFFFFFFF;
  505.                 curVoice->preVal        = 0;
  506.                 curVoice->spreVal        = 0;
  507.                 curVoice->preVal2        = *curVoice->curPtr;
  508.                 if( curVoice->amp == 8) curVoice->preVal2R    = *(curVoice->curPtr+1);
  509.                 else curVoice->preVal2R    = *(curVoice->curPtr+2);
  510.                 curVoice->spreVal2    = *(short*) curVoice->curPtr;
  511.                 curVoice->spreVal2R    = *(short*) (curVoice->curPtr+2);
  512.                 
  513.                 if( curData->loopSize > 2)
  514.                 {
  515.                     curVoice->loopBeg     = curData->loopBeg;
  516.                     curVoice->loopSize    = curData->loopSize;
  517.                     curVoice->maxPtr     = (Ptr) ((long) curData->data + curData->loopBeg + curData->loopSize);
  518.                 }
  519.                 else
  520.                 {
  521.                     curVoice->loopBeg     = 0;
  522.                     curVoice->loopSize    = 0;
  523.                 }
  524.                 curVoice->viboffset        = 0;
  525.                 
  526.                 if(intCmd.cmd != panningE)
  527.                 {
  528.                     curVoice->pann             = intDriver->curMusic->header->chanPan[ curVoice->ID];
  529.                     if( curVoice->pann > MAX_PANNING) curVoice->pann = MAX_PANNING;
  530.                 }
  531.                 
  532.                 StartPanning( curVoice);
  533.                 StartEnvelope( curVoice);
  534.             }
  535.             
  536.             if(intCmd.cmd != volumeE && theNoteCmd->ins != 0)
  537.             {
  538.                 curVoice->vol             = curData->vol;
  539.                 if( curVoice->vol > MAX_VOLUME) curVoice->vol = MAX_VOLUME;
  540.               curVoice->volFade        = 32767;
  541.             }
  542.             
  543.             intDriver->InstruTube[ ins]         = 64;
  544.             intDriver->InstruActif[ ins]         = curVoice->ID;
  545.         }
  546.     }
  547.     
  548.     if( intCmd.note != 0xFF && intCmd.note != 0xFE)
  549.     {
  550.         /**** NOTE & PERIOD ****/
  551.         
  552.         sData    *curData;
  553.         short    samp;
  554.  
  555.         samp                    = intDriver->curMusic->fid[ curVoice->ins].what[ intCmd.note];
  556.         if( samp < intDriver->curMusic->fid[ curVoice->ins].numSamples)
  557.         {
  558.             curData                    = intDriver->curMusic->sample[ intDriver->curMusic->fid[ curVoice->ins].firstSample + samp];
  559.             
  560.             curVoice->note            = intCmd.note + curData->relNote;
  561.             curVoice->fineTune        = curData->c2spd;
  562.             curVoice->KeyOn            = true;
  563.             
  564.             if( intCmd.cmd != portamentoE && intCmd.cmd != portaslideE)
  565.             {
  566.                 curVoice->period         = GetOldPeriod( curVoice->note, curVoice->fineTune, intDriver);
  567.                 curVoice->periodOld     = curVoice->period = (curVoice->period * (long) intDriver->FreqExt) / 80L;
  568.             }
  569.         }
  570.         
  571.         /***********************/
  572.         /* Pour le MIDI Driver */
  573.         /***********************/
  574.         if( intDriver->DriverSettings.driverMode == MIDISoundDriver)
  575.         {
  576.             if( intDriver->NoteOld[ curVoice->ID] != -1)
  577.             {
  578.                 NoteOff( intDriver->InstuNoOld[ curVoice->ID], intDriver->NoteOld[ curVoice->ID], intDriver->VelocityOld[ curVoice->ID], intDriver);
  579.                 intDriver->NoteOld[ curVoice->ID] = -1;
  580.             }
  581.             
  582.             SampleMIDI( curVoice, curVoice->ins, intCmd.note, intDriver);
  583.             
  584.             intDriver->InstuNoOld[ curVoice->ID]    = curVoice->ins;
  585.             intDriver->NoteOld[ curVoice->ID]        = intCmd.note;
  586.             intDriver->VelocityOld[ curVoice->ID]    = curVoice->vol;
  587.         }
  588.         /***********************/
  589.     }
  590. }
  591. else
  592. {
  593.     curVoice->note = 0xFF;
  594. }
  595.  
  596. /**************/
  597. /*   VOLUME   */
  598. /**************/
  599. if( intCmd.vol != 0xFF)
  600. {
  601.     if(intCmd.vol >= 0x10 && intCmd.vol <= 0x50)
  602.     {
  603.         curVoice->vol = intCmd.vol - 0x10;
  604.         if( curVoice->vol < MIN_VOLUME) curVoice->vol = MIN_VOLUME;
  605.         else if( curVoice->vol > MAX_VOLUME) curVoice->vol = MAX_VOLUME;
  606.  
  607.         curVoice->volcmd = 0;
  608.     }
  609.     else curVoice->volcmd = intCmd.vol;
  610. }
  611. else curVoice->volcmd = 0;
  612.  
  613. curVoice->cmd        = intCmd.cmd;
  614. curVoice->arg         = intCmd.arg;
  615.  
  616. SetUpEffect( curVoice, intDriver);
  617.  
  618. if( intCmd.ins != 0 && intCmd.note != 0xFF) intDriver->Tube[ curVoice->ID] = curVoice->vol;
  619.  
  620.  
  621. /**************/
  622. /*   KEY OFF  */
  623. /**************/
  624. if( intCmd.note == 0xFE)
  625. {
  626.     curVoice->KeyOn    = false;
  627.     
  628.     if( intDriver->DriverSettings.driverMode == MIDISoundDriver)
  629.     {
  630.         if( intDriver->NoteOld[ curVoice->ID] != -1)
  631.             NoteOff( intDriver->InstuNoOld[ curVoice->ID], intDriver->NoteOld[ curVoice->ID], intDriver->VelocityOld[ curVoice->ID], intDriver);
  632.         intDriver->NoteOld[ curVoice->ID] = -1;
  633.     }
  634. }
  635. }
  636.  
  637. #if defined(powerc) || defined (__powerc)
  638. void ClearDouble( register double long *a, register long xx)
  639. {
  640.     while( xx-- > 0 ) *a++ = 0;
  641. }
  642.  
  643. #else
  644. void ClearDouble( register long *a, register long xx)
  645. {
  646.     xx *=2;
  647.     while( xx-- > 0 ) *a++ = 0;
  648. }
  649. #endif
  650.  
  651. void ComputeReverb8(  Byte *orgPtr,   Byte *destPtr,  long xx, long strength)
  652. {
  653.     long    temp1;
  654.     
  655.     while( xx-- > 0)
  656.     {
  657.         temp1 = (*destPtr) + ((strength * (*orgPtr++ - 0x80)) / 100L);        // - 0x80L
  658.         
  659.         if( temp1 > 0xFF) temp1 = 0xFF;    // overflow ?
  660.         else if( temp1 < 0 ) temp1 = 0;
  661.         
  662.         *(destPtr)++ = temp1;
  663.     }
  664. }
  665.  
  666. void ComputeReverb16( short *orgPtr, short *destPtr, long xx, long strength)
  667. {
  668.     long    temp1;
  669.     long    valP = 0x7FFFL, valN = -0x7FFFL;
  670.     
  671.     while( xx-- > 0)
  672.     {
  673.         temp1 = *destPtr + ((strength * (long) *orgPtr++) / 100L);
  674.         
  675.         if( temp1 > valP) temp1 = valP;    // overflow ?
  676.         else if( temp1 < valN ) temp1 = valN;
  677.         
  678.         *destPtr++ = temp1;
  679.     }
  680. }
  681.  
  682. void NoteAnalyse( MADDriverRec *intDriver)
  683. {
  684. long                    InterruptBufferSize, i, ASCBUFFERCopy;
  685. Ptr                        DataPtrCopy;
  686. long                    tVSYNC;
  687. Boolean                NoteReading;
  688. long                    *DASCopy;
  689. short                    *DASCopy8;
  690.  
  691.     if( intDriver->curMusic != 0L)
  692.     {
  693.         if( intDriver->curMusic->musicUnderModification)
  694.         {    // SILENCE
  695.             long Tracks;
  696.             
  697.     //        if( intDriver->curMusic->header->MAD != 'MADI') DebugStr("\pError in MADI");
  698.             
  699.             switch( intDriver->DriverSettings.outPutMode)
  700.             {
  701.                 case PolyPhonic:                    Tracks    = intDriver->DriverSettings.numChn;    break;
  702.                 default:                                    Tracks  = 2;    break;
  703.             }
  704.             
  705.             Tracks = 1;
  706.             
  707.             switch( intDriver->DriverSettings.outPutBits)
  708.             {
  709.                 case 8:
  710.                     for( i = 0; i < intDriver->ASCBUFFER*Tracks; i++) intDriver->IntDataPtr[ i] = 0x80;
  711.                 break;
  712.                 
  713.                 case 16:
  714.                     DASCopy8 = (short*) intDriver->IntDataPtr;
  715.                     for( i = 0; i < intDriver->ASCBUFFER*Tracks*2L; i++) DASCopy8[ i] = 0;
  716.                 break;
  717.             }
  718.             return;
  719.         }
  720.     }
  721.     
  722.     DataPtrCopy                    = intDriver->IntDataPtr;
  723.     DASCopy                            = intDriver->DASCBuffer;
  724.     DASCopy8                        = intDriver->DASCBuffer8;
  725.     ASCBUFFERCopy                = intDriver->ASCBUFFER;
  726.     InterruptBufferSize = intDriver->ASCBUFFER;
  727.     
  728.     while( InterruptBufferSize > 0)
  729.     {
  730.         /********************/
  731.         /* Sound Generating */
  732.         /********************/
  733.         
  734.         intDriver->ASCBUFFER = intDriver->BytesToGenerate - intDriver->BufCounter;
  735.         
  736.         if( intDriver->ASCBUFFER < 0) intDriver->ASCBUFFER = 0;
  737.         if( intDriver->ASCBUFFER > InterruptBufferSize) { intDriver->ASCBUFFER = InterruptBufferSize;    NoteReading = false;}
  738.         else NoteReading = true;
  739.         
  740.         if( intDriver->ASCBUFFER > 0)
  741.         {
  742.             GenerateSound( intDriver);
  743.             intDriver->BufCounter    += intDriver->ASCBUFFER;
  744.             InterruptBufferSize        -= intDriver->ASCBUFFER;
  745.         }
  746.         
  747.         /**************************/
  748.         /* Note & Effect Analyser */
  749.         /**************************/
  750.         
  751.         if( !NoteReading) InterruptBufferSize = -1;
  752.         else
  753.         {
  754.             NoteReading = false;
  755.             
  756.             /*********/
  757.             // GEffect : extrasmallpositionning
  758.             
  759.             if( intDriver->curMusic != 0L && intDriver->Reading)
  760.             {
  761.                 for( i = 0; i < intDriver->curMusic->header->numChn; i++)
  762.                 {
  763.                     if( intDriver->chan[ i].GEffect)        
  764.                     {
  765.                         ReadNote( &intDriver->chan[ i], GetMADCommand( intDriver->chan[ i].GReader, i, intDriver->curMusic->partition[ intDriver->chan[ i].GPat]), intDriver);
  766.                     }
  767.                 }
  768.             }
  769.             
  770.             /*********/
  771.             
  772.         //    intDriver->extrasmallcounter--;
  773.         //    if( intDriver->extrasmallcounter <= 0)
  774.             {
  775.             //    intDriver->extrasmallcounter = EXTRASMALLCOUNTER;
  776.                 
  777.                 intDriver->smallcounter++;
  778.                 if( intDriver->smallcounter >= intDriver->speed)
  779.                 {
  780.                     intDriver->smallcounter = 0;
  781.                     
  782.                     if( intDriver->curMusic != 0L)
  783.                     {
  784.                         for( i = 0; i < intDriver->curMusic->header->numChn; i++)
  785.                         {
  786.                             if( intDriver->Reading && intDriver->TrackLineReading[ i])
  787.                             {
  788.                                 ReadNote( &intDriver->chan[ i], GetMADCommand( intDriver->PartitionReader, i, intDriver->curMusic->partition[ intDriver->Pat]), intDriver);
  789.                             }
  790.                             
  791.                             ProcessEnvelope( &intDriver->chan[ i], intDriver);
  792.                             ProcessPanning( &intDriver->chan[ i], intDriver);
  793.                             ProcessFadeOut( &intDriver->chan[ i], intDriver);
  794.                         }
  795.                         
  796.                         if( intDriver->Reading)
  797.                         {
  798.                             for( i = 0; i < MAXTRACK; i++) intDriver->TrackLineReading[ i] = true;
  799.                             
  800.                             intDriver->PartitionReader++;
  801.                             if( intDriver->PartitionReader >= intDriver->curMusic->partition[ intDriver->Pat]->header.size)
  802.                             {
  803.                                 intDriver->PartitionReader = 0;
  804.                                 intDriver->endPattern = true;
  805.                                 
  806.                                 if( intDriver->JumpToNextPattern)
  807.                                 {
  808.                                     intDriver->PL++;
  809.                                     intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  810.                                     
  811.                                     if( intDriver->speed == 1 && intDriver->PL >= intDriver->curMusic->header->numPointers)
  812.                                     {
  813.                                         intDriver->PL = 0;
  814.                                         intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  815.                                         
  816.                                         MADCleanDriver( intDriver);
  817.                                         if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
  818.                                         
  819.                                         intDriver->musicEnd = true;
  820.                                     }
  821.                                 }
  822.                             }
  823.                         }
  824.                     }
  825.                 }
  826.                 else
  827.                 {
  828.                     if( intDriver->curMusic != 0L)
  829.                     {
  830.                         for( i = 0 ; i < intDriver->DriverSettings.numChn; i++)
  831.                         {
  832.                             //    if( intDriver->Reading) 
  833.                                 {
  834.                                     DoVolCmd( &intDriver->chan[ i], intDriver->smallcounter, intDriver);
  835.                                     DoEffect( &intDriver->chan[ i], intDriver->smallcounter, intDriver);
  836.                                 }
  837.                                 ProcessEnvelope( &intDriver->chan[ i], intDriver);
  838.                                 ProcessPanning( &intDriver->chan[ i], intDriver);
  839.                                 ProcessFadeOut( &intDriver->chan[ i], intDriver);
  840.                         }
  841.                         
  842.                         if( intDriver->Reading)
  843.                         {
  844.                             if( intDriver->smallcounter == intDriver->speed - 1)
  845.                             {
  846.                                 if( intDriver->PL >= intDriver->curMusic->header->numPointers)
  847.                                 {
  848.                                     intDriver->PL = 0;
  849.                                     intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
  850.                                     
  851.                                     MADCleanDriver( intDriver);
  852.                                     if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
  853.                                     
  854.                                     intDriver->musicEnd = true;
  855.                                 }
  856.                             }
  857.                         }
  858.                     }
  859.                 }
  860.             }
  861.             tVSYNC         = intDriver->VSYNC;
  862.             tVSYNC         /= intDriver->finespeed;
  863.             
  864.             tVSYNC         *= 80L;
  865.             tVSYNC         /= intDriver->VExt;
  866.             
  867.             intDriver->BytesToGenerate += tVSYNC;
  868.         }
  869.     }
  870.     
  871.     intDriver->ASCBUFFER    = ASCBUFFERCopy;
  872.     intDriver->IntDataPtr    = DataPtrCopy;
  873.     intDriver->DASCBuffer    = DASCopy;
  874.     intDriver->DASCBuffer8    = DASCopy8;
  875.     
  876.     if( intDriver->DriverSettings.MicroDelaySize)
  877.     {
  878.         switch( intDriver->DriverSettings.outPutBits)
  879.         {
  880.             case 16:
  881.                 BlockMoveData( intDriver->DASCBuffer + intDriver->ASCBUFFER*2, intDriver->DASCBuffer, intDriver->MDelay*8L);
  882.                 
  883.                 #if defined (powerc)
  884.                 ClearDouble( (long double*) (intDriver->DASCBuffer + intDriver->MDelay*2L), intDriver->ASCBUFFER);
  885.                 #else
  886.                 ClearDouble( (long*) (intDriver->DASCBuffer + intDriver->MDelay*2L), intDriver->ASCBUFFER);
  887.                 #endif
  888.             break;
  889.             
  890.             case 8:
  891.                 if( intDriver->MDelay % 2 != 0)
  892.                 {
  893.                     BlockMoveData( intDriver->DASCBuffer8 + intDriver->ASCBUFFER*2, intDriver->DASCBuffer8, 1 + intDriver->MDelay*4L);
  894.                     
  895.                     #if defined (powerc)
  896.                     ClearDouble( (long double*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), 1 + intDriver->ASCBUFFER/2);
  897.                     #else
  898.                     ClearDouble( (long*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), 1 + intDriver->ASCBUFFER/2);
  899.                     #endif
  900.                 }
  901.                 else
  902.                 {
  903.                     BlockMoveData( intDriver->DASCBuffer8 + intDriver->ASCBUFFER*2, intDriver->DASCBuffer8, intDriver->MDelay*4L);
  904.                 
  905.                     #if defined (powerc)
  906.                     ClearDouble( (long double*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), intDriver->ASCBUFFER/2);
  907.                     #else
  908.                     ClearDouble( (long*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), intDriver->ASCBUFFER/2);
  909.                     #endif
  910.                 }
  911.             break;
  912.         }
  913.     }
  914.     
  915.     //if( intDriver->DriverSettings.antiAliasing) ApplyFilters( intDriver);
  916.     if( intDriver->DriverSettings.surround) ApplySurround( intDriver);
  917.     
  918.     if( intDriver->DriverSettings.Reverb && intDriver->ASCBUFFER < intDriver->RDelay)
  919.     {
  920.         if( intDriver->DriverSettings.outPutMode == DeluxeStereoOutPut)
  921.         {
  922.             switch( intDriver->DriverSettings.outPutBits)
  923.             {
  924.                 case 8:
  925.                     ComputeReverb8( (Byte*) intDriver->ReverbPtr, (Byte*) intDriver->IntDataPtr, intDriver->ASCBUFFER*2L, intDriver->DriverSettings.ReverbStrength);
  926.                     BlockMoveData( intDriver->ReverbPtr + intDriver->ASCBUFFER*2L, intDriver->ReverbPtr, intDriver->RDelay*2L - intDriver->ASCBUFFER*2L);
  927.                     BlockMoveData( intDriver->IntDataPtr, intDriver->ReverbPtr + intDriver->RDelay*2L - intDriver->ASCBUFFER*2L, intDriver->ASCBUFFER*2L);
  928.                 break;
  929.                 
  930.                 case 16:
  931.                     ComputeReverb16( (short*) intDriver->ReverbPtr, (short*) intDriver->IntDataPtr, intDriver->ASCBUFFER*2L, intDriver->DriverSettings.ReverbStrength);
  932.                     BlockMoveData( intDriver->ReverbPtr + intDriver->ASCBUFFER*4, intDriver->ReverbPtr, (intDriver->RDelay - intDriver->ASCBUFFER)*4);
  933.                     BlockMoveData( intDriver->IntDataPtr, intDriver->ReverbPtr + intDriver->RDelay*4 - intDriver->ASCBUFFER*4, intDriver->ASCBUFFER*4);
  934.                 break;
  935.             }
  936.         }
  937.     }
  938. }
  939.  
  940. void Filter8Bit( register Byte *myPtr, MADDriverRec *intDriver)
  941. {
  942.     long    i;
  943.  
  944.     i = intDriver->ASCBUFFER-1;
  945.     while( i-- > 0)
  946.     {
  947.         *myPtr -= ( *myPtr - *(myPtr + 1)) >> 1;
  948.         myPtr++;
  949.     }
  950. }
  951.  
  952. void Filter8BitX( register Byte *myPtr, MADDriverRec *intDriver)
  953. {
  954.     long    i;
  955.  
  956.     i = intDriver->ASCBUFFER-1;
  957.     while( i-- > 0)
  958.     {
  959.         *myPtr -= ( *myPtr - *(myPtr + 2)) >> 1;
  960.         myPtr += 2;
  961.     }
  962. }
  963.  
  964. void Filter16BitX( register short *myPtr, MADDriverRec *intDriver)
  965. {
  966.     long    i;
  967.  
  968.     i = intDriver->ASCBUFFER-1;
  969.     while( i-- > 0)
  970.     {
  971.         *myPtr -= ( *myPtr - *(myPtr + 2)) >> 1;
  972.         myPtr += 2;
  973.     }
  974.     
  975. /*    i = intDriver->ASCBUFFER-2;
  976.     myPtr += 2;
  977.     while( i-- > 0)
  978.     {
  979.         *myPtr -= ((*myPtr - *(myPtr + 2)) + (*myPtr - *(myPtr - 2))) >> 1;
  980.         myPtr += 2;
  981.     }    */
  982. }
  983.  
  984. void ApplyFilters( MADDriverRec *intDriver)
  985. {
  986.     switch( intDriver->DriverSettings.outPutBits)
  987.     {
  988.         case 8:
  989.             switch( intDriver->DriverSettings.outPutMode)
  990.             {
  991.             /*    case MonoOutPut:
  992.                     Filter8Bit( (Byte*) intDriver->IntDataPtr, intDriver);
  993.                 break;
  994.                 
  995.                 case StereoOutPut:
  996.                     Filter8BitX( (Byte*) intDriver->IntDataPtr, intDriver);
  997.                     Filter8BitX( (Byte*) intDriver->IntDataPtr + 1, intDriver);
  998.                 break;
  999.             */
  1000.                 case DeluxeStereoOutPut:
  1001.                     Filter8BitX( (Byte*) intDriver->IntDataPtr, intDriver);
  1002.                     Filter8BitX( (Byte*) intDriver->IntDataPtr + 1, intDriver);
  1003.                 break;
  1004.             }
  1005.         break;
  1006.         
  1007.         case 16:
  1008.             switch( intDriver->DriverSettings.outPutMode)
  1009.             {
  1010.             /*    case MonoOutPut:
  1011.                 break;
  1012.                 
  1013.                 case StereoOutPut:*/
  1014.                 case DeluxeStereoOutPut:
  1015.                 
  1016.             /*    {
  1017.                 short    i;
  1018.                     
  1019.                     for( i = 0; i < 10; i++)
  1020.                     {*/
  1021.                         Filter16BitX( ( short*) intDriver->IntDataPtr, intDriver);
  1022.                         Filter16BitX( ( short*) (intDriver->IntDataPtr) + 1, intDriver);
  1023.                 /*    }
  1024.                 }*/
  1025.                 break;
  1026.             }
  1027.         break;
  1028.     }
  1029. }
  1030.  
  1031. void ApplySurround( MADDriverRec *intDriver)
  1032. {
  1033.     switch( intDriver->DriverSettings.outPutBits)
  1034.     {
  1035.         case 8:
  1036.             switch( intDriver->DriverSettings.outPutMode)
  1037.             {
  1038.                 case DeluxeStereoOutPut:
  1039.                 {
  1040.                 long    i = intDriver->ASCBUFFER;
  1041.                 char    *data = (char*) intDriver->IntDataPtr;
  1042.                     
  1043.                     while( i-- > 0)
  1044.                     {
  1045.                         *data = -1-*data;
  1046.                         data += 2;
  1047.                     }
  1048.                 }
  1049.                 break;
  1050.             }
  1051.         break;
  1052.         
  1053.         case 16:
  1054.             switch( intDriver->DriverSettings.outPutMode)
  1055.             {
  1056.                 case DeluxeStereoOutPut:
  1057.                 {
  1058.                 long        i = intDriver->ASCBUFFER;
  1059.                 short        *data = (short*) intDriver->IntDataPtr;
  1060.                     
  1061.                     while( i-- > 0)
  1062.                     {
  1063.                         *data = -1-*data;
  1064.                         data += 2;
  1065.                     }
  1066.                 }
  1067.                 break;
  1068.             }
  1069.         break;
  1070.     }
  1071. }
  1072.  
  1073. void GenerateSound( MADDriverRec *intDriver)
  1074. {
  1075.     if( intDriver->DriverSettings.driverMode == MIDISoundDriver) return;
  1076.  
  1077.     switch( intDriver->DriverSettings.outPutBits)
  1078.     {
  1079.         case 8:
  1080.             switch( intDriver->DriverSettings.outPutMode)
  1081.             {
  1082.             /*    case MonoOutPut:
  1083.                     Play8Mono( intDriver);
  1084.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER;
  1085.                 break;
  1086.                 
  1087.                 case StereoOutPut:
  1088.                     Play8Stereo( intDriver);
  1089.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER*2L;
  1090.                 break;
  1091.                 */
  1092.                 case DeluxeStereoOutPut:
  1093.                     Play8StereoDelay( intDriver);
  1094.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER*2L;
  1095.                     intDriver->DASCBuffer8    += intDriver->ASCBUFFER*2L;
  1096.                 break;
  1097.                 
  1098.                 case PolyPhonic:
  1099.             //    case MultiFiles:
  1100.                   Play8PolyPhonic( intDriver);
  1101.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER * intDriver->DriverSettings.numChn;
  1102.                 break;
  1103.             }
  1104.         break;
  1105.         
  1106.         case 16:
  1107.             switch( intDriver->DriverSettings.outPutMode)
  1108.             {
  1109.             /*    case MonoOutPut:
  1110.                     Play16Mono( intDriver);
  1111.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER*2L;
  1112.                 break;
  1113.                 
  1114.                 case StereoOutPut:
  1115.                     Play16Stereo( intDriver);
  1116.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER*4L;
  1117.                 break;
  1118.                 */
  1119.                 case DeluxeStereoOutPut:
  1120.                     Play16StereoDelay( intDriver);
  1121.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER*4L;
  1122.                     intDriver->DASCBuffer    += intDriver->ASCBUFFER*2L;
  1123.                 break;
  1124.                 
  1125.                 case PolyPhonic:
  1126.         //        case MultiFiles:
  1127.             //      Play16PolyPhonic( intDriver);
  1128.                     intDriver->IntDataPtr    += intDriver->ASCBUFFER * 2L * intDriver->DriverSettings.numChn;
  1129.                 break;
  1130.             }
  1131.         break;
  1132.     }
  1133. }
  1134.  
  1135. EXP Boolean DirectSave( Ptr myPtr, MADDriverSettings *driverType, MADDriverRec *intDriver)
  1136. {
  1137. Ptr                                    ptrCopy;
  1138. MADDriverSettings        driverCopy;
  1139.  
  1140.     if( intDriver == 0L) return false;    //intDriver = MADGetMADDriverPtr();
  1141.     if( !intDriver->Reading) return false;
  1142.     
  1143.     /*** Copy values ***/
  1144.     ptrCopy         = intDriver->IntDataPtr;
  1145.     if( driverType != 0L) driverCopy    = intDriver->DriverSettings;
  1146.     
  1147.     /*** Install New Values ***/
  1148.     
  1149.     intDriver->IntDataPtr         = myPtr;
  1150.     if( driverType != 0L) intDriver->DriverSettings    = *driverType;
  1151.     
  1152.     /***/            /***/
  1153.     /***/            /***/
  1154.     /***/            /***/
  1155.     
  1156.     NoteAnalyse( intDriver);
  1157.     
  1158.     /***/            /***/
  1159.     /***/            /***/
  1160.     /***/            /***/
  1161.     
  1162.     /*** Restore values ***/
  1163.     
  1164.     intDriver->IntDataPtr         = ptrCopy;
  1165.     if( driverType != 0L) intDriver->DriverSettings    = driverCopy;
  1166.     
  1167.     if( intDriver->musicEnd == true) return false;
  1168.     
  1169.     if( intDriver->curMusic != 0L)
  1170.     {
  1171.         if( intDriver->PL >= intDriver->curMusic->header->numPointers) return false;
  1172.     }
  1173.     
  1174.     return true;
  1175. }
  1176.  
  1177. pascal void DMAPlay ( void)
  1178. {
  1179. /*unsigned    long                deferredArg;
  1180.             long                        *destPtr;
  1181.             Boolean                    DMAPlayNow;
  1182.             short                        *tempIntG = 0L;
  1183.             Ptr                            myPtr;
  1184.             MADDriverRec        *intDriver = MADGetMADDriverPtr();
  1185.             
  1186.     DMAPlayNow = false;
  1187.  
  1188.     if (SND_OUT_IF0)                            // buffer 0 just finished
  1189.     {
  1190.         deferredArg = kBuf0Offset;                // set offset for copy
  1191.         CLEAR_SND_OUT_IF0;                        // clear offending bit
  1192.         destPtr = ( long*) ((long) DMABufferBase + (long) deferredArg);
  1193.  
  1194.         DMAPlayNow = true;
  1195.     }
  1196.  
  1197.     if (SND_OUT_IF1)                            // buffer 1 just finished
  1198.     {
  1199.         deferredArg = kBuf1Offset;                // set offset for copy
  1200.         CLEAR_SND_OUT_IF1;                        // clear offending bit
  1201.         destPtr = ( long*) ((long) DMABufferBase + (long) deferredArg);
  1202.  
  1203.         DMAPlayNow = true;
  1204.     }
  1205.     
  1206.     if (SND_OUT_UNDERRUN)                        // whoops - we underran! clear it, re-enable DMA, & vamoose
  1207.     {
  1208.         CLEAR_UNDERRUN_INT;                        // only one kind of output error
  1209.         SND_OUT_DMA_ENABLE;                        // re-enable sound out (underrun will have stopped it)
  1210.         return;                                    // return without setting up the DeferUserFn
  1211.     }
  1212.  
  1213.     if( DMAPlayNow)
  1214.     {
  1215.         myPtr = intDriver->IntDataPtr;
  1216.         intDriver->IntDataPtr = (Ptr) destPtr;
  1217.         
  1218.         DISABLE_BUF_AND_UNDERRUN_INTS;
  1219.         
  1220.         NoteAnalyse( intDriver);
  1221.  
  1222.         ENABLE_BUF_AND_UNDERRUN_INTS;
  1223.         
  1224.         intDriver->OscilloWavePtr = intDriver->IntDataPtr;
  1225.         intDriver->IntDataPtr = myPtr;
  1226.     }*/
  1227. }
  1228.  
  1229.  
  1230. #ifdef _MAC_H
  1231.  
  1232. Ptr GetMyDoubleBackProc()
  1233. {
  1234.     return (Ptr) MyDoubleBackProc;
  1235. }
  1236.  
  1237. pascal void MyDoubleBackProc(SndChannelPtr chan, SndDoubleBufferPtr doubleBuffer)
  1238. {
  1239.     Ptr                            myPtr;            
  1240.     MADDriverRec        *intDriver;
  1241.     
  1242.     intDriver = (MADDriverRec*) doubleBuffer->dbUserInfo[ 0];
  1243.     
  1244.     /********************/
  1245.     /**   Read Notes   **/
  1246.     /********************/
  1247.     
  1248.     myPtr = intDriver->IntDataPtr;
  1249.     intDriver->IntDataPtr = (char*) doubleBuffer->dbSoundData;
  1250.     
  1251.     NoteAnalyse( intDriver);
  1252.     
  1253.     intDriver->IntDataPtr        = myPtr;
  1254.     intDriver->OscilloWavePtr    = (char*) doubleBuffer->dbSoundData;
  1255.     
  1256.     doubleBuffer->dbNumFrames    = intDriver->ASCBUFFER;
  1257.     doubleBuffer->dbFlags        |= dbBufferReady;
  1258. }
  1259. /*
  1260. MADDriverRec *MODPlayMADDriver;
  1261.  
  1262. #if defined(powerc) || defined (__powerc)
  1263. pascal void MODPlay (VBLTaskPtr theVBLTask)
  1264. {
  1265.     theVBLTask->vblCount = 1;
  1266.  
  1267.     NoteAnalyse( MODPlayMADDriver);
  1268. }
  1269. #else
  1270. pascal long GetVBLRec( void) = 0x2E88;
  1271.  
  1272. void MODPlay()
  1273. {
  1274.     inVBLRec                *recPtr;
  1275.     MADDriverRec        *intDriver;
  1276.     
  1277.     recPtr = (inVBLRec*) GetVBLRec();
  1278.     
  1279.     intDriver = (MADDriverRec*) recPtr->VBLA5;
  1280.     recPtr->VBL.vblCount = 1;
  1281.     
  1282.     NoteAnalyse( intDriver);
  1283. }
  1284. #endif*/
  1285. #endif
  1286. /*
  1287. void BufferCopyM( MADDriverRec *intDriver)
  1288. {
  1289.     Ptr    srcPtr = intDriver->IntDataPtr, destPtr = *((Ptr*) ASCBase);
  1290.     
  1291.     BlockMoveData( srcPtr, destPtr, 370L);
  1292. }
  1293.  
  1294. void BufferCopyS( MADDriverRec *intDriver)
  1295. {
  1296.     register    Ptr        srcPtr = intDriver->IntDataPtr, leftPtr = *((Ptr*) ASCBase), rightPtr = *((Ptr*) ASCBase) + 0x400L;
  1297.     register    short    x = 370;    
  1298.  
  1299.     while( x-- > 0)
  1300.     {
  1301.         *leftPtr++        = *srcPtr++;
  1302.         *rightPtr++        = *srcPtr++;
  1303.     }
  1304. }*/
  1305.  
  1306. #ifdef _MIDIHARDWARE_
  1307. void NoteOff(short oldIns, short oldN, short oldV, MADDriverRec *intDriver)
  1308. {
  1309.     OMSMIDIPacket pack;
  1310.     
  1311.     if( intDriver->gOutNodeRefNum == -1) return;
  1312.     
  1313.     /*** Note - OFF ***/
  1314.  
  1315.     pack.flags    = 0;    //midiMsgType + midiTimeStampCurrent + midiNoCont;
  1316.     pack.len    = 3;
  1317.  
  1318.     pack.data[ 0] = 0x80 + oldIns;
  1319.     pack.data[ 1] = oldN + 12;
  1320.     
  1321.     if( oldV < 64) pack.data[ 2] = 63 + oldV;    
  1322.     else pack.data[ 2] = 127;
  1323.     
  1324.     #if defined(__MWERKS__)
  1325.     OMSWritePacket2( &pack, intDriver->gOutNodeRefNum, intDriver->MIDIPortRefNum);
  1326.     #endif
  1327. }
  1328.  
  1329. void AllNoteOff( MADDriverRec *intDriver)
  1330. {
  1331.     short         i;
  1332.     
  1333.     if( intDriver->gOutNodeRefNum == -1) return;
  1334.     
  1335.     for( i = 0; i < MAXTRACK; i++)
  1336.     {
  1337.         if( intDriver->NoteOld[ i] != -1)
  1338.         {
  1339.             NoteOff( intDriver->InstuNoOld[ i], intDriver->NoteOld[ i], intDriver->VelocityOld[ i], intDriver);
  1340.             intDriver->NoteOld[ i] = -1;
  1341.         }
  1342.     }
  1343. }
  1344.  
  1345. void SampleMIDI( Channel *curVoice, short channel, short curN, MADDriverRec *intDriver)
  1346. {
  1347.     OMSMIDIPacket pack;
  1348.     
  1349.     if( intDriver->gOutNodeRefNum == -1) return;
  1350.     
  1351.     /*** Note - ON ***/
  1352.     
  1353.     pack.flags    = 0;    //midiMsgType + midiTimeStampCurrent + midiNoCont;
  1354.     pack.len    = 3;
  1355.  
  1356.     pack.data[ 0] = 0x90 + channel;
  1357.     
  1358.     pack.data[ 1] = curN + 12;
  1359.     if( curVoice->vol < 64) pack.data[ 2] = 63 + curVoice->vol;    
  1360.     else pack.data[ 2] = 127;
  1361.     
  1362.     #if defined(__MWERKS__)
  1363.     OMSWritePacket2( &pack, intDriver->gOutNodeRefNum, intDriver->MIDIPortRefNum);
  1364.     #endif
  1365. }
  1366. #else
  1367. void SampleMIDI( Channel *curVoice, short channel, short curN, MADDriverRec *intDriver){};
  1368. void AllNoteOff( MADDriverRec *intDriver){};
  1369. void NoteOff(short oldIns, short oldN, short oldV, MADDriverRec *intDriver){};
  1370. #endif
  1371.