home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / ht12_m68k.lha / HivelyTracker / Replayer / src / hvl_replay.c < prev    next >
Encoding:
C/C++ Source or Header  |  2007-01-01  |  55.7 KB  |  1,978 lines

  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6.  
  7. #include <exec/types.h>
  8.  
  9. #ifndef _AMIGAOS3_
  10. #include <exec/exectags.h>
  11. #endif
  12.  
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15.  
  16. #ifdef _AMIGAOS3_
  17. #include "os3_compat.h"
  18. #endif
  19.  
  20. #include "hvl_replay.h"
  21.  
  22. int32 stereopan_left[]  = { 128,  96,  64,  32,   0 };
  23. int32 stereopan_right[] = { 128, 160, 193, 225, 255 };
  24.  
  25. /*
  26. ** Waves
  27. */
  28. #define WHITENOISELEN (0x280*3)
  29.  
  30. #define WO_LOWPASSES   0
  31. #define WO_TRIANGLE_04 (WO_LOWPASSES+((0xfc+0xfc+0x80*0x1f+0x80+3*0x280)*31))
  32. #define WO_TRIANGLE_08 (WO_TRIANGLE_04+0x04)
  33. #define WO_TRIANGLE_10 (WO_TRIANGLE_08+0x08)
  34. #define WO_TRIANGLE_20 (WO_TRIANGLE_10+0x10)
  35. #define WO_TRIANGLE_40 (WO_TRIANGLE_20+0x20)
  36. #define WO_TRIANGLE_80 (WO_TRIANGLE_40+0x40)
  37. #define WO_SAWTOOTH_04 (WO_TRIANGLE_80+0x80)
  38. #define WO_SAWTOOTH_08 (WO_SAWTOOTH_04+0x04)
  39. #define WO_SAWTOOTH_10 (WO_SAWTOOTH_08+0x08)
  40. #define WO_SAWTOOTH_20 (WO_SAWTOOTH_10+0x10)
  41. #define WO_SAWTOOTH_40 (WO_SAWTOOTH_20+0x20)
  42. #define WO_SAWTOOTH_80 (WO_SAWTOOTH_40+0x40)
  43. #define WO_SQUARES     (WO_SAWTOOTH_80+0x80)
  44. #define WO_WHITENOISE  (WO_SQUARES+(0x80*0x20))
  45. #define WO_HIGHPASSES  (WO_WHITENOISE+WHITENOISELEN)
  46. #define WAVES_SIZE     (WO_HIGHPASSES+((0xfc+0xfc+0x80*0x1f+0x80+3*0x280)*31))
  47.  
  48. int8 waves[WAVES_SIZE];
  49. int16 waves2[WAVES_SIZE];
  50.  
  51. CONST int16 vib_tab[] =
  52.   0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
  53.   253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
  54.   0,-24,-49,-74,-97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,-255,
  55.   -253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,-97,-74,-49,-24
  56. };
  57.  
  58. CONST uint16 period_tab[] =
  59. {
  60.   0x0000, 0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970,
  61.   0x08E8, 0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4,
  62.   0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0,
  63.   0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C,
  64.   0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D,
  65.   0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0,
  66.   0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097,
  67.   0x008F, 0x0087, 0x007F, 0x0078, 0x0071
  68. };
  69.  
  70. uint32 panning_left[256], panning_right[256];
  71.  
  72. static inline void clr_l( uint32 *src, uint32 longs)
  73. {
  74.   do {
  75.     *src++ = 0;
  76.     longs--;
  77.   } while (longs > 0);
  78. }
  79.  
  80. void hvl_GenPanningTables( void )
  81. {
  82.   uint32 i;
  83.   float64 aa, ab;
  84.  
  85.   // Sine based panning table
  86.   aa = (3.14159265f*2.0f)/4.0f;   // Quarter of the way through the sinewave == top peak
  87.   ab = 0.0f;                      // Start of the climb from zero
  88.  
  89.   for( i=0; i<256; i++ )
  90.   {
  91.     panning_left[i]  = (uint32)(sin(aa)*255.0f);
  92.     panning_right[i] = (uint32)(sin(ab)*255.0f);
  93.     
  94.     aa += (3.14159265*2.0f/4.0f)/256.0f;
  95.     ab += (3.14159265*2.0f/4.0f)/256.0f;
  96.   }
  97.   panning_left[255] = 0;
  98.   panning_right[0] = 0;
  99. }
  100.  
  101. void hvl_GenSawtooth( int8 *buf, uint32 len )
  102. {
  103.   uint32 i;
  104.   int32  val, add;
  105.   
  106.   add = 256 / (len-1);
  107.   val = -128;
  108.   
  109.   for( i=0; i<len; i++, val += add )
  110.     *buf++ = (int8)val;  
  111. }
  112.  
  113. void hvl_GenTriangle( int8 *buf, uint32 len )
  114. {
  115.   uint32 i;
  116.   int32  d2, d5, d1, d4;
  117.   int32  val;
  118.   int8   *buf2;
  119.   
  120.   d2  = len;
  121.   d5  = len >> 2;
  122.   d1  = 128/d5;
  123.   d4  = -(d2 >> 1);
  124.   val = 0;
  125.   
  126.   for( i=0; i<d5; i++ )
  127.   {
  128.     *buf++ = val;
  129.     val += d1;
  130.   }
  131.   *buf++ = 0x7f;
  132.  
  133.   if( d5 != 1 )
  134.   {
  135.     val = 128;
  136.     for( i=0; i<d5-1; i++ )
  137.     {
  138.       val -= d1;
  139.       *buf++ = val;
  140.     }
  141.   }
  142.   
  143.   buf2 = buf + d4;
  144.   for( i=0; i<d5*2; i++ )
  145.   {
  146.     int8 c;
  147.     
  148.     c = *buf2++;
  149.     if( c == 0x7f )
  150.       c = 0x80;
  151.     else
  152.       c = -c;
  153.     
  154.     *buf++ = c;
  155.   }
  156. }
  157.  
  158. void hvl_GenSquare( int8 *buf )
  159. {
  160.   uint32 i, j;
  161.   
  162.   for( i=1; i<=0x20; i++ )
  163.   {
  164.     for( j=0; j<(0x40-i)*2; j++ )
  165.       *buf++ = 0x80;
  166.     for( j=0; j<i*2; j++ )
  167.       *buf++ = 0x7f;
  168.   }
  169. }
  170.  
  171. static inline float64 clip( float64 x )
  172. {
  173.   if( x > 127.f )
  174.     x = 127.f;
  175.   else if( x < -128.f )
  176.     x = -128.f;
  177.   return x;
  178. }
  179.  
  180. void hvl_GenFilterWaves( int8 *buf, int8 *lowbuf, int8 *highbuf )
  181. {
  182.   static const uint16 lentab[45] = { 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 3, 7, 0xf, 0x1f, 0x3f, 0x7f,
  183.     0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  184.     0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  185.     (0x280*3)-1 };
  186.  
  187.   float64 freq;
  188.   uint32  temp;
  189.   
  190.   for( temp=0, freq=8.f; temp<31; temp++, freq+=3.f )
  191.   {
  192.     uint32 wv;
  193.     int8   *a0 = buf;
  194.     
  195.     for( wv=0; wv<6+6+0x20+1; wv++ )
  196.     {
  197.       float64 fre, high, mid, low;
  198.       uint32  i;
  199.       
  200.       mid = 0.f;
  201.       low = 0.f;
  202.       fre = freq * 1.25f / 100.0f;
  203.       
  204.       for( i=0; i<=lentab[wv]; i++ )
  205.       {
  206.         high  = a0[i] - mid - low;
  207.         high  = clip( high );
  208.         mid  += high * fre;
  209.         mid   = clip( mid );
  210.         low  += mid * fre;
  211.         low   = clip( low );
  212.       }
  213.       
  214.       for( i=0; i<=lentab[wv]; i++ )
  215.       {
  216.         high  = a0[i] - mid - low;
  217.         high  = clip( high );
  218.         mid  += high * fre;
  219.         mid   = clip( mid );
  220.         low  += mid * fre;
  221.         low   = clip( low );
  222.         *lowbuf++  = (int8)low;
  223.         *highbuf++ = (int8)high;
  224.       }
  225.       
  226.       a0 += lentab[wv]+1;
  227.     }
  228.   }
  229. }
  230.  
  231. void hvl_GenWhiteNoise( int8 *buf, uint32 len )
  232. {
  233.   uint32 ays;
  234.  
  235.   ays = 0x41595321;
  236.  
  237.   do {
  238.     uint16 ax, bx;
  239.     int8 s;
  240.  
  241.     s = ays;
  242.  
  243.     if( ays & 0x100 )
  244.     {
  245.       s = 0x80;
  246.  
  247.       if( (LONG)(ays & 0xffff) >= 0 )
  248.         s = 0x7f;
  249.     }
  250.  
  251.     *buf++ = s;
  252.     len--;
  253.  
  254.     ays = (ays >> 5) | (ays << 27);
  255.     ays = (ays & 0xffffff00) | ((ays & 0xff) ^ 0x9a);
  256.     bx  = ays;
  257.     ays = (ays << 2) | (ays >> 30);
  258.     ax  = ays;
  259.     bx  += ax;
  260.     ax  ^= bx;
  261.     ays  = (ays & 0xffff0000) | ax;
  262.     ays  = (ays >> 3) | (ays << 29);
  263.   } while( len );
  264. }
  265.  
  266. void hvl_reset_some_stuff( struct hvl_tune *ht )
  267. {
  268.   uint32 i;
  269.  
  270.   for( i=0; i<MAX_CHANNELS; i++ )
  271.   {
  272.     ht->ht_Voices[i].vc_SamplePos=ht->ht_Voices[i].vc_Delta=ht->ht_Voices[i].vc_Track=ht->ht_Voices[i].vc_Transpose=ht->ht_Voices[i].vc_NextTrack = ht->ht_Voices[i].vc_NextTranspose = 0;
  273.     ht->ht_Voices[i].vc_ADSRVolume=ht->ht_Voices[i].vc_InstrPeriod=ht->ht_Voices[i].vc_TrackPeriod=ht->ht_Voices[i].vc_VibratoPeriod=ht->ht_Voices[i].vc_NoteMaxVolume=ht->ht_Voices[i].vc_PerfSubVolume=ht->ht_Voices[i].vc_TrackMasterVolume=0;
  274.     ht->ht_Voices[i].vc_NewWaveform=ht->ht_Voices[i].vc_Waveform=ht->ht_Voices[i].vc_PlantSquare=ht->ht_Voices[i].vc_PlantPeriod=ht->ht_Voices[i].vc_IgnoreSquare=0;
  275.     ht->ht_Voices[i].vc_TrackOn=ht->ht_Voices[i].vc_FixedNote=ht->ht_Voices[i].vc_VolumeSlideUp=ht->ht_Voices[i].vc_VolumeSlideDown=ht->ht_Voices[i].vc_HardCut=ht->ht_Voices[i].vc_HardCutRelease=ht->ht_Voices[i].vc_HardCutReleaseF=0;
  276.     ht->ht_Voices[i].vc_PeriodSlideSpeed=ht->ht_Voices[i].vc_PeriodSlidePeriod=ht->ht_Voices[i].vc_PeriodSlideLimit=ht->ht_Voices[i].vc_PeriodSlideOn=ht->ht_Voices[i].vc_PeriodSlideWithLimit=0;
  277.     ht->ht_Voices[i].vc_PeriodPerfSlideSpeed=ht->ht_Voices[i].vc_PeriodPerfSlidePeriod=ht->ht_Voices[i].vc_PeriodPerfSlideOn=ht->ht_Voices[i].vc_VibratoDelay=ht->ht_Voices[i].vc_VibratoCurrent=ht->ht_Voices[i].vc_VibratoDepth=ht->ht_Voices[i].vc_VibratoSpeed=0;
  278.     ht->ht_Voices[i].vc_SquareOn=ht->ht_Voices[i].vc_SquareInit=ht->ht_Voices[i].vc_SquareLowerLimit=ht->ht_Voices[i].vc_SquareUpperLimit=ht->ht_Voices[i].vc_SquarePos=ht->ht_Voices[i].vc_SquareSign=ht->ht_Voices[i].vc_SquareSlidingIn=ht->ht_Voices[i].vc_SquareReverse=0;
  279.     ht->ht_Voices[i].vc_FilterOn=ht->ht_Voices[i].vc_FilterInit=ht->ht_Voices[i].vc_FilterLowerLimit=ht->ht_Voices[i].vc_FilterUpperLimit=ht->ht_Voices[i].vc_FilterPos=ht->ht_Voices[i].vc_FilterSign=ht->ht_Voices[i].vc_FilterSpeed=ht->ht_Voices[i].vc_FilterSlidingIn=ht->ht_Voices[i].vc_IgnoreFilter=0;
  280.     ht->ht_Voices[i].vc_PerfCurrent=ht->ht_Voices[i].vc_PerfSpeed=ht->ht_Voices[i].vc_WaveLength=ht->ht_Voices[i].vc_NoteDelayOn=ht->ht_Voices[i].vc_NoteCutOn=0;
  281.     ht->ht_Voices[i].vc_AudioPeriod=ht->ht_Voices[i].vc_AudioVolume=ht->ht_Voices[i].vc_VoiceVolume=ht->ht_Voices[i].vc_VoicePeriod=ht->ht_Voices[i].vc_VoiceNum=ht->ht_Voices[i].vc_WNRandom=0;
  282.     ht->ht_Voices[i].vc_SquareWait=ht->ht_Voices[i].vc_FilterWait=ht->ht_Voices[i].vc_PerfWait=ht->ht_Voices[i].vc_NoteDelayWait=ht->ht_Voices[i].vc_NoteCutWait=0;
  283.     ht->ht_Voices[i].vc_PerfList=0;
  284.     ht->ht_Voices[i].vc_RingSamplePos=ht->ht_Voices[i].vc_RingDelta=ht->ht_Voices[i].vc_RingPlantPeriod=ht->ht_Voices[i].vc_RingAudioPeriod=ht->ht_Voices[i].vc_RingNewWaveform=ht->ht_Voices[i].vc_RingWaveform=ht->ht_Voices[i].vc_RingFixedPeriod=ht->ht_Voices[i].vc_RingBasePeriod=0;
  285.  
  286.     ht->ht_Voices[i].vc_RingMixSource = NULL;
  287.     ht->ht_Voices[i].vc_RingAudioSource = NULL;
  288.  
  289.     clr_l((ULONG *)&ht->ht_Voices[i].vc_SquareTempBuffer,0x80/4);
  290.     clr_l((ULONG *)&ht->ht_Voices[i].vc_ADSR,sizeof(struct hvl_envelope)/4);
  291.     clr_l((ULONG *)&ht->ht_Voices[i].vc_VoiceBuffer,0x281/4);
  292.     clr_l((ULONG *)&ht->ht_Voices[i].vc_RingVoiceBuffer,0x281/4);
  293.   }
  294.   
  295.   for( i=0; i<MAX_CHANNELS; i++ )
  296.   {
  297.     ht->ht_Voices[i].vc_WNRandom          = 0x280;
  298.     ht->ht_Voices[i].vc_VoiceNum          = i;
  299.     ht->ht_Voices[i].vc_TrackMasterVolume = 0x40;
  300.     ht->ht_Voices[i].vc_TrackOn           = 1;
  301.     ht->ht_Voices[i].vc_MixSource         = ht->ht_Voices[i].vc_VoiceBuffer;
  302.   }
  303. }
  304.  
  305. BOOL hvl_InitSubsong( struct hvl_tune *ht, uint32 nr )
  306. {
  307.   uint32 PosNr, i;
  308.  
  309.   if( nr > ht->ht_SubsongNr )
  310.     return FALSE;
  311.  
  312.   ht->ht_SongNum = nr;
  313.   
  314.   PosNr = 0;
  315.   if( nr ) PosNr = ht->ht_Subsongs[nr-1];
  316.   
  317.   ht->ht_PosNr          = PosNr;
  318.   ht->ht_PosJump        = 0;
  319.   ht->ht_PatternBreak   = 0;
  320.   ht->ht_NoteNr         = 0;
  321.   ht->ht_PosJumpNote    = 0;
  322.   ht->ht_Tempo          = 6;
  323.   ht->ht_StepWaitFrames    = 0;
  324.   ht->ht_GetNewPosition = 1;
  325.   ht->ht_SongEndReached = 0;
  326.   ht->ht_PlayingTime    = 0;
  327.   
  328.   for( i=0; i<MAX_CHANNELS; i+=4 )
  329.   {
  330.     ht->ht_Voices[i+0].vc_Pan          = ht->ht_defpanleft;
  331.     ht->ht_Voices[i+0].vc_PanMultLeft  = panning_left[ht->ht_defpanleft];
  332.     ht->ht_Voices[i+0].vc_PanMultRight = panning_right[ht->ht_defpanleft];
  333.     ht->ht_Voices[i+1].vc_Pan          = ht->ht_defpanright;
  334.     ht->ht_Voices[i+1].vc_PanMultLeft  = panning_left[ht->ht_defpanright];
  335.     ht->ht_Voices[i+1].vc_PanMultRight = panning_right[ht->ht_defpanright];
  336.     ht->ht_Voices[i+2].vc_Pan          = ht->ht_defpanright;
  337.     ht->ht_Voices[i+2].vc_PanMultLeft  = panning_left[ht->ht_defpanright];
  338.     ht->ht_Voices[i+2].vc_PanMultRight = panning_right[ht->ht_defpanright];
  339.     ht->ht_Voices[i+3].vc_Pan          = ht->ht_defpanleft;
  340.     ht->ht_Voices[i+3].vc_PanMultLeft  = panning_left[ht->ht_defpanleft];
  341.     ht->ht_Voices[i+3].vc_PanMultRight = panning_right[ht->ht_defpanleft];
  342.   }
  343.  
  344.   hvl_reset_some_stuff( ht );
  345.   
  346.   return TRUE;
  347. }
  348.  
  349. void hvl_InitReplayer( void )
  350. {
  351.   hvl_GenPanningTables();
  352.   hvl_GenSawtooth( &waves[WO_SAWTOOTH_04], 0x04 );
  353.   hvl_GenSawtooth( &waves[WO_SAWTOOTH_08], 0x08 );
  354.   hvl_GenSawtooth( &waves[WO_SAWTOOTH_10], 0x10 );
  355.   hvl_GenSawtooth( &waves[WO_SAWTOOTH_20], 0x20 );
  356.   hvl_GenSawtooth( &waves[WO_SAWTOOTH_40], 0x40 );
  357.   hvl_GenSawtooth( &waves[WO_SAWTOOTH_80], 0x80 );
  358.   hvl_GenTriangle( &waves[WO_TRIANGLE_04], 0x04 );
  359.   hvl_GenTriangle( &waves[WO_TRIANGLE_08], 0x08 );
  360.   hvl_GenTriangle( &waves[WO_TRIANGLE_10], 0x10 );
  361.   hvl_GenTriangle( &waves[WO_TRIANGLE_20], 0x20 );
  362.   hvl_GenTriangle( &waves[WO_TRIANGLE_40], 0x40 );
  363.   hvl_GenTriangle( &waves[WO_TRIANGLE_80], 0x80 );
  364.   hvl_GenSquare( &waves[WO_SQUARES] );
  365.   hvl_GenWhiteNoise( &waves[WO_WHITENOISE], WHITENOISELEN );
  366.   hvl_GenFilterWaves( &waves[WO_TRIANGLE_04], &waves[WO_LOWPASSES], &waves[WO_HIGHPASSES] );
  367. }
  368.  
  369. struct hvl_tune *hvl_load_ahx( uint8 *buf, uint32 buflen, uint32 defstereo, uint32 freq )
  370. {
  371.   uint8  *bptr;
  372.   TEXT   *nptr;
  373.   uint32  i, j, k, l, posn, insn, ssn, hs, trkn, trkl;
  374.   struct hvl_tune *ht;
  375.   struct  hvl_plsentry *ple;
  376.   int32 defgain[] = { 73, 74, 79, 86, 100 };
  377.   
  378.   posn = ((buf[6]&0x0f)<<8)|buf[7];
  379.   insn = buf[12];
  380.   ssn  = buf[13];
  381.   trkl = buf[10];
  382.   trkn = buf[11];
  383.  
  384.   hs  = sizeof( struct hvl_tune );
  385.   hs += sizeof( struct hvl_position ) * posn;
  386.   hs += sizeof( struct hvl_instrument ) * (insn+1);
  387.   hs += sizeof( uint16 ) * ssn;
  388.  
  389.   // Calculate the size of all instrument PList buffers
  390.   bptr = &buf[14];
  391.   bptr += ssn*2;    // Skip past the subsong list
  392.   bptr += posn*4*2; // Skip past the positions
  393.   bptr += trkn*trkl*3;
  394.   if((buf[6]&0x80)==0) bptr += trkl*3;
  395.   
  396.   // *NOW* we can finally calculate PList space
  397.   for( i=1; i<=insn; i++ )
  398.   {
  399.     hs += bptr[21] * sizeof( struct hvl_plsentry );
  400.     bptr += 22 + bptr[21]*4;
  401.   }
  402.  
  403.   ht = AllocVec( hs, MEMF_ANY );
  404.   if( !ht )
  405.   {
  406.     FreeVec( buf );
  407.     printf( "Out of memory!\n" );
  408.     return NULL;
  409.   }
  410.   
  411.   ht->ht_Frequency       = freq;
  412.   ht->ht_FreqF           = (float64)freq;
  413.   
  414.   ht->ht_Positions   = (struct hvl_position *)(&ht[1]);
  415.   ht->ht_Instruments = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
  416.   ht->ht_Subsongs    = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
  417.   ple                = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
  418.  
  419.   ht->ht_WaveformTab[0]  = &waves[WO_TRIANGLE_04];
  420.   ht->ht_WaveformTab[1]  = &waves[WO_SAWTOOTH_04];
  421.   ht->ht_WaveformTab[3]  = &waves[WO_WHITENOISE];
  422.  
  423.   ht->ht_Channels        = 4;
  424.   ht->ht_PositionNr      = posn;
  425.   ht->ht_Restart         = (buf[8]<<8)|buf[9];
  426.   ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
  427.   ht->ht_TrackLength     = trkl;
  428.   ht->ht_TrackNr         = trkn;
  429.   ht->ht_InstrumentNr    = insn;
  430.   ht->ht_SubsongNr       = ssn;
  431.   ht->ht_defstereo       = defstereo;
  432.   ht->ht_defpanleft      = stereopan_left[ht->ht_defstereo];
  433.   ht->ht_defpanright     = stereopan_right[ht->ht_defstereo];
  434.   ht->ht_mixgain         = (defgain[ht->ht_defstereo]*256)/100;
  435.   
  436.   if( ht->ht_Restart >= ht->ht_PositionNr )
  437.     ht->ht_Restart = ht->ht_PositionNr-1;
  438.  
  439.   // Do some validation  
  440.   if( ( ht->ht_PositionNr > 1000 ) ||
  441.       ( ht->ht_TrackLength > 64 ) ||
  442.       ( ht->ht_InstrumentNr > 64 ) )
  443.   {
  444.     printf( "%d,%d,%d\n", ht->ht_PositionNr,
  445.                           ht->ht_TrackLength,
  446.                           ht->ht_InstrumentNr );
  447.     FreeVec( ht );
  448.     FreeVec( buf );
  449.     printf( "Invalid file.\n" );
  450.     return NULL;
  451.   }
  452.  
  453.   strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
  454.   nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
  455.  
  456.   bptr = &buf[14];
  457.   
  458.   // Subsongs
  459.   for( i=0; i<ht->ht_SubsongNr; i++ )
  460.   {
  461.     ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
  462.     bptr += 2;
  463.   }
  464.   
  465.   // Position list
  466.   for( i=0; i<ht->ht_PositionNr; i++ )
  467.   {
  468.     for( j=0; j<4; j++ )
  469.     {
  470.       ht->ht_Positions[i].pos_Track[j]     = *bptr++;
  471.       ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
  472.     }
  473.   }
  474.   
  475.   // Tracks
  476.   for( i=0; i<=ht->ht_TrackNr; i++ )
  477.   {
  478.     if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
  479.     {
  480.       for( j=0; j<ht->ht_TrackLength; j++ )
  481.       {
  482.         ht->ht_Tracks[i][j].stp_Note       = 0;
  483.         ht->ht_Tracks[i][j].stp_Instrument = 0;
  484.         ht->ht_Tracks[i][j].stp_FX         = 0;
  485.         ht->ht_Tracks[i][j].stp_FXParam    = 0;
  486.         ht->ht_Tracks[i][j].stp_FXb        = 0;
  487.         ht->ht_Tracks[i][j].stp_FXbParam   = 0;
  488.       }
  489.       continue;
  490.     }
  491.     
  492.     for( j=0; j<ht->ht_TrackLength; j++ )
  493.     {
  494.       ht->ht_Tracks[i][j].stp_Note       = (bptr[0]>>2)&0x3f;
  495.       ht->ht_Tracks[i][j].stp_Instrument = ((bptr[0]&0x3)<<4) | (bptr[1]>>4);
  496.       ht->ht_Tracks[i][j].stp_FX         = bptr[1]&0xf;
  497.       ht->ht_Tracks[i][j].stp_FXParam    = bptr[2];
  498.       ht->ht_Tracks[i][j].stp_FXb        = 0;
  499.       ht->ht_Tracks[i][j].stp_FXbParam   = 0;
  500.       bptr += 3;
  501.     }
  502.   }
  503.   
  504.   // Instruments
  505.   for( i=1; i<=ht->ht_InstrumentNr; i++ )
  506.   {
  507.     strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
  508.     nptr += strlen( nptr )+1;
  509.     
  510.     ht->ht_Instruments[i].ins_Volume      = bptr[0];
  511.     ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
  512.     ht->ht_Instruments[i].ins_WaveLength  = bptr[1]&0x07;
  513.  
  514.     ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
  515.     ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
  516.     ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
  517.     ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
  518.     ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
  519.     ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
  520.     ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
  521.     
  522.     ht->ht_Instruments[i].ins_FilterLowerLimit     = bptr[12]&0x7f;
  523.     ht->ht_Instruments[i].ins_VibratoDelay         = bptr[13];
  524.     ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
  525.     ht->ht_Instruments[i].ins_HardCutRelease       = bptr[14]&0x80?1:0;
  526.     ht->ht_Instruments[i].ins_VibratoDepth         = bptr[14]&0x0f;
  527.     ht->ht_Instruments[i].ins_VibratoSpeed         = bptr[15];
  528.     ht->ht_Instruments[i].ins_SquareLowerLimit     = bptr[16];
  529.     ht->ht_Instruments[i].ins_SquareUpperLimit     = bptr[17];
  530.     ht->ht_Instruments[i].ins_SquareSpeed          = bptr[18];
  531.     ht->ht_Instruments[i].ins_FilterUpperLimit     = bptr[19]&0x3f;
  532.     ht->ht_Instruments[i].ins_PList.pls_Speed      = bptr[20];
  533.     ht->ht_Instruments[i].ins_PList.pls_Length     = bptr[21];
  534.     
  535.     ht->ht_Instruments[i].ins_PList.pls_Entries    = ple;
  536.     ple += bptr[21];
  537.     
  538.     bptr += 22;
  539.     for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
  540.     {
  541.       k = (bptr[0]>>5)&7;
  542.       if( k == 6 ) k = 12;
  543.       if( k == 7 ) k = 15;
  544.       l = (bptr[0]>>2)&7;
  545.       if( l == 6 ) l = 12;
  546.       if( l == 7 ) l = 15;
  547.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1]      = k;
  548.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0]      = l;
  549.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform   = ((bptr[0]<<1)&6) | (bptr[1]>>7);
  550.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed      = (bptr[1]>>6)&1;
  551.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note       = bptr[1]&0x3f;
  552.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[2];
  553.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[3];
  554.       bptr += 4;
  555.     }
  556.   }
  557.   
  558.   hvl_InitSubsong( ht, 0 );
  559.   FreeVec( buf );
  560.   return ht;
  561. }
  562.  
  563. struct hvl_tune *hvl_LoadTune( TEXT *name, uint32 freq, uint32 defstereo )
  564. {
  565.   struct hvl_tune *ht;
  566.   uint8  *buf, *bptr;
  567.   TEXT   *nptr;
  568.   uint32  buflen, i, j, posn, insn, ssn, chnn, hs, trkl, trkn;
  569.   BPTR    lock, fh;
  570.   struct  FileInfoBlock *fib;
  571.   struct  hvl_plsentry *ple;
  572.  
  573.   fib = AllocDosObjectTags( DOS_FIB, TAG_DONE );
  574.   if( !fib )
  575.   {
  576.     printf( "Out of memory\n" );
  577.     return NULL;
  578.   }
  579.   
  580.   lock = Lock( name, ACCESS_READ );
  581.   if( !lock )
  582.   {
  583.     FreeDosObject( DOS_FIB, fib );
  584.     printf( "Unable to find '%s'\n", name );
  585.     return NULL;
  586.   }
  587.   
  588.   Examine( lock, fib );
  589.   if( !FIB_IS_FILE( fib ) )
  590.   {
  591.     UnLock( lock );
  592.     FreeDosObject( DOS_FIB, fib );
  593.     printf( "Bad file!\n" );
  594.     return NULL;
  595.   }
  596.   
  597.   buflen = fib->fib_Size;
  598.   buf = AllocVec( buflen, MEMF_ANY );
  599.   if( !buf )
  600.   {
  601.     UnLock( lock );
  602.     FreeDosObject( DOS_FIB, fib );
  603.     printf( "Out of memory!\n" );
  604.     return NULL;
  605.   }
  606.   
  607.   fh = OpenFromLock( lock );
  608.   if( !fh )
  609.   {
  610.     FreeVec( buf );
  611.     UnLock( lock );
  612.     FreeDosObject( DOS_FIB, fib );
  613.     printf( "Can't open file\n" );
  614.     return NULL;
  615.   }
  616.  
  617.   if( Read( fh, buf, buflen ) != buflen )
  618.   {
  619.     FreeVec( buf );
  620.     Close( fh );
  621.     FreeDosObject( DOS_FIB, fib );
  622.     printf( "Unable to read from file!\n" );
  623.     return NULL;
  624.   }
  625.   Close( fh );
  626.   FreeDosObject( DOS_FIB, fib );
  627.   
  628.   if( ( buf[0] == 'T' ) &&
  629.       ( buf[1] == 'H' ) &&
  630.       ( buf[2] == 'X' ) &&
  631.       ( buf[3] < 3 ) )
  632.     return hvl_load_ahx( buf, buflen, defstereo, freq );
  633.  
  634.   if( ( buf[0] != 'H' ) ||
  635.       ( buf[1] != 'V' ) ||
  636.       ( buf[2] != 'L' ) ||
  637.       ( buf[3] > 0 ) )
  638.   {
  639.     FreeVec( buf );
  640.     printf( "Invalid file.\n" );
  641.     return NULL;
  642.   }
  643.   
  644.   posn = ((buf[6]&0x0f)<<8)|buf[7];
  645.   insn = buf[12];
  646.   ssn  = buf[13];
  647.   chnn = (buf[8]>>2)+4;
  648.   trkl = buf[10];
  649.   trkn = buf[11];
  650.  
  651.   hs  = sizeof( struct hvl_tune );
  652.   hs += sizeof( struct hvl_position ) * posn;
  653.   hs += sizeof( struct hvl_instrument ) * (insn+1);
  654.   hs += sizeof( uint16 ) * ssn;
  655.  
  656.   // Calculate the size of all instrument PList buffers
  657.   bptr = &buf[16];
  658.   bptr += ssn*2;       // Skip past the subsong list
  659.   bptr += posn*chnn*2; // Skip past the positions
  660.   
  661.   // Skip past the tracks
  662.   i=(buf[6]&0x80)?1:0;
  663.   for( i=0; i<trkn; i++ )
  664.     for( j=0; j<trkl; j++ )
  665.     {
  666.       if( bptr[0] == 0x3f )
  667.       {
  668.         bptr++;
  669.         continue;
  670.       }
  671.       bptr += 5;
  672.     }
  673.   
  674.   // *NOW* we can finally calculate PList space
  675.   for( i=1; i<=insn; i++ )
  676.   {
  677.     hs += bptr[21] * sizeof( struct hvl_plsentry );
  678.     bptr += 22 + bptr[21]*5;
  679.   }
  680.   
  681.   ht = AllocVec( hs, MEMF_ANY );    
  682.   if( !ht )
  683.   {
  684.     FreeVec( buf );
  685.     printf( "Out of memory!\n" );
  686.     return NULL;
  687.   }
  688.   
  689.   ht->ht_Frequency       = freq;
  690.   ht->ht_FreqF           = (float64)freq;
  691.   
  692.   ht->ht_Positions       = (struct hvl_position *)(&ht[1]);
  693.   ht->ht_Instruments     = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
  694.   ht->ht_Subsongs        = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
  695.   ple                    = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
  696.  
  697.   ht->ht_WaveformTab[0]  = &waves[WO_TRIANGLE_04];
  698.   ht->ht_WaveformTab[1]  = &waves[WO_SAWTOOTH_04];
  699.   ht->ht_WaveformTab[3]  = &waves[WO_WHITENOISE];
  700.  
  701.   ht->ht_PositionNr      = posn;
  702.   ht->ht_Channels        = (buf[8]>>2)+4;
  703.   ht->ht_Restart         = ((buf[8]&3)<<8)|buf[9];
  704.   ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
  705.   ht->ht_TrackLength     = buf[10];
  706.   ht->ht_TrackNr         = buf[11];
  707.   ht->ht_InstrumentNr    = insn;
  708.   ht->ht_SubsongNr       = ssn;
  709.   ht->ht_mixgain         = (buf[14]<<8)/100;
  710.   ht->ht_defstereo       = buf[15];
  711.   ht->ht_defpanleft      = stereopan_left[ht->ht_defstereo];
  712.   ht->ht_defpanright     = stereopan_right[ht->ht_defstereo];
  713.   
  714.   if( ht->ht_Restart >= ht->ht_PositionNr )
  715.     ht->ht_Restart = ht->ht_PositionNr-1;
  716.  
  717.   // Do some validation  
  718.   if( ( ht->ht_PositionNr > 1000 ) ||
  719.       ( ht->ht_TrackLength > 64 ) ||
  720.       ( ht->ht_InstrumentNr > 64 ) )
  721.   {
  722.     printf( "%d,%d,%d\n", ht->ht_PositionNr,
  723.                           ht->ht_TrackLength,
  724.                           ht->ht_InstrumentNr );
  725.     FreeVec( ht );
  726.     FreeVec( buf );
  727.     printf( "Invalid file.\n" );
  728.     return NULL;
  729.   }
  730.  
  731.   strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
  732.   nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
  733.  
  734.   bptr = &buf[16];
  735.   
  736.   // Subsongs
  737.   for( i=0; i<ht->ht_SubsongNr; i++ )
  738.   {
  739.     ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
  740.     bptr += 2;
  741.   }
  742.   
  743.   // Position list
  744.   for( i=0; i<ht->ht_PositionNr; i++ )
  745.   {
  746.     for( j=0; j<ht->ht_Channels; j++ )
  747.     {
  748.       ht->ht_Positions[i].pos_Track[j]     = *bptr++;
  749.       ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
  750.     }
  751.   }
  752.   
  753.   // Tracks
  754.   for( i=0; i<=ht->ht_TrackNr; i++ )
  755.   {
  756.     if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
  757.     {
  758.       for( j=0; j<ht->ht_TrackLength; j++ )
  759.       {
  760.         ht->ht_Tracks[i][j].stp_Note       = 0;
  761.         ht->ht_Tracks[i][j].stp_Instrument = 0;
  762.         ht->ht_Tracks[i][j].stp_FX         = 0;
  763.         ht->ht_Tracks[i][j].stp_FXParam    = 0;
  764.         ht->ht_Tracks[i][j].stp_FXb        = 0;
  765.         ht->ht_Tracks[i][j].stp_FXbParam   = 0;
  766.       }
  767.       continue;
  768.     }
  769.     
  770.     for( j=0; j<ht->ht_TrackLength; j++ )
  771.     {
  772.       if( bptr[0] == 0x3f )
  773.       {
  774.         ht->ht_Tracks[i][j].stp_Note       = 0;
  775.         ht->ht_Tracks[i][j].stp_Instrument = 0;
  776.         ht->ht_Tracks[i][j].stp_FX         = 0;
  777.         ht->ht_Tracks[i][j].stp_FXParam    = 0;
  778.         ht->ht_Tracks[i][j].stp_FXb        = 0;
  779.         ht->ht_Tracks[i][j].stp_FXbParam   = 0;
  780.         bptr++;
  781.         continue;
  782.       }
  783.       
  784.       ht->ht_Tracks[i][j].stp_Note       = bptr[0];
  785.       ht->ht_Tracks[i][j].stp_Instrument = bptr[1];
  786.       ht->ht_Tracks[i][j].stp_FX         = bptr[2]>>4;
  787.       ht->ht_Tracks[i][j].stp_FXParam    = bptr[3];
  788.       ht->ht_Tracks[i][j].stp_FXb        = bptr[2]&0xf;
  789.       ht->ht_Tracks[i][j].stp_FXbParam   = bptr[4];
  790.       bptr += 5;
  791.     }
  792.   }
  793.   
  794.   
  795.   // Instruments
  796.   for( i=1; i<=ht->ht_InstrumentNr; i++ )
  797.   {
  798.     strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
  799.     nptr += strlen( nptr )+1;
  800.     
  801.     ht->ht_Instruments[i].ins_Volume      = bptr[0];
  802.     ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
  803.     ht->ht_Instruments[i].ins_WaveLength  = bptr[1]&0x07;
  804.  
  805.     ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
  806.     ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
  807.     ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
  808.     ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
  809.     ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
  810.     ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
  811.     ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
  812.     
  813.     ht->ht_Instruments[i].ins_FilterLowerLimit     = bptr[12]&0x7f;
  814.     ht->ht_Instruments[i].ins_VibratoDelay         = bptr[13];
  815.     ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
  816.     ht->ht_Instruments[i].ins_HardCutRelease       = bptr[14]&0x80?1:0;
  817.     ht->ht_Instruments[i].ins_VibratoDepth         = bptr[14]&0x0f;
  818.     ht->ht_Instruments[i].ins_VibratoSpeed         = bptr[15];
  819.     ht->ht_Instruments[i].ins_SquareLowerLimit     = bptr[16];
  820.     ht->ht_Instruments[i].ins_SquareUpperLimit     = bptr[17];
  821.     ht->ht_Instruments[i].ins_SquareSpeed          = bptr[18];
  822.     ht->ht_Instruments[i].ins_FilterUpperLimit     = bptr[19]&0x3f;
  823.     ht->ht_Instruments[i].ins_PList.pls_Speed      = bptr[20];
  824.     ht->ht_Instruments[i].ins_PList.pls_Length     = bptr[21];
  825.     
  826.     ht->ht_Instruments[i].ins_PList.pls_Entries    = ple;
  827.     ple += bptr[21];
  828.     
  829.     bptr += 22;
  830.     for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
  831.     {
  832.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0] = bptr[0]&0xf;
  833.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1] = (bptr[1]>>3)&0xf;
  834.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform = bptr[1]&7;
  835.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed = (bptr[2]>>6)&1;
  836.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note  = bptr[2]&0x3f;
  837.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[3];
  838.       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[4];
  839.       bptr += 5;
  840.     }
  841.   }
  842.   
  843.   hvl_InitSubsong( ht, 0 );
  844.   FreeVec( buf );
  845.   return ht;
  846. }
  847.  
  848. void hvl_FreeTune( struct hvl_tune *ht )
  849. {
  850.   if( !ht ) return;
  851.   FreeVec( ht );
  852. }
  853.  
  854. void hvl_process_stepfx_1( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
  855. {
  856.   switch( FX )
  857.   {
  858.     case 0x0:  // Position Jump HI
  859.       if( ((FXParam&0x0f) > 0) && ((FXParam&0x0f) <= 9) )
  860.         ht->ht_PosJump = FXParam & 0xf;
  861.       break;
  862.  
  863.     case 0x5:  // Volume Slide + Tone Portamento
  864.     case 0xa:  // Volume Slide
  865.       voice->vc_VolumeSlideDown = FXParam & 0x0f;
  866.       voice->vc_VolumeSlideUp   = FXParam >> 4;
  867.       break;
  868.     
  869.     case 0x7:  // Panning
  870.       if( FXParam > 127 )
  871.         FXParam -= 256;
  872.       voice->vc_Pan          = (FXParam+128);
  873.       voice->vc_PanMultLeft  = panning_left[voice->vc_Pan];
  874.       voice->vc_PanMultRight = panning_right[voice->vc_Pan];
  875.       break;
  876.     
  877.     case 0xb: // Position jump
  878.       ht->ht_PosJump      = ht->ht_PosJump*100 + (FXParam & 0x0f) + (FXParam >> 4)*10;
  879.       ht->ht_PatternBreak = 1;
  880.       if( ht->ht_PosJump < ht->ht_PosNr )
  881.         ht->ht_SongEndReached = 1;
  882.       break;
  883.     
  884.     case 0xd: // Pattern break
  885.       ht->ht_PosJump      = ht->ht_PosNr+1;
  886.       ht->ht_PosJumpNote  = (FXParam & 0x0f) + (FXParam>>4)*10;
  887.       ht->ht_PatternBreak = 1;
  888.       if( ht->ht_PosJumpNote >  ht->ht_TrackLength )
  889.         ht->ht_PosJumpNote = 0;
  890.       break;
  891.     
  892.     case 0xe: // Extended commands
  893.       switch( FXParam >> 4 )
  894.       {
  895.         case 0xc: // Note cut
  896.           if( (FXParam & 0x0f) < ht->ht_Tempo )
  897.           {
  898.             voice->vc_NoteCutWait = FXParam & 0x0f;
  899.             if( voice->vc_NoteCutWait )
  900.             {
  901.               voice->vc_NoteCutOn      = 1;
  902.               voice->vc_HardCutRelease = 0;
  903.             }
  904.           }
  905.           break;
  906.         case 0xd: // Note delay
  907.           if( voice->vc_NoteDelayOn )
  908.           {
  909.             voice->vc_NoteDelayOn = 0;
  910.           } else {
  911.             if( (FXParam & 0x0f) < ht->ht_Tempo )
  912.             {
  913.               voice->vc_NoteDelayWait = FXParam & 0x0f;
  914.               if( voice->vc_NoteDelayWait )
  915.               {
  916.                 voice->vc_NoteDelayOn = 1;
  917.                 return;
  918.               }
  919.             }
  920.           }
  921.           break;
  922.       }
  923.       break;
  924.     
  925.     case 0xf: // Speed
  926.       ht->ht_Tempo = FXParam;
  927.       if( FXParam == 0 )
  928.         ht->ht_SongEndReached = 1;
  929.       break;
  930.   }  
  931. }
  932.  
  933. void hvl_process_stepfx_2( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam, int32 *Note )
  934. {
  935.   switch( FX )
  936.   {
  937.     case 0x9: // Set squarewave offset
  938.       voice->vc_SquarePos    = FXParam >> (5 - voice->vc_WaveLength);
  939.       voice->vc_PlantSquare  = 1;
  940.       voice->vc_IgnoreSquare = 1;
  941.       break;
  942.     
  943.     case 0x5: // Tone portamento + volume slide
  944.     case 0x3: // Tone portamento
  945.       if( FXParam != 0 ) voice->vc_PeriodSlideSpeed = FXParam;
  946.       
  947.       if( *Note )
  948.       {
  949.         int32 new, diff;
  950.  
  951.         new   = period_tab[*Note];
  952.         diff  = period_tab[voice->vc_TrackPeriod];
  953.         diff -= new;
  954.         new   = diff + voice->vc_PeriodSlidePeriod;
  955.         
  956.         if( new )
  957.           voice->vc_PeriodSlideLimit = -diff;
  958.       }
  959.       voice->vc_PeriodSlideOn        = 1;
  960.       voice->vc_PeriodSlideWithLimit = 1;
  961.       *Note = 0;
  962.       break;      
  963.   } 
  964. }
  965.  
  966. void hvl_process_stepfx_3( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
  967. {
  968.   int32 i;
  969.   
  970.   switch( FX )
  971.   {
  972.     case 0x01: // Portamento up (period slide down)
  973.       voice->vc_PeriodSlideSpeed     = -FXParam;
  974.       voice->vc_PeriodSlideOn        = 1;
  975.       voice->vc_PeriodSlideWithLimit = 0;
  976.       break;
  977.     case 0x02: // Portamento down
  978.       voice->vc_PeriodSlideSpeed     = FXParam;
  979.       voice->vc_PeriodSlideOn        = 1;
  980.       voice->vc_PeriodSlideWithLimit = 0;
  981.       break;
  982.     case 0x04: // Filter override
  983.       if( FXParam < 0x40 )
  984.       {
  985.         voice->vc_IgnoreFilter = FXParam;
  986.         break;
  987.       }
  988.       if( FXParam > 0x7f ) break;
  989.       voice->vc_FilterPos = FXParam - 0x40;
  990.       break;
  991.     case 0x0c: // Volume
  992.       FXParam &= 0xff;
  993.       if( FXParam <= 0x40 )
  994.       {
  995.         voice->vc_NoteMaxVolume = FXParam;
  996.         break;
  997.       }
  998.       
  999.       FXParam -= 0x50;
  1000.       if( FXParam <= 0x40 )
  1001.       {
  1002.         for( i=0; i<ht->ht_Channels; i++ )
  1003.           ht->ht_Voices[i].vc_TrackMasterVolume = FXParam;
  1004.         break;
  1005.       }
  1006.       
  1007.       FXParam -= 0xa0-0x50;
  1008.       if( FXParam <= 0x40 )
  1009.         voice->vc_TrackMasterVolume = FXParam;
  1010.       break;
  1011.  
  1012.     case 0xe: // Extended commands;
  1013.       switch( FXParam >> 4 )
  1014.       {
  1015.         case 0x1: // Fineslide up
  1016.           voice->vc_PeriodSlidePeriod = -(FXParam & 0x0f);
  1017.           voice->vc_PlantPeriod = 1;
  1018.           break;
  1019.         
  1020.         case 0x2: // Fineslide down
  1021.           voice->vc_PeriodSlidePeriod = (FXParam & 0x0f);
  1022.           voice->vc_PlantPeriod = 1;
  1023.           break;
  1024.         
  1025.         case 0x4: // Vibrato control
  1026.           voice->vc_VibratoDepth = FXParam & 0x0f;
  1027.           break;
  1028.         
  1029.         case 0x0a: // Fine volume up
  1030.           voice->vc_NoteMaxVolume += FXParam & 0x0f;
  1031.           
  1032.           if( voice->vc_NoteMaxVolume > 0x40 )
  1033.             voice->vc_NoteMaxVolume = 0x40;
  1034.           break;
  1035.         
  1036.         case 0x0b: // Fine volume down
  1037.           voice->vc_NoteMaxVolume -= FXParam & 0x0f;
  1038.           
  1039.           if( voice->vc_NoteMaxVolume < 0 )
  1040.             voice->vc_NoteMaxVolume = 0;
  1041.           break;
  1042.       } 
  1043.       break;
  1044.   }
  1045. }
  1046.  
  1047. void hvl_process_step( struct hvl_tune *ht, struct hvl_voice *voice )
  1048. {
  1049.   int32  Note, Instr;
  1050.   struct hvl_step *Step;
  1051.   
  1052.   if( voice->vc_TrackOn == 0 )
  1053.     return;
  1054.   
  1055.   voice->vc_VolumeSlideUp = voice->vc_VolumeSlideDown = 0;
  1056.   
  1057.   Step = &ht->ht_Tracks[ht->ht_Positions[ht->ht_PosNr].pos_Track[voice->vc_VoiceNum]][ht->ht_NoteNr];
  1058.   
  1059.   Note    = Step->stp_Note;
  1060.   Instr   = Step->stp_Instrument;
  1061.  
  1062.   hvl_process_stepfx_1( ht, voice, Step->stp_FX&0xf,  Step->stp_FXParam );  
  1063.   hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
  1064.   
  1065.   if( Instr )
  1066.   {
  1067.     struct hvl_instrument *Ins;
  1068.     int16  SquareLower, SquareUpper, d6, d3, d4;
  1069.     
  1070.     voice->vc_PeriodSlideSpeed = voice->vc_PeriodSlidePeriod = voice->vc_PeriodSlideLimit = 0;
  1071.  
  1072.     voice->vc_PerfSubVolume    = 0x40;
  1073.     voice->vc_ADSRVolume       = 0;
  1074.     voice->vc_Instrument       = Ins = &ht->ht_Instruments[Instr];
  1075.     voice->vc_SamplePos        = 0;
  1076.     
  1077.     voice->vc_ADSR.aFrames     = Ins->ins_Envelope.aFrames;
  1078.     voice->vc_ADSR.aVolume     = Ins->ins_Envelope.aVolume*256/voice->vc_ADSR.aFrames;
  1079.     voice->vc_ADSR.dFrames     = Ins->ins_Envelope.dFrames;
  1080.     voice->vc_ADSR.dVolume     = (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume)*256/voice->vc_ADSR.dFrames;
  1081.     voice->vc_ADSR.sFrames     = Ins->ins_Envelope.sFrames;
  1082.     voice->vc_ADSR.rFrames     = Ins->ins_Envelope.rFrames;
  1083.     voice->vc_ADSR.rVolume     = (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume)*256/voice->vc_ADSR.rFrames;
  1084.     
  1085.     voice->vc_WaveLength       = Ins->ins_WaveLength;
  1086.     voice->vc_NoteMaxVolume    = Ins->ins_Volume;
  1087.     
  1088.     voice->vc_VibratoCurrent   = 0;
  1089.     voice->vc_VibratoDelay     = Ins->ins_VibratoDelay;
  1090.     voice->vc_VibratoDepth     = Ins->ins_VibratoDepth;
  1091.     voice->vc_VibratoSpeed     = Ins->ins_VibratoSpeed;
  1092.     voice->vc_VibratoPeriod    = 0;
  1093.     
  1094.     voice->vc_HardCutRelease   = Ins->ins_HardCutRelease;
  1095.     voice->vc_HardCut          = Ins->ins_HardCutReleaseFrames;
  1096.     
  1097.     voice->vc_IgnoreSquare = voice->vc_SquareSlidingIn = 0;
  1098.     voice->vc_SquareWait   = voice->vc_SquareOn        = 0;
  1099.     
  1100.     SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength);
  1101.     SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength);
  1102.     
  1103.     if( SquareUpper < SquareLower )
  1104.     {
  1105.       int16 t = SquareUpper;
  1106.       SquareUpper = SquareLower;
  1107.       SquareLower = t;
  1108.     }
  1109.     
  1110.     voice->vc_SquareUpperLimit = SquareUpper;
  1111.     voice->vc_SquareLowerLimit = SquareLower;
  1112.     
  1113.     voice->vc_IgnoreFilter    = voice->vc_FilterWait = voice->vc_FilterOn = 0;
  1114.     voice->vc_FilterSlidingIn = 0;
  1115.  
  1116.     d6 = Ins->ins_FilterSpeed;
  1117.     d3 = Ins->ins_FilterLowerLimit;
  1118.     d4 = Ins->ins_FilterUpperLimit;
  1119.     
  1120.     if( d3 & 0x80 ) d6 |= 0x20;
  1121.     if( d4 & 0x80 ) d6 |= 0x40;
  1122.     
  1123.     voice->vc_FilterSpeed = d6;
  1124.     d3 &= ~0x80;
  1125.     d4 &= ~0x80;
  1126.     
  1127.     if( d3 > d4 )
  1128.     {
  1129.       int16 t = d3;
  1130.       d3 = d4;
  1131.       d4 = t;
  1132.     }
  1133.     
  1134.     voice->vc_FilterUpperLimit = d4;
  1135.     voice->vc_FilterLowerLimit = d3;
  1136.     voice->vc_FilterPos        = 32;
  1137.     
  1138.     voice->vc_PerfWait  = voice->vc_PerfCurrent = 0;
  1139.     voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed;
  1140.     voice->vc_PerfList  = &voice->vc_Instrument->ins_PList;
  1141.     
  1142.     voice->vc_RingMixSource   = NULL;   // No ring modulation
  1143.     voice->vc_RingSamplePos   = 0;
  1144.     voice->vc_RingPlantPeriod = 0;
  1145.     voice->vc_RingNewWaveform = 0;
  1146.   }
  1147.   
  1148.   voice->vc_PeriodSlideOn = 0;
  1149.   
  1150.   hvl_process_stepfx_2( ht, voice, Step->stp_FX&0xf,  Step->stp_FXParam,  &Note );  
  1151.   hvl_process_stepfx_2( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note );
  1152.  
  1153.   if( Note )
  1154.   {
  1155.     voice->vc_TrackPeriod = Note;
  1156.     voice->vc_PlantPeriod = 1;
  1157.   }
  1158.   
  1159.   hvl_process_stepfx_3( ht, voice, Step->stp_FX&0xf,  Step->stp_FXParam );  
  1160.   hvl_process_stepfx_3( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );  
  1161. }
  1162.  
  1163. void hvl_plist_command_parse( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
  1164. {
  1165.   switch( FX )
  1166.   {
  1167.     case 0:
  1168.       if( FXParam != 0 )
  1169.       {
  1170.         if( voice->vc_IgnoreFilter )
  1171.         {
  1172.           voice->vc_FilterPos    = voice->vc_IgnoreFilter;
  1173.           voice->vc_IgnoreFilter = 0;
  1174.         } else {
  1175.           voice->vc_FilterPos    = FXParam;
  1176.         }
  1177.         voice->vc_NewWaveform = 1;
  1178.       }
  1179.       break;
  1180.  
  1181.     case 1:
  1182.       voice->vc_PeriodPerfSlideSpeed = FXParam;
  1183.       voice->vc_PeriodPerfSlideOn    = 1;
  1184.       break;
  1185.  
  1186.     case 2:
  1187.       voice->vc_PeriodPerfSlideSpeed = -FXParam;
  1188.       voice->vc_PeriodPerfSlideOn    = 1;
  1189.       break;
  1190.     
  1191.     case 3:
  1192.       if( voice->vc_IgnoreSquare == 0 )
  1193.         voice->vc_SquarePos = FXParam >> (5-voice->vc_WaveLength);
  1194.       else
  1195.         voice->vc_IgnoreSquare = 0;
  1196.       break;
  1197.     
  1198.     case 4:
  1199.       if( FXParam == 0 )
  1200.       {
  1201.         voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
  1202.         voice->vc_SquareSign = 1;
  1203.       } else {
  1204.  
  1205.         if( FXParam & 0x0f )
  1206.         {
  1207.           voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
  1208.           voice->vc_SquareSign = 1;
  1209.           if(( FXParam & 0x0f ) == 0x0f )
  1210.             voice->vc_SquareSign = -1;
  1211.         }
  1212.         
  1213.         if( FXParam & 0xf0 )
  1214.         {
  1215.           voice->vc_FilterInit = (voice->vc_FilterOn ^= 1);
  1216.           voice->vc_FilterSign = 1;
  1217.           if(( FXParam & 0xf0 ) == 0xf0 )
  1218.             voice->vc_FilterSign = -1;
  1219.         }
  1220.       }
  1221.       break;
  1222.     
  1223.     case 5:
  1224.       voice->vc_PerfCurrent = FXParam;
  1225.       break;
  1226.     
  1227.     case 7:
  1228.       // Ring modulate with triangle
  1229.       if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
  1230.       {
  1231.         voice->vc_RingBasePeriod = FXParam;
  1232.         voice->vc_RingFixedPeriod = 1;
  1233.       } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
  1234.         voice->vc_RingBasePeriod = FXParam-0x80;
  1235.         voice->vc_RingFixedPeriod = 0;
  1236.       } else {
  1237.         voice->vc_RingBasePeriod = 0;
  1238.         voice->vc_RingFixedPeriod = 0;
  1239.         voice->vc_RingNewWaveform = 0;
  1240.         voice->vc_RingAudioSource = NULL; // turn it off
  1241.         voice->vc_RingMixSource   = NULL;
  1242.         break;
  1243.       }    
  1244.       voice->vc_RingWaveform    = 0;
  1245.       voice->vc_RingNewWaveform = 1;
  1246.       voice->vc_RingPlantPeriod = 1;
  1247.       break;
  1248.     
  1249.     case 8:  // Ring modulate with sawtooth
  1250.       if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
  1251.       {
  1252.         voice->vc_RingBasePeriod = FXParam;
  1253.         voice->vc_RingFixedPeriod = 1;
  1254.       } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
  1255.         voice->vc_RingBasePeriod = FXParam-0x80;
  1256.         voice->vc_RingFixedPeriod = 0;
  1257.       } else {
  1258.         voice->vc_RingBasePeriod = 0;
  1259.         voice->vc_RingFixedPeriod = 0;
  1260.         voice->vc_RingNewWaveform = 0;
  1261.         voice->vc_RingAudioSource = NULL;
  1262.         voice->vc_RingMixSource   = NULL;
  1263.         break;
  1264.       }
  1265.  
  1266.       voice->vc_RingWaveform    = 1;
  1267.       voice->vc_RingNewWaveform = 1;
  1268.       voice->vc_RingPlantPeriod = 1;
  1269.       break;
  1270.     
  1271.     case 12:
  1272.       if( FXParam <= 0x40 )
  1273.       {
  1274.         voice->vc_NoteMaxVolume = FXParam;
  1275.         break;
  1276.       }
  1277.       
  1278.       if( (FXParam -= 0x50) < 0 ) break;
  1279.  
  1280.       if( FXParam <= 0x40 )
  1281.       {
  1282.         voice->vc_PerfSubVolume = FXParam;
  1283.         break;
  1284.       }
  1285.       
  1286.       if( (FXParam -= 0xa0-0x50) < 0 ) break;
  1287.       
  1288.       if( FXParam <= 0x40 )
  1289.         voice->vc_TrackMasterVolume = FXParam;
  1290.       break;
  1291.     
  1292.     case 15:
  1293.       voice->vc_PerfSpeed = voice->vc_PerfWait = FXParam;
  1294.       break;
  1295.   } 
  1296. }
  1297.  
  1298. void hvl_process_frame( struct hvl_tune *ht, struct hvl_voice *voice )
  1299. {
  1300.   static CONST uint8 Offsets[] = {0x00,0x04,0x04+0x08,0x04+0x08+0x10,0x04+0x08+0x10+0x20,0x04+0x08+0x10+0x20+0x40};
  1301.  
  1302.   if( voice->vc_TrackOn == 0 )
  1303.     return;
  1304.  
  1305.   if( voice->vc_NoteDelayOn )
  1306.   {
  1307.     if( voice->vc_NoteDelayWait <= 0 )
  1308.       hvl_process_step( ht, voice );
  1309.     else
  1310.       voice->vc_NoteDelayWait--;
  1311.   }
  1312.   
  1313.   if( voice->vc_HardCut )
  1314.   {
  1315.     int32 nextinst;
  1316.     
  1317.     if( ht->ht_NoteNr+1 < ht->ht_TrackLength )
  1318.       nextinst = ht->ht_Tracks[voice->vc_Track][ht->ht_NoteNr+1].stp_Instrument;
  1319.     else
  1320.       nextinst = ht->ht_Tracks[voice->vc_NextTrack][0].stp_Instrument;
  1321.     
  1322.     if( nextinst )
  1323.     {
  1324.       int32 d1;
  1325.       
  1326.       d1 = ht->ht_Tempo - voice->vc_HardCut;
  1327.       
  1328.       if( d1 < 0 ) d1 = 0;
  1329.     
  1330.       if( !voice->vc_NoteCutOn )
  1331.       {
  1332.         voice->vc_NoteCutOn       = 1;
  1333.         voice->vc_NoteCutWait     = d1;
  1334.         voice->vc_HardCutReleaseF = -(d1-ht->ht_Tempo);
  1335.       } else {
  1336.         voice->vc_HardCut = 0;
  1337.       }
  1338.     }
  1339.   }
  1340.     
  1341.   if( voice->vc_NoteCutOn )
  1342.   {
  1343.     if( voice->vc_NoteCutWait <= 0 )
  1344.     {
  1345.       voice->vc_NoteCutOn = 0;
  1346.         
  1347.       if( voice->vc_HardCutRelease )
  1348.       {
  1349.         voice->vc_ADSR.rVolume = -(voice->vc_ADSRVolume - (voice->vc_Instrument->ins_Envelope.rVolume << 8)) / voice->vc_HardCutReleaseF;
  1350.         voice->vc_ADSR.rFrames = voice->vc_HardCutReleaseF;
  1351.         voice->vc_ADSR.aFrames = voice->vc_ADSR.dFrames = voice->vc_ADSR.sFrames = 0;
  1352.       } else {
  1353.         voice->vc_NoteMaxVolume = 0;
  1354.       }
  1355.     } else {
  1356.       voice->vc_NoteCutWait--;
  1357.     }
  1358.   }
  1359.     
  1360.   // ADSR envelope
  1361.   if( voice->vc_ADSR.aFrames )
  1362.   {
  1363.     voice->vc_ADSRVolume += voice->vc_ADSR.aVolume;
  1364.       
  1365.     if( --voice->vc_ADSR.aFrames <= 0 )
  1366.       voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.aVolume << 8;
  1367.  
  1368.   } else if( voice->vc_ADSR.dFrames ) {
  1369.     
  1370.     voice->vc_ADSRVolume += voice->vc_ADSR.dVolume;
  1371.       
  1372.     if( --voice->vc_ADSR.dFrames <= 0 )
  1373.       voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.dVolume << 8;
  1374.     
  1375.   } else if( voice->vc_ADSR.sFrames ) {
  1376.     
  1377.     voice->vc_ADSR.sFrames--;
  1378.     
  1379.   } else if( voice->vc_ADSR.rFrames ) {
  1380.     
  1381.     voice->vc_ADSRVolume += voice->vc_ADSR.rVolume;
  1382.     
  1383.     if( --voice->vc_ADSR.rFrames <= 0 )
  1384.       voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.rVolume << 8;
  1385.   }
  1386.  
  1387.   // VolumeSlide
  1388.   voice->vc_NoteMaxVolume = voice->vc_NoteMaxVolume + voice->vc_VolumeSlideUp - voice->vc_VolumeSlideDown;
  1389.  
  1390.   if( voice->vc_NoteMaxVolume < 0 )
  1391.     voice->vc_NoteMaxVolume = 0;
  1392.   else if( voice->vc_NoteMaxVolume > 0x40 )
  1393.     voice->vc_NoteMaxVolume = 0x40;
  1394.  
  1395.   // Portamento
  1396.   if( voice->vc_PeriodSlideOn )
  1397.   {
  1398.     if( voice->vc_PeriodSlideWithLimit )
  1399.     {
  1400.       int32  d0, d2;
  1401.       
  1402.       d0 = voice->vc_PeriodSlidePeriod - voice->vc_PeriodSlideLimit;
  1403.       d2 = voice->vc_PeriodSlideSpeed;
  1404.       
  1405.       if( d0 > 0 )
  1406.         d2 = -d2;
  1407.       
  1408.       if( d0 )
  1409.       {
  1410.         int32 d3;
  1411.          
  1412.         d3 = (d0 + d2) ^ d0;
  1413.         
  1414.         if( d3 >= 0 )
  1415.           d0 = voice->vc_PeriodSlidePeriod + d2;
  1416.         else
  1417.           d0 = voice->vc_PeriodSlideLimit;
  1418.         
  1419.         voice->vc_PeriodSlidePeriod = d0;
  1420.         voice->vc_PlantPeriod = 1;
  1421.       }
  1422.     } else {
  1423.       voice->vc_PeriodSlidePeriod += voice->vc_PeriodSlideSpeed;
  1424.       voice->vc_PlantPeriod = 1;
  1425.     }
  1426.   }
  1427.   
  1428.   // Vibrato
  1429.   if( voice->vc_VibratoDepth )
  1430.   {
  1431.     if( voice->vc_VibratoDelay <= 0 )
  1432.     {
  1433.       voice->vc_VibratoPeriod = (vib_tab[voice->vc_VibratoCurrent] * voice->vc_VibratoDepth) >> 7;
  1434.       voice->vc_PlantPeriod = 1;
  1435.       voice->vc_VibratoCurrent = (voice->vc_VibratoCurrent + voice->vc_VibratoSpeed) & 0x3f;
  1436.     } else {
  1437.       voice->vc_VibratoDelay--;
  1438.     }
  1439.   }
  1440.   
  1441.   // PList
  1442.   if( voice->vc_PerfList != 0 )
  1443.   {
  1444.     if( voice->vc_Instrument && voice->vc_PerfCurrent < voice->vc_Instrument->ins_PList.pls_Length )
  1445.     {
  1446.       if( --voice->vc_PerfWait <= 0 )
  1447.       {
  1448.         uint32 i;
  1449.         int32 cur;
  1450.         
  1451.         cur = voice->vc_PerfCurrent++;
  1452.         voice->vc_PerfWait = voice->vc_PerfSpeed;
  1453.         
  1454.         if( voice->vc_PerfList->pls_Entries[cur].ple_Waveform )
  1455.         {
  1456.           voice->vc_Waveform             = voice->vc_PerfList->pls_Entries[cur].ple_Waveform-1;
  1457.           voice->vc_NewWaveform          = 1;
  1458.           voice->vc_PeriodPerfSlideSpeed = voice->vc_PeriodPerfSlidePeriod = 0;
  1459.         }
  1460.         
  1461.         // Holdwave
  1462.         voice->vc_PeriodPerfSlideOn = 0;
  1463.         
  1464.         for( i=0; i<2; i++ )
  1465.           hvl_plist_command_parse( ht, voice, voice->vc_PerfList->pls_Entries[cur].ple_FX[i]&0xff, voice->vc_PerfList->pls_Entries[cur].ple_FXParam[i]&0xff );
  1466.         
  1467.         // GetNote
  1468.         if( voice->vc_PerfList->pls_Entries[cur].ple_Note )
  1469.         {
  1470.           voice->vc_InstrPeriod = voice->vc_PerfList->pls_Entries[cur].ple_Note;
  1471.           voice->vc_PlantPeriod = 1;
  1472.           voice->vc_FixedNote   = voice->vc_PerfList->pls_Entries[cur].ple_Fixed;
  1473.         }
  1474.       }
  1475.     } else {
  1476.       if( voice->vc_PerfWait )
  1477.         voice->vc_PerfWait--;
  1478.       else
  1479.         voice->vc_PeriodPerfSlideSpeed = 0;
  1480.     }
  1481.   }
  1482.   
  1483.   // PerfPortamento
  1484.   if( voice->vc_PeriodPerfSlideOn )
  1485.   {
  1486.     voice->vc_PeriodPerfSlidePeriod -= voice->vc_PeriodPerfSlideSpeed;
  1487.     
  1488.     if( voice->vc_PeriodPerfSlidePeriod )
  1489.       voice->vc_PlantPeriod = 1;
  1490.   }
  1491.   
  1492.   if( voice->vc_Waveform == 3-1 && voice->vc_SquareOn )
  1493.   {
  1494.     if( --voice->vc_SquareWait <= 0 )
  1495.     {
  1496.       int32 d1, d2, d3;
  1497.       
  1498.       d1 = voice->vc_SquareLowerLimit;
  1499.       d2 = voice->vc_SquareUpperLimit;
  1500.       d3 = voice->vc_SquarePos;
  1501.       
  1502.       if( voice->vc_SquareInit )
  1503.       {
  1504.         voice->vc_SquareInit = 0;
  1505.         
  1506.         if( d3 <= d1 )
  1507.         {
  1508.           voice->vc_SquareSlidingIn = 1;
  1509.           voice->vc_SquareSign = 1;
  1510.         } else if( d3 >= d2 ) {
  1511.           voice->vc_SquareSlidingIn = 1;
  1512.           voice->vc_SquareSign = -1;
  1513.         }
  1514.       }
  1515.       
  1516.       // NoSquareInit
  1517.       if( d1 == d3 || d2 == d3 )
  1518.       {
  1519.         if( voice->vc_SquareSlidingIn )
  1520.           voice->vc_SquareSlidingIn = 0;
  1521.         else
  1522.           voice->vc_SquareSign = -voice->vc_SquareSign;
  1523.       }
  1524.       
  1525.       d3 += voice->vc_SquareSign;
  1526.       voice->vc_SquarePos   = d3;
  1527.       voice->vc_PlantSquare = 1;
  1528.       voice->vc_SquareWait  = voice->vc_Instrument->ins_SquareSpeed;
  1529.     }
  1530.   }
  1531.   
  1532.   if( voice->vc_FilterOn && --voice->vc_FilterWait <= 0 )
  1533.   {
  1534.     uint32 i, FMax;
  1535.     int32 d1, d2, d3;
  1536.     
  1537.     d1 = voice->vc_FilterLowerLimit;
  1538.     d2 = voice->vc_FilterUpperLimit;
  1539.     d3 = voice->vc_FilterPos;
  1540.     
  1541.     if( voice->vc_FilterInit )
  1542.     {
  1543.       voice->vc_FilterInit = 0;
  1544.       if( d3 <= d1 )
  1545.       {
  1546.         voice->vc_FilterSlidingIn = 1;
  1547.         voice->vc_FilterSign      = 1;
  1548.       } else if( d3 >= d2 ) {
  1549.         voice->vc_FilterSlidingIn = 1;
  1550.         voice->vc_FilterSign      = -1;
  1551.       }
  1552.     }
  1553.     
  1554.     // NoFilterInit
  1555.     FMax = (voice->vc_FilterSpeed < 3) ? (5-voice->vc_FilterSpeed) : 1;
  1556.  
  1557.     for( i=0; i<FMax; i++ )
  1558.     {
  1559.       if( ( d1 == d3 ) || ( d2 == d3 ) )
  1560.       {
  1561.         if( voice->vc_FilterSlidingIn )
  1562.           voice->vc_FilterSlidingIn = 0;
  1563.         else
  1564.           voice->vc_FilterSign = -voice->vc_FilterSign;
  1565.       }
  1566.       d3 += voice->vc_FilterSign;
  1567.     }
  1568.     
  1569.     voice->vc_FilterPos   = d3;
  1570.     voice->vc_NewWaveform = 1;
  1571.     voice->vc_FilterWait  = voice->vc_FilterSpeed - 3;
  1572.     
  1573.     if( voice->vc_FilterWait < 1 )
  1574.       voice->vc_FilterWait = 1;
  1575.   }
  1576.  
  1577.   if( voice->vc_Waveform == 3-1 || voice->vc_PlantSquare )
  1578.   {
  1579.     // CalcSquare
  1580.     uint32  i;
  1581.     int32   Delta;
  1582.     int8   *SquarePtr;
  1583.     int32  X;
  1584.     
  1585.     SquarePtr = &waves[WO_SQUARES+(voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3)];
  1586.     X = voice->vc_SquarePos << (5 - voice->vc_WaveLength);
  1587.     
  1588.     if( X > 0x20 )
  1589.     {
  1590.       X = 0x40 - X;
  1591.       voice->vc_SquareReverse = 1;
  1592.     }
  1593.     
  1594.     // OkDownSquare
  1595.     if( --X )
  1596.       SquarePtr += X << 7;
  1597.     
  1598.     Delta = 32 >> voice->vc_WaveLength;
  1599.     ht->ht_WaveformTab[2] = voice->vc_SquareTempBuffer;
  1600.     
  1601.     for( i=0; i<(1<<voice->vc_WaveLength)*4; i++ )
  1602.     {
  1603.       // THX.draft-hawk fucks this up, ATM
  1604.       if( SquarePtr >= &waves[WO_WHITENOISE] )
  1605.         SquarePtr = &waves[WO_SQUARES];
  1606.       if( SquarePtr < &waves[0] )
  1607.         SquarePtr = &waves[WO_WHITENOISE-1];
  1608.       if( i>=0x80 ) break;
  1609.       voice->vc_SquareTempBuffer[i] = *SquarePtr;
  1610.       SquarePtr += Delta;
  1611.     }
  1612.     
  1613.     voice->vc_NewWaveform = 1;
  1614.     voice->vc_Waveform    = 3-1;
  1615.     voice->vc_PlantSquare = 0;
  1616.   }
  1617.   
  1618.   if( voice->vc_Waveform == 4-1 )
  1619.     voice->vc_NewWaveform = 1;
  1620.   
  1621.   if( voice->vc_RingNewWaveform )
  1622.   {
  1623.     int8 *rasrc;
  1624.     
  1625.     if( voice->vc_RingWaveform > 1 ) voice->vc_RingWaveform = 1;
  1626.     
  1627.     rasrc = ht->ht_WaveformTab[voice->vc_RingWaveform];
  1628.     rasrc += Offsets[voice->vc_WaveLength];
  1629.     
  1630.     voice->vc_RingAudioSource = rasrc;
  1631.   }    
  1632.         
  1633.   
  1634.   if( voice->vc_NewWaveform )
  1635.   {
  1636.     int8 *AudioSource;
  1637.  
  1638.     AudioSource = ht->ht_WaveformTab[voice->vc_Waveform];
  1639.  
  1640.     if( voice->vc_Waveform != 3-1 )
  1641.       AudioSource += (voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3);
  1642.  
  1643.     if( voice->vc_Waveform < 3-1)
  1644.     {
  1645.       // GetWLWaveformlor2
  1646.       AudioSource += Offsets[voice->vc_WaveLength];
  1647.     }
  1648.  
  1649.     if( voice->vc_Waveform == 4-1 )
  1650.     {
  1651.       // AddRandomMoving
  1652.       AudioSource += ( voice->vc_WNRandom & (2*0x280-1) ) & ~1;
  1653.       // GoOnRandom
  1654.       voice->vc_WNRandom += 2239384;
  1655.       voice->vc_WNRandom  = ((((voice->vc_WNRandom >> 8) | (voice->vc_WNRandom << 24)) + 782323) ^ 75) - 6735;
  1656.     }
  1657.  
  1658.     voice->vc_AudioSource = AudioSource;
  1659.   }
  1660.   
  1661.   // Ring modulation period calculation
  1662.   if( voice->vc_RingAudioSource )
  1663.   {
  1664.     voice->vc_RingAudioPeriod = voice->vc_RingBasePeriod;
  1665.   
  1666.     if( !(voice->vc_RingFixedPeriod) )
  1667.       voice->vc_RingAudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
  1668.   
  1669.     if( voice->vc_RingAudioPeriod > 5*12 )
  1670.       voice->vc_RingAudioPeriod = 5*12;
  1671.   
  1672.     if( voice->vc_RingAudioPeriod < 0 )
  1673.       voice->vc_RingAudioPeriod = 0;
  1674.   
  1675.     voice->vc_RingAudioPeriod = period_tab[voice->vc_RingAudioPeriod];
  1676.  
  1677.     if( !(voice->vc_RingFixedPeriod) )
  1678.       voice->vc_RingAudioPeriod += voice->vc_PeriodSlidePeriod;
  1679.  
  1680.     voice->vc_RingAudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;
  1681.  
  1682.     if( voice->vc_RingAudioPeriod > 0x0d60 )
  1683.       voice->vc_RingAudioPeriod = 0x0d60;
  1684.  
  1685.     if( voice->vc_RingAudioPeriod < 0x0071 )
  1686.       voice->vc_RingAudioPeriod = 0x0071;
  1687.   }
  1688.   
  1689.   // Normal period calculation
  1690.   voice->vc_AudioPeriod = voice->vc_InstrPeriod;
  1691.   
  1692.   if( !(voice->vc_FixedNote) )
  1693.     voice->vc_AudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
  1694.     
  1695.   if( voice->vc_AudioPeriod > 5*12 )
  1696.     voice->vc_AudioPeriod = 5*12;
  1697.   
  1698.   if( voice->vc_AudioPeriod < 0 )
  1699.     voice->vc_AudioPeriod = 0;
  1700.   
  1701.   voice->vc_AudioPeriod = period_tab[voice->vc_AudioPeriod];
  1702.   
  1703.   if( !(voice->vc_FixedNote) )
  1704.     voice->vc_AudioPeriod += voice->vc_PeriodSlidePeriod;
  1705.  
  1706.   voice->vc_AudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;    
  1707.  
  1708.   if( voice->vc_AudioPeriod > 0x0d60 )
  1709.     voice->vc_AudioPeriod = 0x0d60;
  1710.  
  1711.   if( voice->vc_AudioPeriod < 0x0071 )
  1712.     voice->vc_AudioPeriod = 0x0071;
  1713.   
  1714.   voice->vc_AudioVolume = (((((((voice->vc_ADSRVolume >> 8) * voice->vc_NoteMaxVolume) >> 6) * voice->vc_PerfSubVolume) >> 6) * voice->vc_TrackMasterVolume) >> 6);
  1715. }
  1716.  
  1717. void hvl_set_audio( struct hvl_voice *voice, float64 freqf )
  1718. {
  1719.  
  1720.   if( voice->vc_TrackOn == 0 )
  1721.   {
  1722.     voice->vc_VoiceVolume = 0;
  1723.     return;
  1724.   }
  1725.   
  1726.   voice->vc_VoiceVolume = voice->vc_AudioVolume;
  1727.   
  1728.   if( voice->vc_PlantPeriod )
  1729.   {
  1730.     float64 freq2;
  1731.     uint32  delta;
  1732.     
  1733.     voice->vc_PlantPeriod = 0;
  1734.     voice->vc_VoicePeriod = voice->vc_AudioPeriod;
  1735.     
  1736.     freq2 = Period2Freq( voice->vc_AudioPeriod );
  1737.     delta = (uint32)(freq2 / freqf);
  1738.  
  1739.     if( delta > (0x280<<16) ) delta -= (0x280<<16);
  1740.     if( delta == 0 ) delta = 1;
  1741.     voice->vc_Delta = delta;
  1742.   }
  1743.   
  1744.   if( voice->vc_NewWaveform )
  1745.   {
  1746.     int8 *src;
  1747.     
  1748.     src = voice->vc_AudioSource;
  1749.     
  1750.     if( voice->vc_Waveform == 4-1 )
  1751.     {
  1752.       CopyMem((void *)src, &voice->vc_VoiceBuffer[0], 0x280);
  1753.     } else {
  1754.       uint32 i, WaveLoops;
  1755.  
  1756.       WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
  1757.  
  1758.       for( i=0; i<WaveLoops; i++ )
  1759.         CopyMem((void *)src, &voice->vc_VoiceBuffer[i*4*(1<<voice->vc_WaveLength)], 4*(1<<voice->vc_WaveLength));
  1760.     }
  1761.  
  1762.     voice->vc_VoiceBuffer[0x280] = voice->vc_VoiceBuffer[0];
  1763.     voice->vc_MixSource          = voice->vc_VoiceBuffer;
  1764.   }
  1765.  
  1766.   /* Ring Modulation */
  1767.   if( voice->vc_RingPlantPeriod )
  1768.   {
  1769.     float64 freq2;
  1770.     uint32  delta;
  1771.     
  1772.     voice->vc_RingPlantPeriod = 0;
  1773.     freq2 = Period2Freq( voice->vc_RingAudioPeriod );
  1774.     delta = (uint32)(freq2 / freqf);
  1775.  
  1776.     if( delta > (0x280<<16) ) delta -= (0x280<<16);
  1777.     if( delta == 0 ) delta = 1;
  1778.     voice->vc_RingDelta = delta;
  1779.   }
  1780.   
  1781.   if( voice->vc_RingNewWaveform )
  1782.   {
  1783.     int8 *src;
  1784.     uint32 i, WaveLoops;
  1785.     
  1786.     src = voice->vc_RingAudioSource;
  1787.  
  1788.     WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
  1789.  
  1790.     for( i=0; i<WaveLoops; i++ )
  1791.       CopyMem((void *)src, &voice->vc_RingVoiceBuffer[i*4*(1<<voice->vc_WaveLength)], 4*(1<<voice->vc_WaveLength));
  1792.  
  1793.     voice->vc_RingVoiceBuffer[0x280] = voice->vc_RingVoiceBuffer[0];
  1794.     voice->vc_RingMixSource          = voice->vc_RingVoiceBuffer;
  1795.   }
  1796. }
  1797.  
  1798. void hvl_play_irq( struct hvl_tune *ht )
  1799. {
  1800.   uint32 i;
  1801.  
  1802.   if( ht->ht_StepWaitFrames <= 0 )
  1803.   {
  1804.     if( ht->ht_GetNewPosition )
  1805.     {
  1806.       int32 nextpos = (ht->ht_PosNr+1==ht->ht_PositionNr)?0:(ht->ht_PosNr+1);
  1807.  
  1808.       for( i=0; i<ht->ht_Channels; i++ )
  1809.       {
  1810.         ht->ht_Voices[i].vc_Track         = ht->ht_Positions[ht->ht_PosNr].pos_Track[i];
  1811.         ht->ht_Voices[i].vc_Transpose     = ht->ht_Positions[ht->ht_PosNr].pos_Transpose[i];
  1812.         ht->ht_Voices[i].vc_NextTrack     = ht->ht_Positions[nextpos].pos_Track[i];
  1813.         ht->ht_Voices[i].vc_NextTranspose = ht->ht_Positions[nextpos].pos_Transpose[i];
  1814.       }
  1815.       ht->ht_GetNewPosition = 0;
  1816.     }
  1817.     
  1818.     for( i=0; i<ht->ht_Channels; i++ )
  1819.       hvl_process_step( ht, &ht->ht_Voices[i] );
  1820.     
  1821.     ht->ht_StepWaitFrames = ht->ht_Tempo;
  1822.   }
  1823.   
  1824.   for( i=0; i<ht->ht_Channels; i++ )
  1825.     hvl_process_frame( ht, &ht->ht_Voices[i] );
  1826.  
  1827.   ht->ht_PlayingTime++;
  1828.   if( ht->ht_Tempo > 0 && --ht->ht_StepWaitFrames <= 0 )
  1829.   {
  1830.     if( !ht->ht_PatternBreak )
  1831.     {
  1832.       ht->ht_NoteNr++;
  1833.       if( ht->ht_NoteNr >= ht->ht_TrackLength )
  1834.       {
  1835.         ht->ht_PosJump      = ht->ht_PosNr+1;
  1836.         ht->ht_PosJumpNote  = 0;
  1837.         ht->ht_PatternBreak = 1;
  1838.       }
  1839.     }
  1840.     
  1841.     if( ht->ht_PatternBreak )
  1842.     {
  1843.       ht->ht_PatternBreak = 0;
  1844.       ht->ht_PosNr        = ht->ht_PosJump;
  1845.       ht->ht_NoteNr       = ht->ht_PosJumpNote;
  1846.       if( ht->ht_PosNr == ht->ht_PositionNr )
  1847.       {
  1848.         ht->ht_SongEndReached = 1;
  1849.         ht->ht_PosNr          = ht->ht_Restart;
  1850.       }
  1851.       ht->ht_PosJumpNote  = 0;
  1852.       ht->ht_PosJump      = 0;
  1853.  
  1854.       ht->ht_GetNewPosition = 1;
  1855.     }
  1856.   }
  1857.  
  1858.   for( i=0; i<ht->ht_Channels; i++ )
  1859.     hvl_set_audio( &ht->ht_Voices[i], ht->ht_Frequency );
  1860. }
  1861.  
  1862. void hvl_mixchunk( struct hvl_tune *ht, uint32 samples, int8 *buf1, int8 *buf2, int32 bufmod )
  1863. {
  1864.   int8   *src[MAX_CHANNELS];
  1865.   int8   *rsrc[MAX_CHANNELS];
  1866.   uint32  delta[MAX_CHANNELS];
  1867.   uint32  rdelta[MAX_CHANNELS];
  1868.   int32   vol[MAX_CHANNELS];
  1869.   uint32  pos[MAX_CHANNELS];
  1870.   uint32  rpos[MAX_CHANNELS];
  1871.   uint32  cnt;
  1872.   int32   panl[MAX_CHANNELS];
  1873.   int32   panr[MAX_CHANNELS];
  1874. //  uint32  vu[MAX_CHANNELS];
  1875.   int32   a=0, b=0, j;
  1876.   uint32  i, chans, loops;
  1877.   
  1878.   chans = ht->ht_Channels;
  1879.   for( i=0; i<chans; i++ )
  1880.   {
  1881.     delta[i] = ht->ht_Voices[i].vc_Delta;
  1882.     vol[i]   = ht->ht_Voices[i].vc_VoiceVolume;
  1883.     pos[i]   = ht->ht_Voices[i].vc_SamplePos;
  1884.     src[i]   = ht->ht_Voices[i].vc_MixSource;
  1885.     panl[i]  = ht->ht_Voices[i].vc_PanMultLeft;
  1886.     panr[i]  = ht->ht_Voices[i].vc_PanMultRight;
  1887.     
  1888.     /* Ring Modulation */
  1889.     rdelta[i]= ht->ht_Voices[i].vc_RingDelta;
  1890.     rpos[i]  = ht->ht_Voices[i].vc_RingSamplePos;
  1891.     rsrc[i]  = ht->ht_Voices[i].vc_RingMixSource;
  1892.     
  1893. //    vu[i] = 0;
  1894.   }
  1895.   
  1896.   do
  1897.   {
  1898.     loops = samples;
  1899.     for( i=0; i<chans; i++ )
  1900.     {
  1901.       if( pos[i] >= (0x280 << 16)) pos[i] -= 0x280<<16;
  1902.       if (delta[i]!=0) {
  1903.         cnt = ((0x280<<16) - pos[i] - 1) / delta[i] + 1;
  1904.         if( cnt < loops ) loops = cnt;
  1905.       
  1906.         if( rsrc[i] )
  1907.         {
  1908.           if( rpos[i] >= (0x280<<16)) rpos[i] -= 0x280<<16;
  1909.           cnt = ((0x280<<16) - rpos[i] - 1) / rdelta[i] + 1;
  1910.           if( cnt < loops ) loops = cnt;
  1911.         }
  1912.       }
  1913.     }
  1914.     
  1915.     samples -= loops;
  1916.     
  1917.     // Inner loop
  1918.     do
  1919.     {
  1920.       a=0;
  1921.       b=0;
  1922.       for( i=0; i<chans; i++ )
  1923.       {
  1924.         if( rsrc[i] )
  1925.         {
  1926.           /* Ring Modulation */
  1927.           j = ((src[i][pos[i]>>16]*rsrc[i][rpos[i]>>16])>>7)*vol[i];
  1928.           rpos[i] += rdelta[i];
  1929.         } else {
  1930.           j = src[i][pos[i]>>16]*vol[i];
  1931.         }
  1932.         
  1933. //        if( abs( j ) > vu[i] ) vu[i] = abs( j );
  1934.  
  1935.         a += (j * panl[i]) >> 7;
  1936.         b += (j * panr[i]) >> 7;
  1937.         pos[i] += delta[i];
  1938.       }
  1939.       
  1940.       a = (a*ht->ht_mixgain)>>8;
  1941.       b = (b*ht->ht_mixgain)>>8;
  1942.       
  1943.       *(int16 *)buf1 = a;
  1944.       *(int16 *)buf2 = b;
  1945.       
  1946.       loops--;
  1947.       
  1948.       buf1 += bufmod;
  1949.       buf2 += bufmod;
  1950.     } while( loops > 0 );
  1951.   } while( samples > 0 );
  1952.  
  1953.   for( i=0; i<chans; i++ )
  1954.   {
  1955.     ht->ht_Voices[i].vc_SamplePos = pos[i];
  1956.     ht->ht_Voices[i].vc_RingSamplePos = rpos[i];
  1957. //    ht->ht_Voices[i].vc_VUMeter = vu[i];
  1958.   }
  1959. }
  1960.  
  1961. void hvl_DecodeFrame( struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod )
  1962. {
  1963.   uint32 samples, loops;
  1964.   
  1965.   samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
  1966.   loops   = ht->ht_SpeedMultiplier*4;
  1967.   
  1968.   do
  1969.   {
  1970.     hvl_play_irq( ht );
  1971.     hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
  1972.     buf1 += samples * 4;
  1973.     buf2 += samples * 4;
  1974.     loops--;
  1975.   } while( loops );
  1976. }
  1977.