Timing is correct now! Forgot to update samples_per_tick when parsing the 0xf effect.
[pineappletracker.git] / hively / hvl_replay.bak
blob40d4be1a9b8c551b0cbecffc4904e7a10bc3fcfa
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <math.h>
6 #include "types.h"
7 #include <string.h>
9 #include "hvl_replay.h"
11 int32 stereopan_left[]  = { 128,  96,  64,  32,   0 };
12 int32 stereopan_right[] = { 128, 160, 193, 225, 255 };
15 ** Waves
17 #define WHITENOISELEN (0x280*3)
19 #define WO_LOWPASSES   0
20 #define WO_TRIANGLE_04 (WO_LOWPASSES+((0xfc+0xfc+0x80*0x1f+0x80+3*0x280)*31))
21 //#define WO_TRIANGLE_04 (WO_LOWPASSES+((0x01+0x01+0x01*0x01+0x01+3*0x010)*31))
22 #define WO_TRIANGLE_08 (WO_TRIANGLE_04+0x04)
23 #define WO_TRIANGLE_10 (WO_TRIANGLE_08+0x08)
24 #define WO_TRIANGLE_20 (WO_TRIANGLE_10+0x10)
25 #define WO_TRIANGLE_40 (WO_TRIANGLE_20+0x20)
26 #define WO_TRIANGLE_80 (WO_TRIANGLE_40+0x40)
27 #define WO_SAWTOOTH_04 (WO_TRIANGLE_80+0x80)
28 #define WO_SAWTOOTH_08 (WO_SAWTOOTH_04+0x04)
29 #define WO_SAWTOOTH_10 (WO_SAWTOOTH_08+0x08)
30 #define WO_SAWTOOTH_20 (WO_SAWTOOTH_10+0x10)
31 #define WO_SAWTOOTH_40 (WO_SAWTOOTH_20+0x20)
32 #define WO_SAWTOOTH_80 (WO_SAWTOOTH_40+0x40)
33 #define WO_SQUARES     (WO_SAWTOOTH_80+0x80)
34 #define WO_WHITENOISE  (WO_SQUARES+(0x80*0x20))
35 #define WO_HIGHPASSES  (WO_WHITENOISE+WHITENOISELEN)
36 #define WAVES_SIZE     (WO_HIGHPASSES+((0xfc+0xfc+0x80*0x1f+0x80+3*0x280)*31))
38 int8 waves[WAVES_SIZE];
40 CONST int16 vib_tab[] =
41
42   0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
43   253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
44   0,-24,-49,-74,-97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,-255,
45   -253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,-97,-74,-49,-24
48 CONST uint16 period_tab[] =
50   0x0000, 0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970,
51   0x08E8, 0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4,
52   0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0,
53   0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C,
54   0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D,
55   0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0,
56   0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097,
57   0x008F, 0x0087, 0x007F, 0x0078, 0x0071
60 uint32 panning_left[256], panning_right[256];
62 static inline void clr_l( ULONG *src, uint32 longs)
64   do {
65     *src++ = 0;
66     longs--;
67   } while (longs > 0);
70 void hvl_GenPanningTables( void )
72   uint32 i;
73   float64 aa, ab;
75   // Sine based panning table
76   aa = (3.14159265f*2.0f)/4.0f;   // Quarter of the way through the sinewave == top peak
77   ab = 0.0f;                      // Start of the climb from zero
79   for( i=0; i<256; i++ )
80   {
81     panning_left[i]  = (uint32)(sin(aa)*255.0f);
82     panning_right[i] = (uint32)(sin(ab)*255.0f);
83     
84     aa += (3.14159265*2.0f/4.0f)/256.0f;
85     ab += (3.14159265*2.0f/4.0f)/256.0f;
86   }
87   panning_left[255] = 0;
88   panning_right[0] = 0;
91 void hvl_GenSawtooth( int8 *buf, uint32 len )
93   uint32 i;
94   int32  val, add;
95   
96   add = 256 / (len-1);
97   val = -128;
98   
99   for( i=0; i<len; i++, val += add )
100     *buf++ = (int8)val;  
103 void hvl_GenTriangle( int8 *buf, uint32 len )
105   uint32 i;
106   int32  d2, d5, d1, d4;
107   int32  val;
108   int8   *buf2;
109   
110   d2  = len;
111   d5  = len >> 2;
112   d1  = 128/d5;
113   d4  = -(d2 >> 1);
114   val = 0;
115   
116   for( i=0; i<d5; i++ )
117   {
118     *buf++ = val;
119     val += d1;
120   }
121   *buf++ = 0x7f;
123   if( d5 != 1 )
124   {
125     val = 128;
126     for( i=0; i<d5-1; i++ )
127     {
128       val -= d1;
129       *buf++ = val;
130     }
131   }
132   
133   buf2 = buf + d4;
134   for( i=0; i<d5*2; i++ )
135   {
136     int8 c;
137     
138     c = *buf2++;
139     if( c == 0x7f )
140       c = 0x80;
141     else
142       c = -c;
143     
144     *buf++ = c;
145   }
148 void hvl_GenSquare( int8 *buf )
150   uint32 i, j;
151   
152   for( i=1; i<=0x20; i++ )
153   {
154     for( j=0; j<(0x40-i)*2; j++ )
155       *buf++ = 0x80;
156     for( j=0; j<i*2; j++ )
157       *buf++ = 0x7f;
158   }
161 static inline float64 clip( float64 x )
163   if( x > 127.f )
164     x = 127.f;
165   else if( x < -128.f )
166     x = -128.f;
167   return x;
170 void hvl_GenFilterWaves( int8 *buf, int8 *lowbuf, int8 *highbuf )
172   static const uint16 LengthTable[45] = { 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 3, 7, 0xf, 0x1f, 0x3f, 0x7f,
173      0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
174      0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
175      (0x280*3)-1 };
177   float64 freq;
178   uint32 temp;
179   
180   for( temp=0, freq=8.f; temp<31; temp++, freq += 3.f )
181   {
182     uint32 waves;
183     int8   *a0 = buf;
184     
185     for( waves=0; waves<6+6+0x20+1; waves++ )
186     {
187       float64 fre, high, mid, low;
188       uint32 i;
189       
190       mid = 0.f;
191       low = 0.f;
192       fre = freq * 1.25f / 100.f;
193       
194       for( i=0; i<=LengthTable[waves]; i++ )
195       {
196         high  = a0[i] - mid - low;
197         high  = clip( high );
198         mid  += high * fre;
199         mid   = clip( mid );
200         low  += mid * fre;
201         low   = clip( low );
202       }
203       
204       for( i=0; i<=LengthTable[waves]; 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         *lowbuf++  = (int8)low;
213         *highbuf++ = (int8)high;
214       }
215       
216       a0 += LengthTable[waves] + 1;
217     }
218   }
221 void hvl_GenWhiteNoise( int8 *buf, uint32 len )
223   uint32 ays;
225   ays = 0x41595321;
227   do {
228     uint16 ax, bx;
229     int8 s;
231     s = ays;
233     if( ays & 0x100 )
234     {
235       s = 0x80;
237       if( (LONG)(ays & 0xffff) >= 0 )
238         s = 0x7f;
239     }
241     *buf++ = s;
242     len--;
244     ays = (ays >> 5) | (ays << 27);
245     ays = (ays & 0xffffff00) | ((ays & 0xff) ^ 0x9a);
246     bx  = ays;
247     ays = (ays << 2) | (ays >> 30);
248     ax  = ays;
249     bx  += ax;
250     ax  ^= bx;
251     ays  = (ays & 0xffff0000) | ax;
252     ays  = (ays >> 3) | (ays << 29);
253   } while( len );
256 void hvl_reset_some_stuff( struct hvl_tune *ht )
258   uint32 i;
260   for( i=0; i<MAX_CHANNELS; i++ )
261   {
262     ht->ht_Voices[i].vc_Delta=1;
263     ht->ht_Voices[i].vc_SamplePos=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;
264     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;
265     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;
266     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;
267     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;
268     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;
269     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;
270     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;
271     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;
272     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;
273     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;
274     ht->ht_Voices[i].vc_PerfList=0;
275     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;
277     ht->ht_Voices[i].vc_RingMixSource = NULL;
278     ht->ht_Voices[i].vc_RingAudioSource = NULL;
280     clr_l((ULONG *)&ht->ht_Voices[i].vc_SquareTempBuffer,0x80/4);
281     clr_l((ULONG *)&ht->ht_Voices[i].vc_ADSR,sizeof(struct hvl_envelope)/4);
282     clr_l((ULONG *)&ht->ht_Voices[i].vc_VoiceBuffer,0x281/4);
283     clr_l((ULONG *)&ht->ht_Voices[i].vc_RingVoiceBuffer,0x281/4);
284   }
285   
286   for( i=0; i<MAX_CHANNELS; i++ )
287   {
288     ht->ht_Voices[i].vc_WNRandom          = 0x280;
289     ht->ht_Voices[i].vc_VoiceNum          = i;
290     ht->ht_Voices[i].vc_TrackMasterVolume = 0x40;
291     ht->ht_Voices[i].vc_TrackOn           = 1;
292     ht->ht_Voices[i].vc_MixSource         = ht->ht_Voices[i].vc_VoiceBuffer;
293   }
296 BOOL hvl_InitSubsong( struct hvl_tune *ht, uint32 nr )
298   uint32 PosNr, i;
300   if( nr > ht->ht_SubsongNr )
301     return FALSE;
303   ht->ht_SongNum = nr;
304   
305   PosNr = 0;
306   if( nr ) PosNr = ht->ht_Subsongs[nr-1];
307   
308   ht->ht_PosNr          = PosNr;
309   ht->ht_PosJump        = 0;
310   ht->ht_PatternBreak   = 0;
311   ht->ht_NoteNr         = 0;
312   ht->ht_PosJumpNote    = 0;
313   ht->ht_Tempo          = 8;
314   ht->ht_StepWaitFrames = 0;
315   ht->ht_GetNewPosition = 1;
316   ht->ht_SongEndReached = 0;
317   ht->ht_PlayingTime    = 0;
318   
319   for( i=0; i<MAX_CHANNELS; i+=4 )
320   {
321     ht->ht_Voices[i+0].vc_Pan          = ht->ht_defpanleft;
322     ht->ht_Voices[i+0].vc_SetPan       = ht->ht_defpanleft; // 1.4
323     ht->ht_Voices[i+0].vc_PanMultLeft  = panning_left[ht->ht_defpanleft];
324     ht->ht_Voices[i+0].vc_PanMultRight = panning_right[ht->ht_defpanleft];
325     ht->ht_Voices[i+1].vc_Pan          = ht->ht_defpanright;
326     ht->ht_Voices[i+1].vc_SetPan       = ht->ht_defpanright; // 1.4
327     ht->ht_Voices[i+1].vc_PanMultLeft  = panning_left[ht->ht_defpanright];
328     ht->ht_Voices[i+1].vc_PanMultRight = panning_right[ht->ht_defpanright];
329     ht->ht_Voices[i+2].vc_Pan          = ht->ht_defpanright;
330     ht->ht_Voices[i+2].vc_SetPan       = ht->ht_defpanright; // 1.4
331     ht->ht_Voices[i+2].vc_PanMultLeft  = panning_left[ht->ht_defpanright];
332     ht->ht_Voices[i+2].vc_PanMultRight = panning_right[ht->ht_defpanright];
333     ht->ht_Voices[i+3].vc_Pan          = ht->ht_defpanleft;
334     ht->ht_Voices[i+3].vc_SetPan       = ht->ht_defpanleft;  // 1.4
335     ht->ht_Voices[i+3].vc_PanMultLeft  = panning_left[ht->ht_defpanleft];
336     ht->ht_Voices[i+3].vc_PanMultRight = panning_right[ht->ht_defpanleft];
337   }
339   hvl_reset_some_stuff( ht );
340   
341   return TRUE;
344 void hvl_InitReplayer( void )
346   hvl_GenPanningTables();
347   hvl_GenSawtooth( &waves[WO_SAWTOOTH_04], 0x04 );
348   hvl_GenSawtooth( &waves[WO_SAWTOOTH_08], 0x08 );
349   hvl_GenSawtooth( &waves[WO_SAWTOOTH_10], 0x10 );
350   hvl_GenSawtooth( &waves[WO_SAWTOOTH_20], 0x20 );
351   hvl_GenSawtooth( &waves[WO_SAWTOOTH_40], 0x40 );
352   hvl_GenSawtooth( &waves[WO_SAWTOOTH_80], 0x80 );
353   hvl_GenTriangle( &waves[WO_TRIANGLE_04], 0x04 );
354   hvl_GenTriangle( &waves[WO_TRIANGLE_08], 0x08 );
355   hvl_GenTriangle( &waves[WO_TRIANGLE_10], 0x10 );
356   hvl_GenTriangle( &waves[WO_TRIANGLE_20], 0x20 );
357   hvl_GenTriangle( &waves[WO_TRIANGLE_40], 0x40 );
358   hvl_GenTriangle( &waves[WO_TRIANGLE_80], 0x80 );
359   hvl_GenSquare( &waves[WO_SQUARES] );
360   hvl_GenWhiteNoise( &waves[WO_WHITENOISE], WHITENOISELEN );
361   hvl_GenFilterWaves( &waves[WO_TRIANGLE_04], &waves[WO_LOWPASSES], &waves[WO_HIGHPASSES] );
364 struct hvl_tune *hvl_load_ahx( uint8 *buf, uint32 buflen, uint32 defstereo, uint32 freq )
366   uint8  *bptr;
367   TEXT   *nptr;
368   uint32  i, j, k, l, posn, insn, ssn, hs, trkn, trkl;
369   struct hvl_tune *ht;
370   struct  hvl_plsentry *ple;
371   int32 defgain[] = { 71, 72, 76, 85, 100 };
372   
373   posn = ((buf[6]&0x0f)<<8)|buf[7];
374   insn = buf[12];
375   ssn  = buf[13];
376   trkl = buf[10];
377   trkn = buf[11];
379   hs  = sizeof( struct hvl_tune );
380   hs += sizeof( struct hvl_position ) * posn;
381   hs += sizeof( struct hvl_instrument ) * (insn+1);
382   hs += sizeof( uint16 ) * ssn;
384   // Calculate the size of all instrument PList buffers
385   bptr = &buf[14];
386   bptr += ssn*2;    // Skip past the subsong list
387   bptr += posn*4*2; // Skip past the positions
388   bptr += trkn*trkl*3;
389   if((buf[6]&0x80)==0) bptr += trkl*3;
390   
391   // *NOW* we can finally calculate PList space
392   for( i=1; i<=insn; i++ )
393   {
394     hs += bptr[21] * sizeof( struct hvl_plsentry );
395     bptr += 22 + bptr[21]*4;
396   }
398   ht = malloc(hs); //AllocVec( hs, MEMF_ANY );
399   if( !ht )
400   {
401     free( buf );
402     printf( "Out of memory!\n" );
403     return NULL;
404   }
405   
406   ht->ht_Frequency       = freq;
407   ht->ht_FreqF           = (float64)freq;
408   
409   ht->ht_Positions   = (struct hvl_position *)(&ht[1]);
410   ht->ht_Instruments = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
411   ht->ht_Subsongs    = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
412   ple                = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
414   ht->ht_WaveformTab[0]  = &waves[WO_TRIANGLE_04];
415   ht->ht_WaveformTab[1]  = &waves[WO_SAWTOOTH_04];
416   ht->ht_WaveformTab[3]  = &waves[WO_WHITENOISE];
418   ht->ht_Channels        = 4;
419   ht->ht_PositionNr      = posn;
420   ht->ht_Restart         = (buf[8]<<8)|buf[9];
421   ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
422   ht->ht_TrackLength     = trkl;
423   ht->ht_TrackNr         = trkn;
424   ht->ht_InstrumentNr    = insn;
425   ht->ht_SubsongNr       = ssn;
426   ht->ht_defstereo       = defstereo;
427   ht->ht_defpanleft      = stereopan_left[ht->ht_defstereo];
428   ht->ht_defpanright     = stereopan_right[ht->ht_defstereo];
429   ht->ht_mixgain         = (defgain[ht->ht_defstereo]*256)/100;
430   
431   if( ht->ht_Restart >= ht->ht_PositionNr )
432     ht->ht_Restart = ht->ht_PositionNr-1;
434   // Do some validation  
435   if( ( ht->ht_PositionNr > 1000 ) ||
436       ( ht->ht_TrackLength > 64 ) ||
437       ( ht->ht_InstrumentNr > 64 ) )
438   {
439     printf( "%d,%d,%d\n", ht->ht_PositionNr,
440                           ht->ht_TrackLength,
441                           ht->ht_InstrumentNr );
442     free( ht );
443     free( buf );
444     printf( "Invalid file.\n" );
445     return NULL;
446   }
448   strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
449   nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
451   bptr = &buf[14];
452   
453   // Subsongs
454   for( i=0; i<ht->ht_SubsongNr; i++ )
455   {
456     ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
457     if( ht->ht_Subsongs[i] >= ht->ht_PositionNr )
458       ht->ht_Subsongs[i] = 0;
459     bptr += 2;
460   }
461   
462   // Position list
463   for( i=0; i<ht->ht_PositionNr; i++ )
464   {
465     for( j=0; j<4; j++ )
466     {
467       ht->ht_Positions[i].pos_Track[j]     = *bptr++;
468       ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
469     }
470   }
471   
472   // Tracks
473   for( i=0; i<=ht->ht_TrackNr; i++ )
474   {
475     if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
476     {
477       for( j=0; j<ht->ht_TrackLength; j++ )
478       {
479         ht->ht_Tracks[i][j].stp_Note       = 0;
480         ht->ht_Tracks[i][j].stp_Instrument = 0;
481         ht->ht_Tracks[i][j].stp_FX         = 0;
482         ht->ht_Tracks[i][j].stp_FXParam    = 0;
483         ht->ht_Tracks[i][j].stp_FXb        = 0;
484         ht->ht_Tracks[i][j].stp_FXbParam   = 0;
485       }
486       continue;
487     }
488     
489     for( j=0; j<ht->ht_TrackLength; j++ )
490     {
491       ht->ht_Tracks[i][j].stp_Note       = (bptr[0]>>2)&0x3f;
492       ht->ht_Tracks[i][j].stp_Instrument = ((bptr[0]&0x3)<<4) | (bptr[1]>>4);
493       ht->ht_Tracks[i][j].stp_FX         = bptr[1]&0xf;
494       ht->ht_Tracks[i][j].stp_FXParam    = bptr[2];
495       ht->ht_Tracks[i][j].stp_FXb        = 0;
496       ht->ht_Tracks[i][j].stp_FXbParam   = 0;
497       bptr += 3;
498     }
499   }
500   
501   // Instruments
502   for( i=1; i<=ht->ht_InstrumentNr; i++ )
503   {
504     if( nptr < (TEXT *)(buf+buflen) )
505     {
506       strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
507       nptr += strlen( nptr )+1;
508     } else {
509       ht->ht_Instruments[i].ins_Name[0] = 0;
510     }
511     
512     ht->ht_Instruments[i].ins_Volume      = bptr[0];
513     ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
514     ht->ht_Instruments[i].ins_WaveLength  = bptr[1]&0x07;
516     ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
517     ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
518     ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
519     ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
520     ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
521     ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
522     ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
523     
524     ht->ht_Instruments[i].ins_FilterLowerLimit     = bptr[12]&0x7f;
525     ht->ht_Instruments[i].ins_VibratoDelay         = bptr[13];
526     ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
527     ht->ht_Instruments[i].ins_HardCutRelease       = bptr[14]&0x80?1:0;
528     ht->ht_Instruments[i].ins_VibratoDepth         = bptr[14]&0x0f;
529     ht->ht_Instruments[i].ins_VibratoSpeed         = bptr[15];
530     ht->ht_Instruments[i].ins_SquareLowerLimit     = bptr[16];
531     ht->ht_Instruments[i].ins_SquareUpperLimit     = bptr[17];
532     ht->ht_Instruments[i].ins_SquareSpeed          = bptr[18];
533     ht->ht_Instruments[i].ins_FilterUpperLimit     = bptr[19]&0x3f;
534     ht->ht_Instruments[i].ins_PList.pls_Speed      = bptr[20];
535     ht->ht_Instruments[i].ins_PList.pls_Length     = bptr[21];
536     
537     ht->ht_Instruments[i].ins_PList.pls_Entries    = ple;
538     ple += bptr[21];
539     
540     bptr += 22;
541     for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
542     {
543       k = (bptr[0]>>5)&7;
544       if( k == 6 ) k = 12;
545       if( k == 7 ) k = 15;
546       l = (bptr[0]>>2)&7;
547       if( l == 6 ) l = 12;
548       if( l == 7 ) l = 15;
549       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1]      = k;
550       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0]      = l;
551       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform   = ((bptr[0]<<1)&6) | (bptr[1]>>7);
552       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed      = (bptr[1]>>6)&1;
553       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note       = bptr[1]&0x3f;
554       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[2];
555       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[3];
556       bptr += 4;
557     }
558   }
559   
560   hvl_InitSubsong( ht, 0 );
561   free( buf );
562   return ht;
565 struct hvl_tune *hvl_LoadTune( TEXT *name, uint32 freq, uint32 defstereo )
567   struct hvl_tune *ht;
568   uint8  *buf, *bptr;
569   TEXT   *nptr;
570   uint32  buflen, i, j, posn, insn, ssn, chnn, hs, trkl, trkn;
571   // BPTR    lock, fh;
572   //struct  FileInfoBlock *fib;
573   struct  hvl_plsentry *ple;
574   FILE *f;
576   //fib = AllocDosObjectTags( DOS_FIB, TAG_DONE );
577   f = fopen( name, "rb" );
578   if( !f )
579   {
580     printf( "Cannot open file\n" );
581     return NULL;
582   }
583   fseek( f, 0, SEEK_END );
584   buflen = ftell( f );
585   rewind( f );
586   buf = malloc( buflen );
587   if( !buf )
588   {
589     close( f );
590     printf( "Out of memory!\n" );
591     return NULL;
592   }
594   if( fread( buf, 1, buflen, f ) != buflen )
595   {
596     free( buf );
597     fclose( f );
598     printf( "Unable to read from file!\n" );
599     return NULL;
600   }
601   fclose( f );
605   if( ( buf[0] == 'T' ) &&
606       ( buf[1] == 'H' ) &&
607       ( buf[2] == 'X' ) &&
608       ( buf[3] < 3 ) )
609     return hvl_load_ahx( buf, buflen, defstereo, freq );
611   if( ( buf[0] != 'H' ) ||
612       ( buf[1] != 'V' ) ||
613       ( buf[2] != 'L' ) ||
614       ( buf[3] > 0 ) )
615   {
616     free( buf );
617     printf( "Invalid file.\n" );
618     return NULL;
619   }
620   
621   posn = ((buf[6]&0x0f)<<8)|buf[7];
622   insn = buf[12];
623   ssn  = buf[13];
624   chnn = (buf[8]>>2)+4;
625   trkl = buf[10];
626   trkn = buf[11];
628   hs  = sizeof( struct hvl_tune );
629   hs += sizeof( struct hvl_position ) * posn;
630   hs += sizeof( struct hvl_instrument ) * (insn+1);
631   hs += sizeof( uint16 ) * ssn;
633   // Calculate the size of all instrument PList buffers
634   bptr = &buf[16];
635   bptr += ssn*2;       // Skip past the subsong list
636   bptr += posn*chnn*2; // Skip past the positions
637   
638   // Skip past the tracks
639   // 1.4: Fixed two really stupid bugs that cancelled each other
640   //      out if the module had a blank first track (which is how
641   //      come they were missed.
642   for( i=((buf[6]&0x80)==0x80)?1:0; i<=trkn; i++ )
643     for( j=0; j<trkl; j++ )
644     {
645       if( bptr[0] == 0x3f )
646       {
647         bptr++;
648         continue;
649       }
650       bptr += 5;
651     }
652   
653   // *NOW* we can finally calculate PList space
654   for( i=1; i<=insn; i++ )
655   {
656     hs += bptr[21] * sizeof( struct hvl_plsentry );
657     bptr += 22 + bptr[21]*5;
658   }
659   
660   ht = malloc(hs); // AllocVec( hs, MEMF_ANY );    
661   if( !ht )
662   {
663     free( buf );
664     printf( "Out of memory!\n" );
665     return NULL;
666   }
667   
668   ht->ht_Frequency       = freq;
669   ht->ht_FreqF           = (float64)freq;
670   
671   ht->ht_Positions       = (struct hvl_position *)(&ht[1]);
672   ht->ht_Instruments     = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
673   ht->ht_Subsongs        = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
674   ple                    = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
676   ht->ht_WaveformTab[0]  = &waves[WO_TRIANGLE_04];
677   ht->ht_WaveformTab[1]  = &waves[WO_SAWTOOTH_04];
678   ht->ht_WaveformTab[3]  = &waves[WO_WHITENOISE];
680   ht->ht_PositionNr      = posn;
681   ht->ht_Channels        = (buf[8]>>2)+4;
682   ht->ht_Restart         = ((buf[8]&3)<<8)|buf[9];
683   ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
684   ht->ht_TrackLength     = buf[10];
685   ht->ht_TrackNr         = buf[11];
686   ht->ht_InstrumentNr    = insn;
687   ht->ht_SubsongNr       = ssn;
688   ht->ht_mixgain         = (buf[14]<<8)/100;
689   ht->ht_defstereo       = buf[15];
690   ht->ht_defpanleft      = stereopan_left[ht->ht_defstereo];
691   ht->ht_defpanright     = stereopan_right[ht->ht_defstereo];
692   
693   if( ht->ht_Restart >= ht->ht_PositionNr )
694     ht->ht_Restart = ht->ht_PositionNr-1;
696   // Do some validation  
697   if( ( ht->ht_PositionNr > 1000 ) ||
698       ( ht->ht_TrackLength > 64 ) ||
699       ( ht->ht_InstrumentNr > 64 ) )
700   {
701     printf( "%d,%d,%d\n", ht->ht_PositionNr,
702                           ht->ht_TrackLength,
703                           ht->ht_InstrumentNr );
704     free( ht );
705     free( buf );
706     printf( "Invalid file.\n" );
707     return NULL;
708   }
710   strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
711   nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
713   bptr = &buf[16];
714   
715   // Subsongs
716   for( i=0; i<ht->ht_SubsongNr; i++ )
717   {
718     ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
719     bptr += 2;
720   }
721   
722   // Position list
723   for( i=0; i<ht->ht_PositionNr; i++ )
724   {
725     for( j=0; j<ht->ht_Channels; j++ )
726     {
727       ht->ht_Positions[i].pos_Track[j]     = *bptr++;
728       ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
729     }
730   }
731   
732   // Tracks
733   for( i=0; i<=ht->ht_TrackNr; i++ )
734   {
735     if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
736     {
737       for( j=0; j<ht->ht_TrackLength; j++ )
738       {
739         ht->ht_Tracks[i][j].stp_Note       = 0;
740         ht->ht_Tracks[i][j].stp_Instrument = 0;
741         ht->ht_Tracks[i][j].stp_FX         = 0;
742         ht->ht_Tracks[i][j].stp_FXParam    = 0;
743         ht->ht_Tracks[i][j].stp_FXb        = 0;
744         ht->ht_Tracks[i][j].stp_FXbParam   = 0;
745       }
746       continue;
747     }
748     
749     for( j=0; j<ht->ht_TrackLength; j++ )
750     {
751       if( bptr[0] == 0x3f )
752       {
753         ht->ht_Tracks[i][j].stp_Note       = 0;
754         ht->ht_Tracks[i][j].stp_Instrument = 0;
755         ht->ht_Tracks[i][j].stp_FX         = 0;
756         ht->ht_Tracks[i][j].stp_FXParam    = 0;
757         ht->ht_Tracks[i][j].stp_FXb        = 0;
758         ht->ht_Tracks[i][j].stp_FXbParam   = 0;
759         bptr++;
760         continue;
761       }
762       
763       ht->ht_Tracks[i][j].stp_Note       = bptr[0];
764       ht->ht_Tracks[i][j].stp_Instrument = bptr[1];
765       ht->ht_Tracks[i][j].stp_FX         = bptr[2]>>4;
766       ht->ht_Tracks[i][j].stp_FXParam    = bptr[3];
767       ht->ht_Tracks[i][j].stp_FXb        = bptr[2]&0xf;
768       ht->ht_Tracks[i][j].stp_FXbParam   = bptr[4];
769       bptr += 5;
770     }
771   }
772   
773   
774   // Instruments
775   for( i=1; i<=ht->ht_InstrumentNr; i++ )
776   {
777     if( nptr < (TEXT *)(buf+buflen) )
778     {
779       strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
780       nptr += strlen( nptr )+1;
781     } else {
782       ht->ht_Instruments[i].ins_Name[0] = 0;
783     }
784     ht->ht_Instruments[i].ins_Volume      = bptr[0];
785     ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
786     ht->ht_Instruments[i].ins_WaveLength  = bptr[1]&0x07;
788     ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
789     ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
790     ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
791     ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
792     ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
793     ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
794     ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
795     
796     ht->ht_Instruments[i].ins_FilterLowerLimit     = bptr[12]&0x7f;
797     ht->ht_Instruments[i].ins_VibratoDelay         = bptr[13];
798     ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
799     ht->ht_Instruments[i].ins_HardCutRelease       = bptr[14]&0x80?1:0;
800     ht->ht_Instruments[i].ins_VibratoDepth         = bptr[14]&0x0f;
801     ht->ht_Instruments[i].ins_VibratoSpeed         = bptr[15];
802     ht->ht_Instruments[i].ins_SquareLowerLimit     = bptr[16];
803     ht->ht_Instruments[i].ins_SquareUpperLimit     = bptr[17];
804     ht->ht_Instruments[i].ins_SquareSpeed          = bptr[18];
805     ht->ht_Instruments[i].ins_FilterUpperLimit     = bptr[19]&0x3f;
806     ht->ht_Instruments[i].ins_PList.pls_Speed      = bptr[20];
807     ht->ht_Instruments[i].ins_PList.pls_Length     = bptr[21];
808     
809     ht->ht_Instruments[i].ins_PList.pls_Entries    = ple;
810     ple += bptr[21];
811     
812     bptr += 22;
813     for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
814     {
815       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0] = bptr[0]&0xf;
816       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1] = (bptr[1]>>3)&0xf;
817       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform = bptr[1]&7;
818       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed = (bptr[2]>>6)&1;
819       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note  = bptr[2]&0x3f;
820       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[3];
821       ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[4];
822       bptr += 5;
823     }
824   }
825   
826   hvl_InitSubsong( ht, 0 );
827   free( buf );
828   return ht;
831 void hvl_FreeTune( struct hvl_tune *ht )
833   if( !ht ) return;
834   free( ht );
837 void hvl_process_stepfx_1( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
839   switch( FX )
840   {
841     case 0x0:  // Position Jump HI
842       if( ((FXParam&0x0f) > 0) && ((FXParam&0x0f) <= 9) )
843         ht->ht_PosJump = FXParam & 0xf;
844       break;
846     case 0x5:  // Volume Slide + Tone Portamento
847     case 0xa:  // Volume Slide
848       voice->vc_VolumeSlideDown = FXParam & 0x0f;
849       voice->vc_VolumeSlideUp   = FXParam >> 4;
850       break;
851     
852     case 0x7:  // Panning
853       if( FXParam > 127 )
854         FXParam -= 256;
855       voice->vc_Pan          = (FXParam+128);
856       voice->vc_SetPan       = (FXParam+128); // 1.4
857       voice->vc_PanMultLeft  = panning_left[voice->vc_Pan];
858       voice->vc_PanMultRight = panning_right[voice->vc_Pan];
859       break;
860     
861     case 0xb: // Position jump
862       ht->ht_PosJump      = ht->ht_PosJump*100 + (FXParam & 0x0f) + (FXParam >> 4)*10;
863       ht->ht_PatternBreak = 1;
864       if( ht->ht_PosJump <= ht->ht_PosNr )
865         ht->ht_SongEndReached = 1;
866       break;
867     
868     case 0xd: // Pattern break
869       ht->ht_PosJump      = ht->ht_PosNr+1;
870       ht->ht_PosJumpNote  = (FXParam & 0x0f) + (FXParam>>4)*10;
871       ht->ht_PatternBreak = 1;
872       if( ht->ht_PosJumpNote >  ht->ht_TrackLength )
873         ht->ht_PosJumpNote = 0;
874       break;
875     
876     case 0xe: // Extended commands
877       switch( FXParam >> 4 )
878       {
879         case 0xc: // Note cut
880           if( (FXParam & 0x0f) < ht->ht_Tempo )
881           {
882             voice->vc_NoteCutWait = FXParam & 0x0f;
883             if( voice->vc_NoteCutWait )
884             {
885               voice->vc_NoteCutOn      = 1;
886               voice->vc_HardCutRelease = 0;
887             }
888           }
889           break;
890         case 0xd: // Note delay
891           if( voice->vc_NoteDelayOn )
892           {
893             voice->vc_NoteDelayOn = 0;
894           } else {
895             if( (FXParam & 0x0f) < ht->ht_Tempo )
896             {
897               voice->vc_NoteDelayWait = FXParam & 0x0f;
898               if( voice->vc_NoteDelayWait )
899               {
900                 voice->vc_NoteDelayOn = 1;
901                 return;
902               }
903             }
904           }
905           break;
906       }
907       break;
908     
909     case 0xf: // Speed
910       ht->ht_Tempo = FXParam;
911       if( FXParam == 0 )
912         ht->ht_SongEndReached = 1;
913       break;
914   }  
917 void hvl_process_stepfx_2( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam, int32 *Note )
919   switch( FX )
920   {
921     case 0x9: // Set squarewave offset
922       voice->vc_SquarePos    = FXParam >> (5 - voice->vc_WaveLength);
923       voice->vc_PlantSquare  = 1;
924       voice->vc_IgnoreSquare = 1;
925       break;
926     
927     case 0x5: // Tone portamento + volume slide
928     case 0x3: // Tone portamento
929       if( FXParam != 0 ) voice->vc_PeriodSlideSpeed = FXParam;
930       
931       if( *Note )
932       {
933         int32 new, diff;
935         new   = period_tab[*Note];
936         diff  = period_tab[voice->vc_TrackPeriod];
937         diff -= new;
938         new   = diff + voice->vc_PeriodSlidePeriod;
939         
940         if( new )
941           voice->vc_PeriodSlideLimit = -diff;
942       }
943       voice->vc_PeriodSlideOn        = 1;
944       voice->vc_PeriodSlideWithLimit = 1;
945       *Note = 0;
946       break;      
947   } 
950 void hvl_process_stepfx_3( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
952   int32 i;
953   
954   switch( FX )
955   {
956     case 0x01: // Portamento up (period slide down)
957       voice->vc_PeriodSlideSpeed     = -FXParam;
958       voice->vc_PeriodSlideOn        = 1;
959       voice->vc_PeriodSlideWithLimit = 0;
960       break;
961     case 0x02: // Portamento down
962       voice->vc_PeriodSlideSpeed     = FXParam;
963       voice->vc_PeriodSlideOn        = 1;
964       voice->vc_PeriodSlideWithLimit = 0;
965       break;
966     case 0x04: // Filter override
967       if( ( FXParam == 0 ) || ( FXParam == 0x40 ) ) break;
968       if( FXParam < 0x40 )
969       {
970         voice->vc_IgnoreFilter = FXParam;
971         break;
972       }
973       if( FXParam > 0x7f ) break;
974       voice->vc_FilterPos = FXParam - 0x40;
975       break;
976     case 0x0c: // Volume
977       FXParam &= 0xff;
978       if( FXParam <= 0x40 )
979       {
980         voice->vc_NoteMaxVolume = FXParam;
981         break;
982       }
983       
984       FXParam -= 0x50;
985       if( FXParam <= 0x40 )
986       {
987         for( i=0; i<ht->ht_Channels; i++ )
988           ht->ht_Voices[i].vc_TrackMasterVolume = FXParam;
989         break;
990       }
991       
992       FXParam -= 0xa0-0x50;
993       if( FXParam <= 0x40 )
994         voice->vc_TrackMasterVolume = FXParam;
995       break;
997     case 0xe: // Extended commands;
998       switch( FXParam >> 4 )
999       {
1000         case 0x1: // Fineslide up
1001           voice->vc_PeriodSlidePeriod = -(FXParam & 0x0f);
1002           voice->vc_PlantPeriod = 1;
1003           break;
1004         
1005         case 0x2: // Fineslide down
1006           voice->vc_PeriodSlidePeriod = (FXParam & 0x0f);
1007           voice->vc_PlantPeriod = 1;
1008           break;
1009         
1010         case 0x4: // Vibrato control
1011           voice->vc_VibratoDepth = FXParam & 0x0f;
1012           break;
1013         
1014         case 0x0a: // Fine volume up
1015           voice->vc_NoteMaxVolume += FXParam & 0x0f;
1016           
1017           if( voice->vc_NoteMaxVolume > 0x40 )
1018             voice->vc_NoteMaxVolume = 0x40;
1019           break;
1020         
1021         case 0x0b: // Fine volume down
1022           voice->vc_NoteMaxVolume -= FXParam & 0x0f;
1023           
1024           if( voice->vc_NoteMaxVolume < 0 )
1025             voice->vc_NoteMaxVolume = 0;
1026           break;
1027       } 
1028       break;
1029   }
1032 void hvl_process_step( struct hvl_tune *ht, struct hvl_voice *voice )
1034   int32  Note, Instr;
1035   struct hvl_step *Step;
1036   
1037   if( voice->vc_TrackOn == 0 )
1038     return;
1039   
1040   voice->vc_VolumeSlideUp = voice->vc_VolumeSlideDown = 0;
1041   
1042   Step = &ht->ht_Tracks[ht->ht_Positions[ht->ht_PosNr].pos_Track[voice->vc_VoiceNum]][ht->ht_NoteNr];
1043   
1044   //Note    = Step->stp_Note;
1045   Note = 37;
1046   //Instr   = Step->stp_Instrument;
1047   Instr = 1;
1048   //hvl_process_stepfx_1( ht, voice, Step->stp_FX&0xf,  Step->stp_FXParam );  
1049   //hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
1050   
1051   if( ( Instr ) && ( Instr <= ht->ht_InstrumentNr ) )
1052   {
1053     struct hvl_instrument *Ins;
1054     int16  SquareLower, SquareUpper, d6, d3, d4;
1055     
1056     /* 1.4: Reset panning to last set position */
1057     voice->vc_Pan          = voice->vc_SetPan;
1058     voice->vc_PanMultLeft  = panning_left[voice->vc_Pan];
1059     voice->vc_PanMultRight = panning_right[voice->vc_Pan];
1061     voice->vc_PeriodSlideSpeed = voice->vc_PeriodSlidePeriod = voice->vc_PeriodSlideLimit = 0;
1063     voice->vc_PerfSubVolume    = 0x40;
1064     voice->vc_ADSRVolume       = 0;
1065     voice->vc_Instrument       = Ins = &ht->ht_Instruments[Instr];
1066     voice->vc_SamplePos        = 0;
1068     voice->vc_ADSR.aFrames     = Ins->ins_Envelope.aFrames;
1069     voice->vc_ADSR.aVolume     = Ins->ins_Envelope.aVolume*256/voice->vc_ADSR.aFrames;
1070     voice->vc_ADSR.dFrames     = Ins->ins_Envelope.dFrames;
1071     voice->vc_ADSR.dVolume     = (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume)*256/voice->vc_ADSR.dFrames;
1072     voice->vc_ADSR.sFrames     = Ins->ins_Envelope.sFrames;
1073     voice->vc_ADSR.rFrames     = Ins->ins_Envelope.rFrames;
1074     voice->vc_ADSR.rVolume     = (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume)*256/voice->vc_ADSR.rFrames;
1075     
1076     voice->vc_WaveLength       = Ins->ins_WaveLength;
1077     voice->vc_NoteMaxVolume    = Ins->ins_Volume;
1078     
1079     voice->vc_VibratoCurrent   = 0;
1080     voice->vc_VibratoDelay     = Ins->ins_VibratoDelay;
1081     voice->vc_VibratoDepth     = Ins->ins_VibratoDepth;
1082     voice->vc_VibratoSpeed     = Ins->ins_VibratoSpeed;
1083     voice->vc_VibratoPeriod    = 0;
1084     
1085     voice->vc_HardCutRelease   = Ins->ins_HardCutRelease;
1086     voice->vc_HardCut          = Ins->ins_HardCutReleaseFrames;
1087     
1088     voice->vc_IgnoreSquare = voice->vc_SquareSlidingIn = 0;
1089     voice->vc_SquareWait   = voice->vc_SquareOn        = 0;
1090     
1091     SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength);
1092     SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength);
1093     
1094     if( SquareUpper < SquareLower )
1095     {
1096       int16 t = SquareUpper;
1097       SquareUpper = SquareLower;
1098       SquareLower = t;
1099     }
1100     
1101     voice->vc_SquareUpperLimit = SquareUpper;
1102     voice->vc_SquareLowerLimit = SquareLower;
1103     
1104     //voice->vc_IgnoreFilter    = voice->vc_FilterWait = voice->vc_FilterOn = 0;
1105     //voice->vc_FilterSlidingIn = 0;
1107     d6 = Ins->ins_FilterSpeed;
1108     d3 = Ins->ins_FilterLowerLimit;
1109     d4 = Ins->ins_FilterUpperLimit;
1110     
1111     if( d3 & 0x80 ) d6 |= 0x20;
1112     if( d4 & 0x80 ) d6 |= 0x40;
1113     
1114     voice->vc_FilterSpeed = d6;
1115     d3 &= ~0x80;
1116     d4 &= ~0x80;
1117     
1118     if( d3 > d4 )
1119     {
1120       int16 t = d3;
1121       d3 = d4;
1122       d4 = t;
1123     }
1124     
1125     voice->vc_FilterUpperLimit = d4;
1126     voice->vc_FilterLowerLimit = d3;
1127     voice->vc_FilterPos        = 32;
1128     
1129     voice->vc_PerfWait  = voice->vc_PerfCurrent = 0;
1130     voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed;
1131     voice->vc_PerfList  = &voice->vc_Instrument->ins_PList;
1132     
1133     voice->vc_RingMixSource   = NULL;   // No ring modulation
1134     voice->vc_RingSamplePos   = 0;
1135     voice->vc_RingPlantPeriod = 0;
1136     voice->vc_RingNewWaveform = 0;
1137   }
1138   
1139   //voice->vc_PeriodSlideOn = 0;
1140   
1141   //hvl_process_stepfx_2( ht, voice, Step->stp_FX&0xf,  Step->stp_FXParam,  &Note );  
1142   //hvl_process_stepfx_2( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note );
1144   if( Note )
1145   {
1146     voice->vc_TrackPeriod = Note;
1147     voice->vc_PlantPeriod = 1;
1148   }
1149   
1150   //hvl_process_stepfx_3( ht, voice, Step->stp_FX&0xf,  Step->stp_FXParam );  
1151   //hvl_process_stepfx_3( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );  
1154 void hvl_plist_command_parse( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
1156   switch( FX )
1157   {
1158     case 0:
1159       if( ( FXParam > 0 ) && ( FXParam < 0x40 ) )
1160       {
1161         if( voice->vc_IgnoreFilter )
1162         {
1163           voice->vc_FilterPos    = voice->vc_IgnoreFilter;
1164           voice->vc_IgnoreFilter = 0;
1165         } else {
1166           voice->vc_FilterPos    = FXParam;
1167         }
1168         voice->vc_NewWaveform = 1;
1169       }
1170       break;
1172     case 1:
1173       voice->vc_PeriodPerfSlideSpeed = FXParam;
1174       voice->vc_PeriodPerfSlideOn    = 1;
1175       break;
1177     case 2:
1178       voice->vc_PeriodPerfSlideSpeed = -FXParam;
1179       voice->vc_PeriodPerfSlideOn    = 1;
1180       break;
1181     
1182     case 3:
1183       if( voice->vc_IgnoreSquare == 0 )
1184         voice->vc_SquarePos = FXParam >> (5-voice->vc_WaveLength);
1185       else
1186         voice->vc_IgnoreSquare = 0;
1187       break;
1188     
1189     case 4:
1190       if( FXParam == 0 )
1191       {
1192         voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
1193         voice->vc_SquareSign = 1;
1194       } else {
1196         if( FXParam & 0x0f )
1197         {
1198           voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
1199           voice->vc_SquareSign = 1;
1200           if(( FXParam & 0x0f ) == 0x0f )
1201             voice->vc_SquareSign = -1;
1202         }
1203         
1204         if( FXParam & 0xf0 )
1205         {
1206           voice->vc_FilterInit = (voice->vc_FilterOn ^= 1);
1207           voice->vc_FilterSign = 1;
1208           if(( FXParam & 0xf0 ) == 0xf0 )
1209             voice->vc_FilterSign = -1;
1210         }
1211       }
1212       break;
1213     
1214     case 5:
1215       voice->vc_PerfCurrent = FXParam;
1216       break;
1217     
1218     case 7:
1219       // Ring modulate with triangle
1220       if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
1221       {
1222         voice->vc_RingBasePeriod = FXParam;
1223         voice->vc_RingFixedPeriod = 1;
1224       } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
1225         voice->vc_RingBasePeriod = FXParam-0x80;
1226         voice->vc_RingFixedPeriod = 0;
1227       } else {
1228         voice->vc_RingBasePeriod = 0;
1229         voice->vc_RingFixedPeriod = 0;
1230         voice->vc_RingNewWaveform = 0;
1231         voice->vc_RingAudioSource = NULL; // turn it off
1232         voice->vc_RingMixSource   = NULL;
1233         break;
1234       }    
1235       voice->vc_RingWaveform    = 0;
1236       voice->vc_RingNewWaveform = 1;
1237       voice->vc_RingPlantPeriod = 1;
1238       break;
1239     
1240     case 8:  // Ring modulate with sawtooth
1241       if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
1242       {
1243         voice->vc_RingBasePeriod = FXParam;
1244         voice->vc_RingFixedPeriod = 1;
1245       } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
1246         voice->vc_RingBasePeriod = FXParam-0x80;
1247         voice->vc_RingFixedPeriod = 0;
1248       } else {
1249         voice->vc_RingBasePeriod = 0;
1250         voice->vc_RingFixedPeriod = 0;
1251         voice->vc_RingNewWaveform = 0;
1252         voice->vc_RingAudioSource = NULL;
1253         voice->vc_RingMixSource   = NULL;
1254         break;
1255       }
1257       voice->vc_RingWaveform    = 1;
1258       voice->vc_RingNewWaveform = 1;
1259       voice->vc_RingPlantPeriod = 1;
1260       break;
1262     /* New in HivelyTracker 1.4 */    
1263     case 9:    
1264       if( FXParam > 127 )
1265         FXParam -= 256;
1266       voice->vc_Pan          = (FXParam+128);
1267       voice->vc_PanMultLeft  = panning_left[voice->vc_Pan];
1268       voice->vc_PanMultRight = panning_right[voice->vc_Pan];
1269       break;
1271     case 12:
1272       if( FXParam <= 0x40 )
1273       {
1274         voice->vc_NoteMaxVolume = FXParam;
1275         break;
1276       }
1277       
1278       if( (FXParam -= 0x50) < 0 ) break;
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   } 
1298 void hvl_process_frame( struct hvl_tune *ht, struct hvl_voice *voice )
1300   static CONST uint8 Offsets[] = {0x00,0x04,0x04+0x08,0x04+0x08+0x10,0x04+0x08+0x10+0x20,0x04+0x08+0x10+0x20+0x40};
1302   if( voice->vc_TrackOn == 0 )
1303     return;
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;
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   }
1387   // VolumeSlide
1388   voice->vc_NoteMaxVolume = voice->vc_NoteMaxVolume + voice->vc_VolumeSlideUp - voice->vc_VolumeSlideDown;
1390   if( voice->vc_NoteMaxVolume < 0 )
1391     voice->vc_NoteMaxVolume = 0;
1392   else if( voice->vc_NoteMaxVolume > 0x40 )
1393     voice->vc_NoteMaxVolume = 0x40;
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;
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     }
1569     if( d3 < 1 )  d3 = 1;
1570     if( d3 > 63 ) d3 = 63;
1571     voice->vc_FilterPos   = d3;
1572     voice->vc_NewWaveform = 1;
1573     voice->vc_FilterWait  = voice->vc_FilterSpeed - 3;
1574     
1575     if( voice->vc_FilterWait < 1 )
1576       voice->vc_FilterWait = 1;
1577   }
1579   if( voice->vc_Waveform == 3-1 || voice->vc_PlantSquare )
1580   {
1581     // CalcSquare
1582     uint32  i;
1583     int32   Delta;
1584     int8   *SquarePtr;
1585     int32  X;
1586     
1587     SquarePtr = &waves[WO_SQUARES+(voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3)];
1588     X = voice->vc_SquarePos << (5 - voice->vc_WaveLength);
1589     
1590     if( X > 0x20 )
1591     {
1592       X = 0x40 - X;
1593       voice->vc_SquareReverse = 1;
1594     }
1595     
1596     // OkDownSquare
1597     if( X > 0 )
1598       SquarePtr += (X-1) << 7;
1599     
1600     Delta = 32 >> voice->vc_WaveLength;
1601     ht->ht_WaveformTab[2] = voice->vc_SquareTempBuffer;
1602     
1603     for( i=0; i<(1<<voice->vc_WaveLength)*4; i++ )
1604     {
1605       voice->vc_SquareTempBuffer[i] = *SquarePtr;
1606       SquarePtr += Delta;
1607     }
1608     
1609     voice->vc_NewWaveform = 1;
1610     voice->vc_Waveform    = 3-1;
1611     voice->vc_PlantSquare = 0;
1612   }
1613   
1614   if( voice->vc_Waveform == 4-1 )
1615     voice->vc_NewWaveform = 1;
1616   
1617   if( voice->vc_RingNewWaveform )
1618   {
1619     int8 *rasrc;
1620     
1621     if( voice->vc_RingWaveform > 1 ) voice->vc_RingWaveform = 1;
1622     
1623     rasrc = ht->ht_WaveformTab[voice->vc_RingWaveform];
1624     rasrc += Offsets[voice->vc_WaveLength];
1625     
1626     voice->vc_RingAudioSource = rasrc;
1627   }    
1628         
1629   if( voice->vc_NewWaveform )
1630   {
1631     int8 *AudioSource;
1633     AudioSource = ht->ht_WaveformTab[voice->vc_Waveform];
1635     if( voice->vc_Waveform != 3-1 )
1636       AudioSource += (voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3);
1638     if( voice->vc_Waveform < 3-1)
1639     {
1640       // GetWLWaveformlor2
1641       AudioSource += Offsets[voice->vc_WaveLength];
1642     }
1644     if( voice->vc_Waveform == 4-1 )
1645     {
1646       // AddRandomMoving
1647       AudioSource += ( voice->vc_WNRandom & (2*0x280-1) ) & ~1;
1648       // GoOnRandom
1649       voice->vc_WNRandom += 2239384;
1650       voice->vc_WNRandom  = ((((voice->vc_WNRandom >> 8) | (voice->vc_WNRandom << 24)) + 782323) ^ 75) - 6735;
1651     }
1653     voice->vc_AudioSource = AudioSource;
1654   }
1655   
1656   // Ring modulation period calculation
1657   if( voice->vc_RingAudioSource )
1658   {
1659     voice->vc_RingAudioPeriod = voice->vc_RingBasePeriod;
1660   
1661     if( !(voice->vc_RingFixedPeriod) )
1662       voice->vc_RingAudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
1663   
1664     if( voice->vc_RingAudioPeriod > 5*12 )
1665       voice->vc_RingAudioPeriod = 5*12;
1666   
1667     if( voice->vc_RingAudioPeriod < 0 )
1668       voice->vc_RingAudioPeriod = 0;
1669   
1670     voice->vc_RingAudioPeriod = period_tab[voice->vc_RingAudioPeriod];
1672     if( !(voice->vc_RingFixedPeriod) )
1673       voice->vc_RingAudioPeriod += voice->vc_PeriodSlidePeriod;
1675     voice->vc_RingAudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;
1677     if( voice->vc_RingAudioPeriod > 0x0d60 )
1678       voice->vc_RingAudioPeriod = 0x0d60;
1680     if( voice->vc_RingAudioPeriod < 0x0071 )
1681       voice->vc_RingAudioPeriod = 0x0071;
1682   }
1683   
1684   // Normal period calculation
1685   voice->vc_AudioPeriod = voice->vc_InstrPeriod;
1686   
1687   if( !(voice->vc_FixedNote) )
1688     voice->vc_AudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
1689     
1690   if( voice->vc_AudioPeriod > 5*12 )
1691     voice->vc_AudioPeriod = 5*12;
1692   
1693   if( voice->vc_AudioPeriod < 0 )
1694     voice->vc_AudioPeriod = 0;
1695   
1696   voice->vc_AudioPeriod = period_tab[voice->vc_AudioPeriod];
1697   
1698   if( !(voice->vc_FixedNote) )
1699     voice->vc_AudioPeriod += voice->vc_PeriodSlidePeriod;
1701   voice->vc_AudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;    
1703   if( voice->vc_AudioPeriod > 0x0d60 )
1704     voice->vc_AudioPeriod = 0x0d60;
1706   if( voice->vc_AudioPeriod < 0x0071 )
1707     voice->vc_AudioPeriod = 0x0071;
1708   
1709   voice->vc_AudioVolume = (((((((voice->vc_ADSRVolume >> 8) * voice->vc_NoteMaxVolume) >> 6) * voice->vc_PerfSubVolume) >> 6) * voice->vc_TrackMasterVolume) >> 6);
1712 void hvl_set_audio( struct hvl_voice *voice, float64 freqf )
1715   if( voice->vc_TrackOn == 0 )
1716   {
1717     voice->vc_VoiceVolume = 0;
1718     return;
1719   }
1720   
1721   voice->vc_VoiceVolume = voice->vc_AudioVolume;
1722   
1723   if( voice->vc_PlantPeriod )
1724   {
1725     float64 freq2;
1726     uint32  delta;
1727     
1728     voice->vc_PlantPeriod = 0;
1729     voice->vc_VoicePeriod = voice->vc_AudioPeriod;
1730     
1731     freq2 = Period2Freq( voice->vc_AudioPeriod );
1732     delta = (uint32)(freq2 / freqf);
1734     if( delta > (0x280<<16) ) delta -= (0x280<<16);
1735     if( delta == 0 ) delta = 1;
1736     voice->vc_Delta = delta;
1737   }
1738   
1739   if( voice->vc_NewWaveform )
1740   {
1741     int8 *src;
1742     
1743     src = voice->vc_AudioSource;
1744     
1745     if( voice->vc_Waveform == 4-1 )
1746     {
1747       //CopyMem((void *)src, &voice->vc_VoiceBuffer[0], 0x280);
1748       memcpy( &voice->vc_VoiceBuffer[0], (void *)src, 0x280);
1749     } else {
1750       uint32 i, WaveLoops;
1752       WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
1754       for( i=0; i<WaveLoops; i++ )
1755         //CopyMem((void *)src, &voice->vc_VoiceBuffer[i*4*(1<<voice->vc_WaveLength)], 4*(1<<voice->vc_WaveLength));
1756         memcpy( &voice->vc_VoiceBuffer[i*4*(1<<voice->vc_WaveLength)],
1757                 (void *)src,
1758                 4*(1<<voice->vc_WaveLength));
1759     }
1761     voice->vc_VoiceBuffer[0x280] = voice->vc_VoiceBuffer[0];
1762     voice->vc_MixSource          = voice->vc_VoiceBuffer;
1763   }
1765   /* Ring Modulation */
1766   if( voice->vc_RingPlantPeriod )
1767   {
1768     float64 freq2;
1769     uint32  delta;
1770     
1771     voice->vc_RingPlantPeriod = 0;
1772     freq2 = Period2Freq( voice->vc_RingAudioPeriod );
1773     delta = (uint32)(freq2 / freqf);
1775     if( delta > (0x280<<16) ) delta -= (0x280<<16);
1776     if( delta == 0 ) delta = 1;
1777     voice->vc_RingDelta = delta;
1778   }
1779   
1780   if( voice->vc_RingNewWaveform )
1781   {
1782     int8 *src;
1783     uint32 i, WaveLoops;
1784     
1785     src = voice->vc_RingAudioSource;
1787     WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
1789     for( i=0; i<WaveLoops; i++ )
1790       //CopyMem((void *)src, &voice->vc_RingVoiceBuffer[i*4*(1<<voice->vc_WaveLength)], 4*(1<<voice->vc_WaveLength));
1791      memcpy( &voice->vc_RingVoiceBuffer[i*4*(1<<voice->vc_WaveLength)],
1792               (void *)src,
1793               4*(1<<voice->vc_WaveLength));
1795     voice->vc_RingVoiceBuffer[0x280] = voice->vc_RingVoiceBuffer[0];
1796     voice->vc_RingMixSource          = voice->vc_RingVoiceBuffer;
1797   }
1800 void hvl_play_irq( struct hvl_tune *ht )
1802   uint32 i;
1804   if( ht->ht_StepWaitFrames <= 0 )
1805   {
1806     if( ht->ht_GetNewPosition )
1807     {
1808       int32 nextpos = (ht->ht_PosNr+1==ht->ht_PositionNr)?0:(ht->ht_PosNr+1);
1810       for( i=0; i<ht->ht_Channels; i++ )
1811       {
1812         ht->ht_Voices[i].vc_Track         = ht->ht_Positions[ht->ht_PosNr].pos_Track[i];
1813         ht->ht_Voices[i].vc_Transpose     = ht->ht_Positions[ht->ht_PosNr].pos_Transpose[i];
1814         ht->ht_Voices[i].vc_NextTrack     = ht->ht_Positions[nextpos].pos_Track[i];
1815         ht->ht_Voices[i].vc_NextTranspose = ht->ht_Positions[nextpos].pos_Transpose[i];
1816       }
1817       ht->ht_GetNewPosition = 0;
1818     }
1819     
1820     for( i=0; i<ht->ht_Channels; i++ )
1821       hvl_process_step( ht, &ht->ht_Voices[i] );
1822     
1823     ht->ht_StepWaitFrames = ht->ht_Tempo;
1824   }
1825   
1826   for( i=0; i<ht->ht_Channels; i++ )
1827     hvl_process_frame( ht, &ht->ht_Voices[i] );
1829   ht->ht_PlayingTime++;
1830   if( ht->ht_Tempo > 0 && --ht->ht_StepWaitFrames <= 0 )
1831   {
1832     if( !ht->ht_PatternBreak )
1833     {
1834       ht->ht_NoteNr++;
1835       if( ht->ht_NoteNr >= ht->ht_TrackLength )
1836       {
1837         ht->ht_PosJump      = ht->ht_PosNr+1;
1838         ht->ht_PosJumpNote  = 0;
1839         ht->ht_PatternBreak = 1;
1840       }
1841     }
1842     
1843     if( ht->ht_PatternBreak )
1844     {
1845       ht->ht_PatternBreak = 0;
1846       ht->ht_PosNr        = ht->ht_PosJump;
1847       ht->ht_NoteNr       = ht->ht_PosJumpNote;
1848       if( ht->ht_PosNr == ht->ht_PositionNr )
1849       {
1850         ht->ht_SongEndReached = 1;
1851         ht->ht_PosNr          = ht->ht_Restart;
1852       }
1853       ht->ht_PosJumpNote  = 0;
1854       ht->ht_PosJump      = 0;
1856       ht->ht_GetNewPosition = 1;
1857     }
1858   }
1860   for( i=0; i<ht->ht_Channels; i++ )
1861     hvl_set_audio( &ht->ht_Voices[i], ht->ht_Frequency );
1864 void hvl_mixchunk( struct hvl_tune *ht, uint32 samples, int8 *buf1, int8 *buf2, int32 bufmod )
1866   int8   *src[MAX_CHANNELS];
1867   int8   *rsrc[MAX_CHANNELS];
1868   uint32  delta[MAX_CHANNELS];
1869   uint32  rdelta[MAX_CHANNELS];
1870   int32   vol[MAX_CHANNELS];
1871   uint32  pos[MAX_CHANNELS];
1872   uint32  rpos[MAX_CHANNELS];
1873   uint32  cnt;
1874   int32   panl[MAX_CHANNELS];
1875   int32   panr[MAX_CHANNELS];
1876 //  uint32  vu[MAX_CHANNELS];
1877   int32   a=0, b=0, j;
1878   uint32  i, chans, loops;
1879   
1880   chans = ht->ht_Channels;
1881   for( i=0; i<chans; i++ )
1882   {
1883     delta[i] = ht->ht_Voices[i].vc_Delta;
1884     vol[i]   = ht->ht_Voices[i].vc_VoiceVolume;
1885     pos[i]   = ht->ht_Voices[i].vc_SamplePos;
1886     src[i]   = ht->ht_Voices[i].vc_MixSource;
1887     panl[i]  = ht->ht_Voices[i].vc_PanMultLeft;
1888     panr[i]  = ht->ht_Voices[i].vc_PanMultRight;
1889     
1890     /* Ring Modulation */
1891     rdelta[i]= ht->ht_Voices[i].vc_RingDelta;
1892     rpos[i]  = ht->ht_Voices[i].vc_RingSamplePos;
1893     rsrc[i]  = ht->ht_Voices[i].vc_RingMixSource;
1894     
1895 //    vu[i] = 0;
1896   }
1897   
1898   do
1899   {
1900     loops = samples;
1901     for( i=0; i<chans; i++ )
1902     {
1903       if( pos[i] >= (0x280 << 16)) pos[i] -= 0x280<<16;
1904       cnt = ((0x280<<16) - pos[i] - 1) / delta[i] + 1;
1905       if( cnt < loops ) loops = cnt;
1906       
1907       if( rsrc[i] )
1908       {
1909         if( rpos[i] >= (0x280<<16)) rpos[i] -= 0x280<<16;
1910         cnt = ((0x280<<16) - rpos[i] - 1) / rdelta[i] + 1;
1911         if( cnt < loops ) loops = cnt;
1912       }
1913       
1914     }
1915     
1916     samples -= loops;
1917     
1918     // Inner loop
1919     do
1920     {
1921       a=0;
1922       b=0;
1923       for( i=0; i<chans; i++ )
1924       {
1925         if( rsrc[i] )
1926         {
1927           /* Ring Modulation */
1928           j = ((src[i][pos[i]>>16]*rsrc[i][rpos[i]>>16])>>7)*vol[i];
1929           rpos[i] += rdelta[i];
1930         } else {
1931           j = src[i][pos[i]>>16]*vol[i];
1932         }
1933         
1934 //        if( abs( j ) > vu[i] ) vu[i] = abs( j );
1936         a += (j * panl[i]) >> 7;
1937         b += (j * panr[i]) >> 7;
1938         pos[i] += delta[i];
1939       }
1940       
1941       a = (a*ht->ht_mixgain)>>8;
1942       b = (b*ht->ht_mixgain)>>8;
1943       
1944       *(int16 *)buf1 = a;
1945       *(int16 *)buf2 = b;
1946       
1947       loops--;
1948       
1949       buf1 += bufmod;
1950       buf2 += bufmod;
1951     } while( loops > 0 );
1952   } while( samples > 0 );
1954   for( i=0; i<chans; i++ )
1955   {
1956     ht->ht_Voices[i].vc_SamplePos = pos[i];
1957     ht->ht_Voices[i].vc_RingSamplePos = rpos[i];
1958 //    ht->ht_Voices[i].vc_VUMeter = vu[i];
1959   }
1962 /*void hvl_DecodeFrame( struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod )
1964   uint32 samples, loops;
1965   
1966   samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
1967   loops   = ht->ht_SpeedMultiplier;
1969   do
1970   {
1971         hvl_play_irq( ht );
1972         hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
1973         buf1 += samples * 4;
1974         buf2 += samples * 4;
1975         loops--;
1976   } while( loops );
1979 void hvl_DecodeFrame( struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod )
1981   uint32 samples, loops;
1982   
1983   samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
1984   loops   = ht->ht_SpeedMultiplier;
1986   do {
1987   //uint32 i;
1989   //from hvl_play_irq
1990   //if( ht->ht_StepWaitFrames <= 0 )
1991   //{
1992     //if( ht->ht_GetNewPosition )
1993     //{
1994       //int32 nextpos = (ht->ht_PosNr+1==ht->ht_PositionNr)?0:(ht->ht_PosNr+1);
1996       /*for( i=0; i<ht->ht_Channels; i++ )
1997       {
1998         ht->ht_Voices[i].vc_Track         = ht->ht_Positions[ht->ht_PosNr].pos_Track[i];
1999         ht->ht_Voices[i].vc_Transpose     = ht->ht_Positions[ht->ht_PosNr].pos_Transpose[i];
2000         ht->ht_Voices[i].vc_NextTrack     = ht->ht_Positions[nextpos].pos_Track[i];
2001         ht->ht_Voices[i].vc_NextTranspose = ht->ht_Positions[nextpos].pos_Transpose[i];
2002       }
2003           */
2004      // ht->ht_GetNewPosition = 0;
2005     //}
2006     hvl_process_step( ht, &ht->ht_Voices[0] );
2007     //ht->ht_StepWaitFrames = ht->ht_Tempo;
2008   //}
2009   hvl_process_frame( ht, &ht->ht_Voices[0] );
2010   //if( ht->ht_Tempo > 0 && --ht->ht_StepWaitFrames <= 0 )
2011   //{
2012     //if( !ht->ht_PatternBreak )
2013     //{
2014       //ht->ht_NoteNr++;
2015       ht->ht_NoteNr = -1;
2016       /*if( ht->ht_NoteNr >= ht->ht_TrackLength )
2017       {
2018         ht->ht_PosJump      = ht->ht_PosNr+1;
2019         ht->ht_PosJumpNote  = 0;
2020         ht->ht_PatternBreak = 1;
2021       }
2022           */
2023     //}
2024     
2025     /*if( ht->ht_PatternBreak )
2026     {
2027       ht->ht_PatternBreak = 0;
2028       ht->ht_PosNr        = ht->ht_PosJump;
2029       ht->ht_NoteNr       = ht->ht_PosJumpNote;
2030       if( ht->ht_PosNr == ht->ht_PositionNr )
2031       {
2032         ht->ht_SongEndReached = 1;
2033         ht->ht_PosNr          = ht->ht_Restart;
2034       }
2035       ht->ht_PosJumpNote  = 0;
2036       ht->ht_PosJump      = 0;
2038       ht->ht_GetNewPosition = 1;
2039     }
2040         */
2041   //}
2042   //hvl_process_step( ht, &ht->ht_Voices[0] );
2043   //hvl_process_frame( ht, &ht->ht_Voices[0] );
2044   hvl_set_audio( &ht->ht_Voices[0], ht->ht_Frequency );
2045   hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
2046   buf1 += samples * 4;
2047   buf2 += samples * 4;
2048   loops--;
2049   } while (loops);
2050   /*do
2051   {
2052     hvl_play_irq( ht );
2053     hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
2054     buf1 += samples * 4;
2055     buf2 += samples * 4;
2056     loops--;
2057   } while( loops );
2058   */