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