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