Timing is correct now! Forgot to update samples_per_tick when parsing the 0xf effect.
[pineappletracker.git] / hvl_replay.c
blob6b8ae4fd3a1f72933e5802468cab403d27992c91
1 /* AHX originally by Pink/Abyss and bigup Xeron for Hivelytracker! */
3 /*
4 ** Changes for the 1.4 release are commented. You can do
5 ** a search for "1.4" and merge them into your own replay
6 ** code.
7 **
8 ** Changes for 1.5 are marked also.
9 **
10 ** ... as are those for 1.6
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <math.h>
19 #include "hvl_replay.h"
20 #include "pineapple.h"
22 int32 stereopan_left[] = { 128, 96, 64, 32, 0 };
23 int32 stereopan_right[] = { 128, 160, 193, 225, 255 };
26 ** Waves
28 #define WHITENOISELEN (0x280*3)
30 #define WO_LOWPASSES 0
31 #define WO_TRIANGLE_04 (WO_LOWPASSES+((0xfc+0xfc+0x80*0x1f+0x80+3*0x280)*31))
32 #define WO_TRIANGLE_08 (WO_TRIANGLE_04+0x04)
33 #define WO_TRIANGLE_10 (WO_TRIANGLE_08+0x08)
34 #define WO_TRIANGLE_20 (WO_TRIANGLE_10+0x10)
35 #define WO_TRIANGLE_40 (WO_TRIANGLE_20+0x20)
36 #define WO_TRIANGLE_80 (WO_TRIANGLE_40+0x40)
37 #define WO_SAWTOOTH_04 (WO_TRIANGLE_80+0x80)
38 #define WO_SAWTOOTH_08 (WO_SAWTOOTH_04+0x04)
39 #define WO_SAWTOOTH_10 (WO_SAWTOOTH_08+0x08)
40 #define WO_SAWTOOTH_20 (WO_SAWTOOTH_10+0x10)
41 #define WO_SAWTOOTH_40 (WO_SAWTOOTH_20+0x20)
42 #define WO_SAWTOOTH_80 (WO_SAWTOOTH_40+0x40)
43 #define WO_SQUARES (WO_SAWTOOTH_80+0x80)
44 #define WO_WHITENOISE (WO_SQUARES+(0x80*0x20))
45 #define WO_HIGHPASSES (WO_WHITENOISE+WHITENOISELEN)
46 #define WAVES_SIZE (WO_HIGHPASSES+((0xfc+0xfc+0x80*0x1f+0x80+3*0x280)*31))
48 int8 waves[WAVES_SIZE];
49 int16 waves2[WAVES_SIZE];
51 int16 vib_tab[] = {
52 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
53 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
54 0,-24,-49,-74,-97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,-255,
55 -253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,-97,-74,-49,-24
58 uint16 period_tab[] = {
59 0x0000, 0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970,
60 0x08E8, 0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4,
61 0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0,
62 0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C,
63 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D,
64 0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0,
65 0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097,
66 0x008F, 0x0087, 0x007F, 0x0078, 0x0071
69 uint32 panning_left[256], panning_right[256];
71 void hvl_GenPanningTables(void){
72 uint32 i;
73 float64 aa, ab;
75 // Sine based panning table
76 aa = (3.14159265f*2.0f)/4.0f; // Quarter of the way through the sinewave == top peak
77 ab = 0.0f; // Start of the climb from zero
79 for( i=0; i<256; i++ ){
80 panning_left[i] = (uint32)(sin(aa)*255.0f);
81 panning_right[i] = (uint32)(sin(ab)*255.0f);
83 aa += (3.14159265*2.0f/4.0f)/256.0f;
84 ab += (3.14159265*2.0f/4.0f)/256.0f;
86 panning_left[255] = 0;
87 panning_right[0] = 0;
90 void hvl_GenSawtooth(int8 *buf, uint32 len){
91 uint32 i;
92 int32 val, add;
94 add = 256 / (len-1);
95 val = -128;
97 for( i=0; i<len; i++, val += add )
98 *buf++ = (int8)val;
101 void hvl_GenTriangle( int8 *buf, uint32 len )
103 uint32 i;
104 int32 d2, d5, d1, d4;
105 int32 val;
106 int8 *buf2;
108 d2 = len;
109 d5 = len >> 2;
110 d1 = 128/d5;
111 d4 = -(d2 >> 1);
112 val = 0;
114 for( i=0; i<d5; i++ )
116 *buf++ = val;
117 val += d1;
119 *buf++ = 0x7f;
121 if( d5 != 1 )
123 val = 128;
124 for( i=0; i<d5-1; i++ )
126 val -= d1;
127 *buf++ = val;
131 buf2 = buf + d4;
132 for( i=0; i<d5*2; i++ )
134 int8 c;
136 c = *buf2++;
137 if( c == 0x7f )
138 c = 0x80;
139 else
140 c = -c;
142 *buf++ = c;
146 void hvl_GenSquare( int8 *buf )
148 uint32 i, j;
150 for( i=1; i<=0x20; i++ )
152 for( j=0; j<(0x40-i)*2; j++ )
153 *buf++ = 0x80;
154 for( j=0; j<i*2; j++ )
155 *buf++ = 0x7f;
159 static inline float64 clip( float64 x )
161 if( x > 127.f )
162 x = 127.f;
163 else if( x < -128.f )
164 x = -128.f;
165 return x;
168 void hvl_GenFilterWaves( int8 *buf, int8 *lowbuf, int8 *highbuf )
170 static const uint16 lentab[45] = { 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 3, 7, 0xf, 0x1f, 0x3f, 0x7f,
171 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
172 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
173 (0x280*3)-1 };
175 float64 freq;
176 uint32 temp;
178 for( temp=0, freq=8.f; temp<31; temp++, freq+=3.f )
180 uint32 wv;
181 int8 *a0 = buf;
183 for( wv=0; wv<6+6+0x20+1; wv++ )
185 float64 fre, high, mid, low;
186 uint32 i;
188 mid = 0.f;
189 low = 0.f;
190 fre = freq * 1.25f / 100.0f;
192 for( i=0; i<=lentab[wv]; i++ )
194 high = a0[i] - mid - low;
195 high = clip( high );
196 mid += high * fre;
197 mid = clip( mid );
198 low += mid * fre;
199 low = clip( low );
202 for( i=0; i<=lentab[wv]; i++ )
204 high = a0[i] - mid - low;
205 high = clip( high );
206 mid += high * fre;
207 mid = clip( mid );
208 low += mid * fre;
209 low = clip( low );
210 *lowbuf++ = (int8)low;
211 *highbuf++ = (int8)high;
214 a0 += lentab[wv]+1;
219 void hvl_GenWhiteNoise( int8 *buf, uint32 len )
221 uint32 ays;
223 ays = 0x41595321;
225 do {
226 uint16 ax, bx;
227 int8 s;
229 s = ays;
231 if( ays & 0x100 )
233 s = 0x80;
235 if( (int32)(ays & 0xffff) >= 0 )
236 s = 0x7f;
239 *buf++ = s;
240 len--;
242 ays = (ays >> 5) | (ays << 27);
243 ays = (ays & 0xffffff00) | ((ays & 0xff) ^ 0x9a);
244 bx = ays;
245 ays = (ays << 2) | (ays >> 30);
246 ax = ays;
247 bx += ax;
248 ax ^= bx;
249 ays = (ays & 0xffff0000) | ax;
250 ays = (ays >> 3) | (ays << 29);
251 } while( len );
254 void hvl_reset_some_stuff( struct hvl_tune *ht )
256 uint32 i;
258 for( i=0; i<MAX_CHANNELS; i++ )
260 ht->ht_Voices[i].vc_Delta=1;
261 ht->ht_Voices[i].vc_OverrideTranspose=1000; // 1.5
262 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;
263 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;
264 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;
265 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;
266 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;
267 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;
268 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;
269 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;
270 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;
271 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;
272 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;
273 ht->ht_Voices[i].vc_PerfList=0;
274 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;
276 ht->ht_Voices[i].vc_RingMixSource = NULL;
277 ht->ht_Voices[i].vc_RingAudioSource = NULL;
279 memset(&ht->ht_Voices[i].vc_SquareTempBuffer,0,0x80);
280 memset(&ht->ht_Voices[i].vc_ADSR,0,sizeof(struct hvl_envelope));
281 memset(&ht->ht_Voices[i].vc_VoiceBuffer,0,0x281);
282 memset(&ht->ht_Voices[i].vc_RingVoiceBuffer,0,0x281);
285 for( i=0; i<MAX_CHANNELS; i++ )
287 ht->ht_Voices[i].vc_WNRandom = 0x280;
288 ht->ht_Voices[i].vc_VoiceNum = i;
289 ht->ht_Voices[i].vc_TrackMasterVolume = 0x40;
290 ht->ht_Voices[i].vc_TrackOn = 1;
291 ht->ht_Voices[i].vc_MixSource = ht->ht_Voices[i].vc_VoiceBuffer;
295 BOOL hvl_InitSubsong( struct hvl_tune *ht, uint32 nr )
297 uint32 PosNr, i;
299 if( nr > ht->ht_SubsongNr )
300 return FALSE;
302 ht->ht_SongNum = nr;
304 PosNr = 0;
305 if( nr ) PosNr = ht->ht_Subsongs[nr-1];
307 tune->songpos = PosNr;
308 ht->ht_PosJump = 0;
309 ht->ht_PatternBreak = 0;
310 ht->ht_NoteNr = 0;
311 ht->ht_PosJumpNote = 0;
312 ht->ht_Tempo = 6;
313 ht->ht_StepWaitFrames = 0;
314 ht->ht_GetNewPosition = 1;
315 ht->ht_SongEndReached = 0;
316 ht->ht_PlayingTime = 0;
318 for( i=0; i<MAX_CHANNELS; i+=4 )
320 ht->ht_Voices[i+0].vc_Pan = ht->ht_defpanleft;
321 ht->ht_Voices[i+0].vc_SetPan = ht->ht_defpanleft; // 1.4
322 ht->ht_Voices[i+0].vc_PanMultLeft = panning_left[ht->ht_defpanleft];
323 ht->ht_Voices[i+0].vc_PanMultRight = panning_right[ht->ht_defpanleft];
324 ht->ht_Voices[i+1].vc_Pan = ht->ht_defpanright;
325 ht->ht_Voices[i+1].vc_SetPan = ht->ht_defpanright; // 1.4
326 ht->ht_Voices[i+1].vc_PanMultLeft = panning_left[ht->ht_defpanright];
327 ht->ht_Voices[i+1].vc_PanMultRight = panning_right[ht->ht_defpanright];
328 ht->ht_Voices[i+2].vc_Pan = ht->ht_defpanright;
329 ht->ht_Voices[i+2].vc_SetPan = ht->ht_defpanright; // 1.4
330 ht->ht_Voices[i+2].vc_PanMultLeft = panning_left[ht->ht_defpanright];
331 ht->ht_Voices[i+2].vc_PanMultRight = panning_right[ht->ht_defpanright];
332 ht->ht_Voices[i+3].vc_Pan = ht->ht_defpanleft;
333 ht->ht_Voices[i+3].vc_SetPan = ht->ht_defpanleft; // 1.4
334 ht->ht_Voices[i+3].vc_PanMultLeft = panning_left[ht->ht_defpanleft];
335 ht->ht_Voices[i+3].vc_PanMultRight = panning_right[ht->ht_defpanleft];
338 hvl_reset_some_stuff( ht );
340 return TRUE;
343 void hvl_InitReplayer( void )
345 hvl_GenPanningTables();
346 hvl_GenSawtooth( &waves[WO_SAWTOOTH_04], 0x04 );
347 hvl_GenSawtooth( &waves[WO_SAWTOOTH_08], 0x08 );
348 hvl_GenSawtooth( &waves[WO_SAWTOOTH_10], 0x10 );
349 hvl_GenSawtooth( &waves[WO_SAWTOOTH_20], 0x20 );
350 hvl_GenSawtooth( &waves[WO_SAWTOOTH_40], 0x40 );
351 hvl_GenSawtooth( &waves[WO_SAWTOOTH_80], 0x80 );
352 hvl_GenTriangle( &waves[WO_TRIANGLE_04], 0x04 );
353 hvl_GenTriangle( &waves[WO_TRIANGLE_08], 0x08 );
354 hvl_GenTriangle( &waves[WO_TRIANGLE_10], 0x10 );
355 hvl_GenTriangle( &waves[WO_TRIANGLE_20], 0x20 );
356 hvl_GenTriangle( &waves[WO_TRIANGLE_40], 0x40 );
357 hvl_GenTriangle( &waves[WO_TRIANGLE_80], 0x80 );
358 hvl_GenSquare( &waves[WO_SQUARES] );
359 hvl_GenWhiteNoise( &waves[WO_WHITENOISE], WHITENOISELEN );
360 hvl_GenFilterWaves( &waves[WO_TRIANGLE_04], &waves[WO_LOWPASSES], &waves[WO_HIGHPASSES] );
363 struct hvl_tune *hvl_load_ahx( uint8 *buf, uint32 buflen, uint32 defstereo, uint32 freq )
365 uint8 *bptr;
366 TEXT *nptr;
367 uint32 i, j, k, l, posn, insn, ssn, hs, trkn, trkl;
368 struct hvl_tune *ht;
369 struct hvl_plsentry *ple;
370 int32 defgain[] = { 71, 72, 76, 85, 100 };
372 posn = ((buf[6]&0x0f)<<8)|buf[7];
373 insn = buf[12];
374 ssn = buf[13];
375 trkl = buf[10];
376 trkn = buf[11];
378 hs = sizeof( struct hvl_tune );
379 hs += sizeof( struct hvl_position ) * posn;
380 hs += sizeof( struct hvl_instrument ) * (insn+1);
381 hs += sizeof( uint16 ) * ssn;
383 // Calculate the size of all instrument PList buffers
384 bptr = &buf[14];
385 bptr += ssn*2; // Skip past the subsong list
386 bptr += posn*4*2; // Skip past the positions
387 bptr += trkn*trkl*3;
388 if((buf[6]&0x80)==0) bptr += trkl*3;
390 // *NOW* we can finally calculate PList space
391 for( i=1; i<=insn; i++ )
393 hs += bptr[21] * sizeof( struct hvl_plsentry );
394 bptr += 22 + bptr[21]*4;
397 ht = malloc( hs );
398 if( !ht )
400 free( buf );
401 printf( "Out of memory!\n" );
402 return NULL;
405 ht->ht_Frequency = freq;
406 ht->ht_FreqF = (float64)freq;
408 ht->ht_Positions = (struct hvl_position *)(&ht[1]);
409 ht->ht_Instruments = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
410 ht->ht_Subsongs = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
411 ple = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
413 ht->ht_WaveformTab[0] = &waves[WO_TRIANGLE_04];
414 ht->ht_WaveformTab[1] = &waves[WO_SAWTOOTH_04];
415 ht->ht_WaveformTab[3] = &waves[WO_WHITENOISE];
417 ht->ht_Channels = 4;
418 ht->ht_PositionNr = posn;
419 ht->ht_Restart = (buf[8]<<8)|buf[9];
420 ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
421 ht->ht_TrackLength = trkl;
422 ht->ht_TrackNr = trkn;
423 ht->ht_InstrumentNr = insn;
424 ht->ht_SubsongNr = ssn;
425 ht->ht_defstereo = defstereo;
426 ht->ht_defpanleft = stereopan_left[ht->ht_defstereo];
427 ht->ht_defpanright = stereopan_right[ht->ht_defstereo];
428 ht->ht_mixgain = (defgain[ht->ht_defstereo]*256)/100;
430 if( ht->ht_Restart >= ht->ht_PositionNr )
431 ht->ht_Restart = ht->ht_PositionNr-1;
433 // Do some validation
434 if( ( ht->ht_PositionNr > 1000 ) ||
435 ( ht->ht_TrackLength > 64 ) ||
436 ( ht->ht_InstrumentNr > 64 ) )
438 printf( "%d,%d,%d\n", ht->ht_PositionNr,
439 ht->ht_TrackLength,
440 ht->ht_InstrumentNr );
441 free( ht );
442 free( buf );
443 printf( "Invalid file.\n" );
444 return NULL;
447 strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
448 nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
450 bptr = &buf[14];
452 // Subsongs
453 for( i=0; i<ht->ht_SubsongNr; i++ )
455 ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
456 if( ht->ht_Subsongs[i] >= ht->ht_PositionNr )
457 ht->ht_Subsongs[i] = 0;
458 bptr += 2;
461 // Position list
462 for( i=0; i<ht->ht_PositionNr; i++ )
464 for( j=0; j<4; j++ )
466 ht->ht_Positions[i].pos_Track[j] = *bptr++;
467 ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
471 // Tracks
472 for( i=0; i<=ht->ht_TrackNr; i++ )
474 if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
476 for( j=0; j<ht->ht_TrackLength; j++ )
478 ht->ht_Tracks[i][j].stp_Note = 0;
479 ht->ht_Tracks[i][j].stp_Instrument = 0;
480 ht->ht_Tracks[i][j].stp_FX = 0;
481 ht->ht_Tracks[i][j].stp_FXParam = 0;
482 ht->ht_Tracks[i][j].stp_FXb = 0;
483 ht->ht_Tracks[i][j].stp_FXbParam = 0;
485 continue;
488 for( j=0; j<ht->ht_TrackLength; j++ )
490 ht->ht_Tracks[i][j].stp_Note = (bptr[0]>>2)&0x3f;
491 ht->ht_Tracks[i][j].stp_Instrument = ((bptr[0]&0x3)<<4) | (bptr[1]>>4);
492 ht->ht_Tracks[i][j].stp_FX = bptr[1]&0xf;
493 ht->ht_Tracks[i][j].stp_FXParam = bptr[2];
494 ht->ht_Tracks[i][j].stp_FXb = 0;
495 ht->ht_Tracks[i][j].stp_FXbParam = 0;
496 bptr += 3;
500 // Instruments
501 for( i=1; i<=ht->ht_InstrumentNr; i++ )
503 if( nptr < (TEXT *)(buf+buflen) )
505 strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
506 nptr += strlen( nptr )+1;
507 } else {
508 ht->ht_Instruments[i].ins_Name[0] = 0;
511 ht->ht_Instruments[i].ins_Volume = bptr[0];
512 ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
513 ht->ht_Instruments[i].ins_WaveLength = bptr[1]&0x07;
515 ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
516 ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
517 ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
518 ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
519 ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
520 ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
521 ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
523 ht->ht_Instruments[i].ins_FilterLowerLimit = bptr[12]&0x7f;
524 ht->ht_Instruments[i].ins_VibratoDelay = bptr[13];
525 ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
526 ht->ht_Instruments[i].ins_HardCutRelease = bptr[14]&0x80?1:0;
527 ht->ht_Instruments[i].ins_VibratoDepth = bptr[14]&0x0f;
528 ht->ht_Instruments[i].ins_VibratoSpeed = bptr[15];
529 ht->ht_Instruments[i].ins_SquareLowerLimit = bptr[16];
530 ht->ht_Instruments[i].ins_SquareUpperLimit = bptr[17];
531 ht->ht_Instruments[i].ins_SquareSpeed = bptr[18];
532 ht->ht_Instruments[i].ins_FilterUpperLimit = bptr[19]&0x3f;
533 ht->ht_Instruments[i].ins_PList.pls_Speed = bptr[20];
534 ht->ht_Instruments[i].ins_PList.pls_Length = bptr[21];
536 ht->ht_Instruments[i].ins_PList.pls_Entries = ple;
537 ple += bptr[21];
539 bptr += 22;
540 for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
542 k = (bptr[0]>>5)&7;
543 if( k == 6 ) k = 12;
544 if( k == 7 ) k = 15;
545 l = (bptr[0]>>2)&7;
546 if( l == 6 ) l = 12;
547 if( l == 7 ) l = 15;
548 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1] = k;
549 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0] = l;
550 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform = ((bptr[0]<<1)&6) | (bptr[1]>>7);
551 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed = (bptr[1]>>6)&1;
552 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note = bptr[1]&0x3f;
553 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[2];
554 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[3];
556 // 1.6: Strip "toggle filter" commands if the module is
557 // version 0 (pre-filters). This is what AHX also does.
558 if( ( buf[3] == 0 ) && ( l == 4 ) && ( (bptr[2]&0xf0) != 0 ) )
559 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] &= 0x0f;
560 if( ( buf[3] == 0 ) && ( k == 4 ) && ( (bptr[3]&0xf0) != 0 ) )
561 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] &= 0x0f;
563 bptr += 4;
567 //hvl_InitSubsong( ht, 0 );
568 free( buf );
569 return ht;
572 struct hvl_tune *hvl_LoadTune( TEXT *name, uint32 freq, uint32 defstereo )
574 struct hvl_tune *ht;
575 uint8 *buf, *bptr;
576 TEXT *nptr;
577 uint32 buflen, i, j, posn, insn, ssn, chnn, hs, trkl, trkn;
578 FILE *fh;
579 struct hvl_plsentry *ple;
581 fh = fopen( name, "rb" );
582 if( !fh )
584 printf( "Can't open file\n" );
585 return NULL;
588 fseek( fh, 0, SEEK_END );
589 buflen = ftell( fh );
590 fseek( fh, 0, SEEK_SET );
592 buf = malloc( buflen );
593 if( !buf )
595 fclose( fh );
596 printf( "Out of memory!\n" );
597 return NULL;
600 if( fread( buf, 1, buflen, fh ) != buflen )
602 fclose( fh );
603 free( buf );
604 printf( "Unable to read from file!\n" );
605 return NULL;
607 fclose( fh );
609 if( ( buf[0] == 'T' ) &&
610 ( buf[1] == 'H' ) &&
611 ( buf[2] == 'X' ) &&
612 ( buf[3] < 3 ) )
613 return hvl_load_ahx( buf, buflen, defstereo, freq );
615 if( ( buf[0] != 'H' ) ||
616 ( buf[1] != 'V' ) ||
617 ( buf[2] != 'L' ) ||
618 ( buf[3] > 1 ) )
620 free( buf );
621 printf( "Invalid file.\n" );
622 return NULL;
625 posn = ((buf[6]&0x0f)<<8)|buf[7];
626 insn = buf[12];
627 ssn = buf[13];
628 chnn = (buf[8]>>2)+4;
629 trkl = buf[10];
630 trkn = buf[11];
632 hs = sizeof( struct hvl_tune );
633 hs += sizeof( struct hvl_position ) * posn;
634 hs += sizeof( struct hvl_instrument ) * (insn+1);
635 hs += sizeof( uint16 ) * ssn;
637 // Calculate the size of all instrument PList buffers
638 bptr = &buf[16];
639 bptr += ssn*2; // Skip past the subsong list
640 bptr += posn*chnn*2; // Skip past the positions
642 // Skip past the tracks
643 // 1.4: Fixed two really stupid bugs that cancelled each other
644 // out if the module had a blank first track (which is how
645 // come they were missed.
646 for( i=((buf[6]&0x80)==0x80)?1:0; i<=trkn; i++ )
647 for( j=0; j<trkl; j++ )
649 if( bptr[0] == 0x3f )
651 bptr++;
652 continue;
654 bptr += 5;
657 // *NOW* we can finally calculate PList space
658 for( i=1; i<=insn; i++ )
660 hs += bptr[21] * sizeof( struct hvl_plsentry );
661 bptr += 22 + bptr[21]*5;
664 ht = malloc( hs );
665 if( !ht )
667 free( buf );
668 printf( "Out of memory!\n" );
669 return NULL;
672 ht->ht_Version = buf[3]; // 1.5
673 ht->ht_Frequency = freq;
674 ht->ht_FreqF = (float64)freq;
676 ht->ht_Positions = (struct hvl_position *)(&ht[1]);
677 ht->ht_Instruments = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
678 ht->ht_Subsongs = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
679 ple = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
681 ht->ht_WaveformTab[0] = &waves[WO_TRIANGLE_04];
682 ht->ht_WaveformTab[1] = &waves[WO_SAWTOOTH_04];
683 ht->ht_WaveformTab[3] = &waves[WO_WHITENOISE];
685 ht->ht_PositionNr = posn;
686 ht->ht_Channels = (buf[8]>>2)+4;
687 ht->ht_Restart = ((buf[8]&3)<<8)|buf[9];
688 ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
689 ht->ht_TrackLength = buf[10];
690 ht->ht_TrackNr = buf[11];
691 ht->ht_InstrumentNr = insn;
692 ht->ht_SubsongNr = ssn;
693 ht->ht_mixgain = (buf[14]<<8)/100;
694 ht->ht_defstereo = buf[15];
695 ht->ht_defpanleft = stereopan_left[ht->ht_defstereo];
696 ht->ht_defpanright = stereopan_right[ht->ht_defstereo];
698 if( ht->ht_Restart >= ht->ht_PositionNr )
699 ht->ht_Restart = ht->ht_PositionNr-1;
701 // Do some validation
702 if( ( ht->ht_PositionNr > 1000 ) ||
703 ( ht->ht_TrackLength > 64 ) ||
704 ( ht->ht_InstrumentNr > 64 ) )
706 printf( "%d,%d,%d\n", ht->ht_PositionNr,
707 ht->ht_TrackLength,
708 ht->ht_InstrumentNr );
709 free( ht );
710 free( buf );
711 printf( "Invalid file.\n" );
712 return NULL;
715 strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
716 nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
718 bptr = &buf[16];
720 // Subsongs
721 for( i=0; i<ht->ht_SubsongNr; i++ )
723 ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
724 bptr += 2;
727 // Position list
728 for( i=0; i<ht->ht_PositionNr; i++ )
730 for( j=0; j<ht->ht_Channels; j++ )
732 ht->ht_Positions[i].pos_Track[j] = *bptr++;
733 ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
737 // Tracks
738 for( i=0; i<=ht->ht_TrackNr; i++ )
740 if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
742 for( j=0; j<ht->ht_TrackLength; j++ )
744 ht->ht_Tracks[i][j].stp_Note = 0;
745 ht->ht_Tracks[i][j].stp_Instrument = 0;
746 ht->ht_Tracks[i][j].stp_FX = 0;
747 ht->ht_Tracks[i][j].stp_FXParam = 0;
748 ht->ht_Tracks[i][j].stp_FXb = 0;
749 ht->ht_Tracks[i][j].stp_FXbParam = 0;
751 continue;
754 for( j=0; j<ht->ht_TrackLength; j++ )
756 if( bptr[0] == 0x3f )
758 ht->ht_Tracks[i][j].stp_Note = 0;
759 ht->ht_Tracks[i][j].stp_Instrument = 0;
760 ht->ht_Tracks[i][j].stp_FX = 0;
761 ht->ht_Tracks[i][j].stp_FXParam = 0;
762 ht->ht_Tracks[i][j].stp_FXb = 0;
763 ht->ht_Tracks[i][j].stp_FXbParam = 0;
764 bptr++;
765 continue;
768 ht->ht_Tracks[i][j].stp_Note = bptr[0];
769 ht->ht_Tracks[i][j].stp_Instrument = bptr[1];
770 ht->ht_Tracks[i][j].stp_FX = bptr[2]>>4;
771 ht->ht_Tracks[i][j].stp_FXParam = bptr[3];
772 ht->ht_Tracks[i][j].stp_FXb = bptr[2]&0xf;
773 ht->ht_Tracks[i][j].stp_FXbParam = bptr[4];
774 bptr += 5;
779 // Instruments
780 for( i=1; i<=ht->ht_InstrumentNr; i++ )
782 if( nptr < (TEXT *)(buf+buflen) )
784 strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
785 nptr += strlen( nptr )+1;
786 } else {
787 ht->ht_Instruments[i].ins_Name[0] = 0;
790 ht->ht_Instruments[i].ins_Volume = bptr[0];
791 ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
792 ht->ht_Instruments[i].ins_WaveLength = bptr[1]&0x07;
794 ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
795 ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
796 ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
797 ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
798 ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
799 ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
800 ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
802 ht->ht_Instruments[i].ins_FilterLowerLimit = bptr[12]&0x7f;
803 ht->ht_Instruments[i].ins_VibratoDelay = bptr[13];
804 ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
805 ht->ht_Instruments[i].ins_HardCutRelease = bptr[14]&0x80?1:0;
806 ht->ht_Instruments[i].ins_VibratoDepth = bptr[14]&0x0f;
807 ht->ht_Instruments[i].ins_VibratoSpeed = bptr[15];
808 ht->ht_Instruments[i].ins_SquareLowerLimit = bptr[16];
809 ht->ht_Instruments[i].ins_SquareUpperLimit = bptr[17];
810 ht->ht_Instruments[i].ins_SquareSpeed = bptr[18];
811 ht->ht_Instruments[i].ins_FilterUpperLimit = bptr[19]&0x3f;
812 ht->ht_Instruments[i].ins_PList.pls_Speed = bptr[20];
813 ht->ht_Instruments[i].ins_PList.pls_Length = bptr[21];
815 ht->ht_Instruments[i].ins_PList.pls_Entries = ple;
816 ple += bptr[21];
818 bptr += 22;
819 for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
821 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0] = bptr[0]&0xf;
822 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1] = (bptr[1]>>3)&0xf;
823 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform = bptr[1]&7;
824 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed = (bptr[2]>>6)&1;
825 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note = bptr[2]&0x3f;
826 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[3];
827 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[4];
828 bptr += 5;
832 //hvl_InitSubsong( ht, 0 );
833 free( buf );
834 return ht;
837 void hvl_FreeTune( struct hvl_tune *ht )
839 if( !ht ) return;
840 free( ht );
843 void hvl_process_stepfx_1( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
845 switch( FX )
847 case 0x0: // Position Jump HI
848 if( ((FXParam&0x0f) > 0) && ((FXParam&0x0f) <= 9) )
849 ht->ht_PosJump = FXParam & 0xf;
850 break;
852 case 0x5: // Volume Slide + Tone Portamento
853 case 0xa: // Volume Slide
854 voice->vc_VolumeSlideDown = FXParam & 0x0f;
855 voice->vc_VolumeSlideUp = FXParam >> 4;
856 break;
858 case 0x7: // Panning
859 if( FXParam > 127 )
860 FXParam -= 256;
861 voice->vc_Pan = (FXParam+128);
862 voice->vc_SetPan = (FXParam+128); // 1.4
863 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
864 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
865 break;
867 case 0xb: // Position jump
868 ht->ht_PosJump = ht->ht_PosJump*100 + (FXParam & 0x0f) + (FXParam >> 4)*10;
869 ht->ht_PatternBreak = 1;
870 if( ht->ht_PosJump <= tune->songpos )
871 ht->ht_SongEndReached = 1;
872 break;
874 case 0xd: // Pattern break
875 ht->ht_PosJump = tune->songpos+1;
876 ht->ht_PosJumpNote = (FXParam & 0x0f) + (FXParam>>4)*10;
877 ht->ht_PatternBreak = 1;
878 if( ht->ht_PosJumpNote > ht->ht_TrackLength )
879 ht->ht_PosJumpNote = 0;
880 break;
882 case 0xe: // Extended commands
883 switch( FXParam >> 4 )
885 case 0xc: // Note cut
886 if( (FXParam & 0x0f) < ht->ht_Tempo )
888 voice->vc_NoteCutWait = FXParam & 0x0f;
889 if( voice->vc_NoteCutWait )
891 voice->vc_NoteCutOn = 1;
892 voice->vc_HardCutRelease = 0;
895 break;
897 // 1.6: 0xd case removed
899 break;
901 case 0xf: // Speed
902 ht->ht_Tempo = FXParam;
903 if( FXParam == 0 )
904 ht->ht_SongEndReached = 1;
905 break;
909 void hvl_process_stepfx_2( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam, int32 *Note )
911 switch( FX )
913 case 0x9: // Set squarewave offset
914 voice->vc_SquarePos = FXParam >> (5 - voice->vc_WaveLength);
915 voice->vc_PlantSquare = 1;
916 voice->vc_IgnoreSquare = 1;
917 break;
919 case 0x5: // Tone portamento + volume slide
920 case 0x3: // Tone portamento
921 if( FXParam != 0 ) voice->vc_PeriodSlideSpeed = FXParam;
923 if( *Note )
925 int32 new, diff;
927 new = period_tab[*Note];
928 diff = period_tab[voice->vc_TrackPeriod];
929 diff -= new;
930 new = diff + voice->vc_PeriodSlidePeriod;
932 if( new )
933 voice->vc_PeriodSlideLimit = -diff;
935 voice->vc_PeriodSlideOn = 1;
936 voice->vc_PeriodSlideWithLimit = 1;
937 *Note = 0;
938 break;
942 void hvl_process_stepfx_3( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
944 int32 i;
946 switch( FX )
948 case 0x01: // Portamento up (period slide down)
949 voice->vc_PeriodSlideSpeed = -FXParam;
950 voice->vc_PeriodSlideOn = 1;
951 voice->vc_PeriodSlideWithLimit = 0;
952 break;
953 case 0x02: // Portamento down
954 voice->vc_PeriodSlideSpeed = FXParam;
955 voice->vc_PeriodSlideOn = 1;
956 voice->vc_PeriodSlideWithLimit = 0;
957 break;
958 case 0x04: // Filter override
959 if( ( FXParam == 0 ) || ( FXParam == 0x40 ) ) break;
960 if( FXParam < 0x40 )
962 voice->vc_IgnoreFilter = FXParam;
963 break;
965 if( FXParam > 0x7f ) break;
966 voice->vc_FilterPos = FXParam - 0x40;
967 break;
968 case 0x0c: // Volume
969 FXParam &= 0xff;
970 if( FXParam <= 0x40 )
972 voice->vc_NoteMaxVolume = FXParam;
973 break;
976 if( (FXParam -= 0x50) < 0 ) break; // 1.6
978 if( FXParam <= 0x40 )
980 for( i=0; i<ht->ht_Channels; i++ )
981 ht->ht_Voices[i].vc_TrackMasterVolume = FXParam;
982 break;
985 if( (FXParam -= 0xa0-0x50) < 0 ) break; // 1.6
987 if( FXParam <= 0x40 )
988 voice->vc_TrackMasterVolume = FXParam;
989 break;
991 case 0xe: // Extended commands;
992 switch( FXParam >> 4 )
994 case 0x1: // Fineslide up
995 voice->vc_PeriodSlidePeriod = -(FXParam & 0x0f);
996 voice->vc_PlantPeriod = 1;
997 break;
999 case 0x2: // Fineslide down
1000 voice->vc_PeriodSlidePeriod = (FXParam & 0x0f);
1001 voice->vc_PlantPeriod = 1;
1002 break;
1004 case 0x4: // Vibrato control
1005 voice->vc_VibratoDepth = FXParam & 0x0f;
1006 break;
1008 case 0x0a: // Fine volume up
1009 voice->vc_NoteMaxVolume += FXParam & 0x0f;
1011 if( voice->vc_NoteMaxVolume > 0x40 )
1012 voice->vc_NoteMaxVolume = 0x40;
1013 break;
1015 case 0x0b: // Fine volume down
1016 voice->vc_NoteMaxVolume -= FXParam & 0x0f;
1018 if( voice->vc_NoteMaxVolume < 0 )
1019 voice->vc_NoteMaxVolume = 0;
1020 break;
1022 case 0x0f: // Misc flags (1.5)
1023 if( ht->ht_Version < 1 ) break;
1024 switch( FXParam & 0xf )
1026 case 1:
1027 voice->vc_OverrideTranspose = voice->vc_Transpose;
1028 break;
1030 break;
1032 break;
1036 void hvl_process_step( struct hvl_tune *ht, struct hvl_voice *voice )
1038 int32 Note, Instr, donenotedel;
1039 struct hvl_step *Step;
1041 if( voice->vc_TrackOn == 0 )
1042 return;
1044 voice->vc_VolumeSlideUp = voice->vc_VolumeSlideDown = 0;
1046 Step = &ht->ht_Tracks[ht->ht_Positions[tune->songpos].pos_Track[voice->vc_VoiceNum]][ht->ht_NoteNr];
1048 Note = Step->stp_Note;
1049 Instr = Step->stp_Instrument;
1051 // --------- 1.6: from here --------------
1053 donenotedel = 0;
1055 // Do notedelay here
1056 if( ((Step->stp_FX&0xf)==0xe) && ((Step->stp_FXParam&0xf0)==0xd0) )
1058 if( voice->vc_NoteDelayOn )
1060 voice->vc_NoteDelayOn = 0;
1061 donenotedel = 1;
1062 } else {
1063 if( (Step->stp_FXParam&0x0f) < ht->ht_Tempo )
1065 voice->vc_NoteDelayWait = Step->stp_FXParam & 0x0f;
1066 if( voice->vc_NoteDelayWait )
1068 voice->vc_NoteDelayOn = 1;
1069 return;
1075 if( (donenotedel==0) && ((Step->stp_FXb&0xf)==0xe) && ((Step->stp_FXbParam&0xf0)==0xd0) )
1077 if( voice->vc_NoteDelayOn )
1079 voice->vc_NoteDelayOn = 0;
1080 } else {
1081 if( (Step->stp_FXbParam&0x0f) < ht->ht_Tempo )
1083 voice->vc_NoteDelayWait = Step->stp_FXbParam & 0x0f;
1084 if( voice->vc_NoteDelayWait )
1086 voice->vc_NoteDelayOn = 1;
1087 return;
1093 // --------- 1.6: to here --------------
1095 if( Note ) voice->vc_OverrideTranspose = 1000; // 1.5
1097 hvl_process_stepfx_1( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
1098 hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
1100 if( ( Instr ) && ( Instr <= ht->ht_InstrumentNr ) )
1102 struct hvl_instrument *Ins;
1103 int16 SquareLower, SquareUpper, d6, d3, d4;
1105 /* 1.4: Reset panning to last set position */
1106 voice->vc_Pan = voice->vc_SetPan;
1107 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
1108 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
1110 voice->vc_PeriodSlideSpeed = voice->vc_PeriodSlidePeriod = voice->vc_PeriodSlideLimit = 0;
1112 voice->vc_PerfSubVolume = 0x40;
1113 voice->vc_ADSRVolume = 0;
1114 voice->vc_Instrument = Ins = &ht->ht_Instruments[Instr];
1115 voice->vc_SamplePos = 0;
1117 voice->vc_ADSR.aFrames = Ins->ins_Envelope.aFrames;
1118 voice->vc_ADSR.aVolume = Ins->ins_Envelope.aVolume*256/voice->vc_ADSR.aFrames;
1119 voice->vc_ADSR.dFrames = Ins->ins_Envelope.dFrames;
1120 voice->vc_ADSR.dVolume = (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume)*256/voice->vc_ADSR.dFrames;
1121 voice->vc_ADSR.sFrames = Ins->ins_Envelope.sFrames;
1122 voice->vc_ADSR.rFrames = Ins->ins_Envelope.rFrames;
1123 voice->vc_ADSR.rVolume = (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume)*256/voice->vc_ADSR.rFrames;
1125 voice->vc_WaveLength = Ins->ins_WaveLength;
1126 voice->vc_NoteMaxVolume = Ins->ins_Volume;
1128 voice->vc_VibratoCurrent = 0;
1129 voice->vc_VibratoDelay = Ins->ins_VibratoDelay;
1130 voice->vc_VibratoDepth = Ins->ins_VibratoDepth;
1131 voice->vc_VibratoSpeed = Ins->ins_VibratoSpeed;
1132 voice->vc_VibratoPeriod = 0;
1134 voice->vc_HardCutRelease = Ins->ins_HardCutRelease;
1135 voice->vc_HardCut = Ins->ins_HardCutReleaseFrames;
1137 voice->vc_IgnoreSquare = voice->vc_SquareSlidingIn = 0;
1138 voice->vc_SquareWait = voice->vc_SquareOn = 0;
1140 SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength);
1141 SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength);
1143 if( SquareUpper < SquareLower )
1145 int16 t = SquareUpper;
1146 SquareUpper = SquareLower;
1147 SquareLower = t;
1150 voice->vc_SquareUpperLimit = SquareUpper;
1151 voice->vc_SquareLowerLimit = SquareLower;
1153 voice->vc_IgnoreFilter = voice->vc_FilterWait = voice->vc_FilterOn = 0;
1154 voice->vc_FilterSlidingIn = 0;
1156 d6 = Ins->ins_FilterSpeed;
1157 d3 = Ins->ins_FilterLowerLimit;
1158 d4 = Ins->ins_FilterUpperLimit;
1160 if( d3 & 0x80 ) d6 |= 0x20;
1161 if( d4 & 0x80 ) d6 |= 0x40;
1163 voice->vc_FilterSpeed = d6;
1164 d3 &= ~0x80;
1165 d4 &= ~0x80;
1167 if( d3 > d4 )
1169 int16 t = d3;
1170 d3 = d4;
1171 d4 = t;
1174 voice->vc_FilterUpperLimit = d4;
1175 voice->vc_FilterLowerLimit = d3;
1176 voice->vc_FilterPos = 32;
1178 voice->vc_PerfWait = voice->vc_PerfCurrent = 0;
1179 voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed;
1180 voice->vc_PerfList = &voice->vc_Instrument->ins_PList;
1182 voice->vc_RingMixSource = NULL; // No ring modulation
1183 voice->vc_RingSamplePos = 0;
1184 voice->vc_RingPlantPeriod = 0;
1185 voice->vc_RingNewWaveform = 0;
1188 voice->vc_PeriodSlideOn = 0;
1190 hvl_process_stepfx_2( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam, &Note );
1191 hvl_process_stepfx_2( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note );
1193 if( Note )
1195 voice->vc_TrackPeriod = Note;
1196 voice->vc_PlantPeriod = 1;
1199 hvl_process_stepfx_3( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
1200 hvl_process_stepfx_3( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
1203 void hvl_plist_command_parse( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
1205 switch( FX )
1207 case 0:
1208 if( ( FXParam > 0 ) && ( FXParam < 0x40 ) )
1210 if( voice->vc_IgnoreFilter )
1212 voice->vc_FilterPos = voice->vc_IgnoreFilter;
1213 voice->vc_IgnoreFilter = 0;
1214 } else {
1215 voice->vc_FilterPos = FXParam;
1217 voice->vc_NewWaveform = 1;
1219 break;
1221 case 1:
1222 voice->vc_PeriodPerfSlideSpeed = FXParam;
1223 voice->vc_PeriodPerfSlideOn = 1;
1224 break;
1226 case 2:
1227 voice->vc_PeriodPerfSlideSpeed = -FXParam;
1228 voice->vc_PeriodPerfSlideOn = 1;
1229 break;
1231 case 3:
1232 if( voice->vc_IgnoreSquare == 0 )
1233 voice->vc_SquarePos = FXParam >> (5-voice->vc_WaveLength);
1234 else
1235 voice->vc_IgnoreSquare = 0;
1236 break;
1238 case 4:
1239 if( FXParam == 0 )
1241 voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
1242 voice->vc_SquareSign = 1;
1243 } else {
1245 if( FXParam & 0x0f )
1247 voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
1248 voice->vc_SquareSign = 1;
1249 if(( FXParam & 0x0f ) == 0x0f )
1250 voice->vc_SquareSign = -1;
1253 if( FXParam & 0xf0 )
1255 voice->vc_FilterInit = (voice->vc_FilterOn ^= 1);
1256 voice->vc_FilterSign = 1;
1257 if(( FXParam & 0xf0 ) == 0xf0 )
1258 voice->vc_FilterSign = -1;
1261 break;
1263 case 5:
1264 voice->vc_PerfCurrent = FXParam;
1265 break;
1267 case 7:
1268 // Ring modulate with triangle
1269 if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
1271 voice->vc_RingBasePeriod = FXParam;
1272 voice->vc_RingFixedPeriod = 1;
1273 } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
1274 voice->vc_RingBasePeriod = FXParam-0x80;
1275 voice->vc_RingFixedPeriod = 0;
1276 } else {
1277 voice->vc_RingBasePeriod = 0;
1278 voice->vc_RingFixedPeriod = 0;
1279 voice->vc_RingNewWaveform = 0;
1280 voice->vc_RingAudioSource = NULL; // turn it off
1281 voice->vc_RingMixSource = NULL;
1282 break;
1284 voice->vc_RingWaveform = 0;
1285 voice->vc_RingNewWaveform = 1;
1286 voice->vc_RingPlantPeriod = 1;
1287 break;
1288 //orly
1289 case 8: // Ring modulate with sawtooth
1290 if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
1292 voice->vc_RingBasePeriod = FXParam;
1293 voice->vc_RingFixedPeriod = 1;
1294 } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
1295 voice->vc_RingBasePeriod = FXParam-0x80;
1296 voice->vc_RingFixedPeriod = 0;
1297 } else {
1298 voice->vc_RingBasePeriod = 0;
1299 voice->vc_RingFixedPeriod = 0;
1300 voice->vc_RingNewWaveform = 0;
1301 voice->vc_RingAudioSource = NULL;
1302 voice->vc_RingMixSource = NULL;
1303 break;
1306 voice->vc_RingWaveform = 1;
1307 voice->vc_RingNewWaveform = 1;
1308 voice->vc_RingPlantPeriod = 1;
1309 break;
1311 /* New in HivelyTracker 1.4 */
1312 case 9:
1313 if( FXParam > 127 )
1314 FXParam -= 256;
1315 voice->vc_Pan = (FXParam+128);
1316 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
1317 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
1318 break;
1320 case 12:
1321 if( FXParam <= 0x40 )
1323 voice->vc_NoteMaxVolume = FXParam;
1324 break;
1327 if( (FXParam -= 0x50) < 0 ) break;
1329 if( FXParam <= 0x40 )
1331 voice->vc_PerfSubVolume = FXParam;
1332 break;
1335 if( (FXParam -= 0xa0-0x50) < 0 ) break;
1337 if( FXParam <= 0x40 )
1338 voice->vc_TrackMasterVolume = FXParam;
1339 break;
1341 case 15:
1342 voice->vc_PerfSpeed = voice->vc_PerfWait = FXParam;
1343 break;
1347 void hvl_process_frame( struct hvl_tune *ht, struct hvl_voice *voice )
1349 static uint8 Offsets[] = {0x00,0x04,0x04+0x08,0x04+0x08+0x10,0x04+0x08+0x10+0x20,0x04+0x08+0x10+0x20+0x40};
1351 if( voice->vc_TrackOn == 0 )
1352 return;
1354 if( voice->vc_NoteDelayOn )
1356 if( voice->vc_NoteDelayWait <= 0 )
1357 hvl_process_step( ht, voice );
1358 else
1359 voice->vc_NoteDelayWait--;
1362 if( voice->vc_HardCut )
1364 int32 nextinst;
1366 if( ht->ht_NoteNr+1 < ht->ht_TrackLength )
1367 nextinst = ht->ht_Tracks[voice->vc_Track][ht->ht_NoteNr+1].stp_Instrument;
1368 else
1369 nextinst = ht->ht_Tracks[voice->vc_NextTrack][0].stp_Instrument;
1371 if( nextinst )
1373 int32 d1;
1375 d1 = ht->ht_Tempo - voice->vc_HardCut;
1377 if( d1 < 0 ) d1 = 0;
1379 if( !voice->vc_NoteCutOn )
1381 voice->vc_NoteCutOn = 1;
1382 voice->vc_NoteCutWait = d1;
1383 voice->vc_HardCutReleaseF = -(d1-ht->ht_Tempo);
1384 } else {
1385 voice->vc_HardCut = 0;
1390 if( voice->vc_NoteCutOn )
1392 if( voice->vc_NoteCutWait <= 0 )
1394 voice->vc_NoteCutOn = 0;
1396 if( voice->vc_HardCutRelease )
1398 voice->vc_ADSR.rVolume = -(voice->vc_ADSRVolume - (voice->vc_Instrument->ins_Envelope.rVolume << 8)) / voice->vc_HardCutReleaseF;
1399 voice->vc_ADSR.rFrames = voice->vc_HardCutReleaseF;
1400 voice->vc_ADSR.aFrames = voice->vc_ADSR.dFrames = voice->vc_ADSR.sFrames = 0;
1401 } else {
1402 voice->vc_NoteMaxVolume = 0;
1404 } else {
1405 voice->vc_NoteCutWait--;
1409 // ADSR envelope
1410 if( voice->vc_ADSR.aFrames )
1412 voice->vc_ADSRVolume += voice->vc_ADSR.aVolume;
1414 if( --voice->vc_ADSR.aFrames <= 0 )
1415 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.aVolume << 8;
1417 } else if( voice->vc_ADSR.dFrames ) {
1419 voice->vc_ADSRVolume += voice->vc_ADSR.dVolume;
1421 if( --voice->vc_ADSR.dFrames <= 0 )
1422 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.dVolume << 8;
1424 } else if( voice->vc_ADSR.sFrames ) {
1426 voice->vc_ADSR.sFrames--;
1428 } else if( voice->vc_ADSR.rFrames ) {
1430 voice->vc_ADSRVolume += voice->vc_ADSR.rVolume;
1432 if( --voice->vc_ADSR.rFrames <= 0 )
1433 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.rVolume << 8;
1436 // VolumeSlide
1437 voice->vc_NoteMaxVolume = voice->vc_NoteMaxVolume + voice->vc_VolumeSlideUp - voice->vc_VolumeSlideDown;
1439 if( voice->vc_NoteMaxVolume < 0 )
1440 voice->vc_NoteMaxVolume = 0;
1441 else if( voice->vc_NoteMaxVolume > 0x40 )
1442 voice->vc_NoteMaxVolume = 0x40;
1444 // Portamento
1445 if( voice->vc_PeriodSlideOn )
1447 if( voice->vc_PeriodSlideWithLimit )
1449 int32 d0, d2;
1451 d0 = voice->vc_PeriodSlidePeriod - voice->vc_PeriodSlideLimit;
1452 d2 = voice->vc_PeriodSlideSpeed;
1454 if( d0 > 0 )
1455 d2 = -d2;
1457 if( d0 )
1459 int32 d3;
1461 d3 = (d0 + d2) ^ d0;
1463 if( d3 >= 0 )
1464 d0 = voice->vc_PeriodSlidePeriod + d2;
1465 else
1466 d0 = voice->vc_PeriodSlideLimit;
1468 voice->vc_PeriodSlidePeriod = d0;
1469 voice->vc_PlantPeriod = 1;
1471 } else {
1472 voice->vc_PeriodSlidePeriod += voice->vc_PeriodSlideSpeed;
1473 voice->vc_PlantPeriod = 1;
1477 // Vibrato
1478 if( voice->vc_VibratoDepth )
1480 if( voice->vc_VibratoDelay <= 0 )
1482 voice->vc_VibratoPeriod = (vib_tab[voice->vc_VibratoCurrent] * voice->vc_VibratoDepth) >> 7;
1483 voice->vc_PlantPeriod = 1;
1484 voice->vc_VibratoCurrent = (voice->vc_VibratoCurrent + voice->vc_VibratoSpeed) & 0x3f;
1485 } else {
1486 voice->vc_VibratoDelay--;
1490 // PList
1491 if( voice->vc_PerfList != 0 )
1493 if( voice->vc_Instrument && voice->vc_PerfCurrent < voice->vc_Instrument->ins_PList.pls_Length )
1495 if( --voice->vc_PerfWait <= 0 )
1497 uint32 i;
1498 int32 cur;
1500 cur = voice->vc_PerfCurrent++;
1501 voice->vc_PerfWait = voice->vc_PerfSpeed;
1503 if( voice->vc_PerfList->pls_Entries[cur].ple_Waveform )
1505 voice->vc_Waveform = voice->vc_PerfList->pls_Entries[cur].ple_Waveform-1;
1506 voice->vc_NewWaveform = 1;
1507 voice->vc_PeriodPerfSlideSpeed = voice->vc_PeriodPerfSlidePeriod = 0;
1510 // Holdwave
1511 voice->vc_PeriodPerfSlideOn = 0;
1513 for( i=0; i<2; i++ )
1514 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 );
1516 // GetNote
1517 if( voice->vc_PerfList->pls_Entries[cur].ple_Note )
1519 voice->vc_InstrPeriod = voice->vc_PerfList->pls_Entries[cur].ple_Note;
1520 voice->vc_PlantPeriod = 1;
1521 voice->vc_FixedNote = voice->vc_PerfList->pls_Entries[cur].ple_Fixed;
1524 } else {
1525 if( voice->vc_PerfWait )
1526 voice->vc_PerfWait--;
1527 else
1528 voice->vc_PeriodPerfSlideSpeed = 0;
1532 // PerfPortamento
1533 if( voice->vc_PeriodPerfSlideOn )
1535 voice->vc_PeriodPerfSlidePeriod -= voice->vc_PeriodPerfSlideSpeed;
1537 if( voice->vc_PeriodPerfSlidePeriod )
1538 voice->vc_PlantPeriod = 1;
1541 if( voice->vc_Waveform == 3-1 && voice->vc_SquareOn )
1543 if( --voice->vc_SquareWait <= 0 )
1545 int32 d1, d2, d3;
1547 d1 = voice->vc_SquareLowerLimit;
1548 d2 = voice->vc_SquareUpperLimit;
1549 d3 = voice->vc_SquarePos;
1551 if( voice->vc_SquareInit )
1553 voice->vc_SquareInit = 0;
1555 if( d3 <= d1 )
1557 voice->vc_SquareSlidingIn = 1;
1558 voice->vc_SquareSign = 1;
1559 } else if( d3 >= d2 ) {
1560 voice->vc_SquareSlidingIn = 1;
1561 voice->vc_SquareSign = -1;
1565 // NoSquareInit
1566 if( d1 == d3 || d2 == d3 )
1568 if( voice->vc_SquareSlidingIn )
1569 voice->vc_SquareSlidingIn = 0;
1570 else
1571 voice->vc_SquareSign = -voice->vc_SquareSign;
1574 d3 += voice->vc_SquareSign;
1575 voice->vc_SquarePos = d3;
1576 voice->vc_PlantSquare = 1;
1577 voice->vc_SquareWait = voice->vc_Instrument->ins_SquareSpeed;
1581 if( voice->vc_FilterOn && --voice->vc_FilterWait <= 0 )
1583 uint32 i, FMax;
1584 int32 d1, d2, d3;
1586 d1 = voice->vc_FilterLowerLimit;
1587 d2 = voice->vc_FilterUpperLimit;
1588 d3 = voice->vc_FilterPos;
1590 if( voice->vc_FilterInit )
1592 voice->vc_FilterInit = 0;
1593 if( d3 <= d1 )
1595 voice->vc_FilterSlidingIn = 1;
1596 voice->vc_FilterSign = 1;
1597 } else if( d3 >= d2 ) {
1598 voice->vc_FilterSlidingIn = 1;
1599 voice->vc_FilterSign = -1;
1603 // NoFilterInit
1604 FMax = (voice->vc_FilterSpeed < 3) ? (5-voice->vc_FilterSpeed) : 1;
1606 for( i=0; i<FMax; i++ )
1608 if( ( d1 == d3 ) || ( d2 == d3 ) )
1610 if( voice->vc_FilterSlidingIn )
1611 voice->vc_FilterSlidingIn = 0;
1612 else
1613 voice->vc_FilterSign = -voice->vc_FilterSign;
1615 d3 += voice->vc_FilterSign;
1618 if( d3 < 1 ) d3 = 1;
1619 if( d3 > 63 ) d3 = 63;
1620 voice->vc_FilterPos = d3;
1621 voice->vc_NewWaveform = 1;
1622 voice->vc_FilterWait = voice->vc_FilterSpeed - 3;
1624 if( voice->vc_FilterWait < 1 )
1625 voice->vc_FilterWait = 1;
1628 if( voice->vc_Waveform == 3-1 || voice->vc_PlantSquare )
1630 // CalcSquare
1631 uint32 i;
1632 int32 Delta;
1633 int8 *SquarePtr;
1634 int32 X;
1636 SquarePtr = &waves[WO_SQUARES+(voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3)];
1637 X = voice->vc_SquarePos << (5 - voice->vc_WaveLength);
1639 if( X > 0x20 )
1641 X = 0x40 - X;
1642 voice->vc_SquareReverse = 1;
1645 // OkDownSquare
1646 if( X > 0 )
1647 SquarePtr += (X-1) << 7;
1649 Delta = 32 >> voice->vc_WaveLength;
1650 ht->ht_WaveformTab[2] = voice->vc_SquareTempBuffer;
1652 for( i=0; i<(1<<voice->vc_WaveLength)*4; i++ )
1654 voice->vc_SquareTempBuffer[i] = *SquarePtr;
1655 SquarePtr += Delta;
1658 voice->vc_NewWaveform = 1;
1659 voice->vc_Waveform = 3-1;
1660 voice->vc_PlantSquare = 0;
1663 if( voice->vc_Waveform == 4-1 )
1664 voice->vc_NewWaveform = 1;
1666 if( voice->vc_RingNewWaveform )
1668 int8 *rasrc;
1670 if( voice->vc_RingWaveform > 1 ) voice->vc_RingWaveform = 1;
1672 rasrc = ht->ht_WaveformTab[voice->vc_RingWaveform];
1673 rasrc += Offsets[voice->vc_WaveLength];
1675 voice->vc_RingAudioSource = rasrc;
1679 if( voice->vc_NewWaveform )
1681 int8 *AudioSource;
1683 AudioSource = ht->ht_WaveformTab[voice->vc_Waveform];
1685 if( voice->vc_Waveform != 3-1 )
1686 AudioSource += (voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3);
1688 if( voice->vc_Waveform < 3-1)
1690 // GetWLWaveformlor2
1691 AudioSource += Offsets[voice->vc_WaveLength];
1694 if( voice->vc_Waveform == 4-1 )
1696 // AddRandomMoving
1697 AudioSource += ( voice->vc_WNRandom & (2*0x280-1) ) & ~1;
1698 // GoOnRandom
1699 voice->vc_WNRandom += 2239384;
1700 voice->vc_WNRandom = ((((voice->vc_WNRandom >> 8) | (voice->vc_WNRandom << 24)) + 782323) ^ 75) - 6735;
1703 voice->vc_AudioSource = AudioSource;
1706 // Ring modulation period calculation
1707 if( voice->vc_RingAudioSource )
1709 voice->vc_RingAudioPeriod = voice->vc_RingBasePeriod;
1711 if( !(voice->vc_RingFixedPeriod) )
1713 if( voice->vc_OverrideTranspose != 1000 ) // 1.5
1714 voice->vc_RingAudioPeriod += voice->vc_OverrideTranspose + voice->vc_TrackPeriod - 1;
1715 else
1716 voice->vc_RingAudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
1719 if( voice->vc_RingAudioPeriod > 5*12 )
1720 voice->vc_RingAudioPeriod = 5*12;
1722 if( voice->vc_RingAudioPeriod < 0 )
1723 voice->vc_RingAudioPeriod = 0;
1725 voice->vc_RingAudioPeriod = period_tab[voice->vc_RingAudioPeriod];
1727 if( !(voice->vc_RingFixedPeriod) )
1728 voice->vc_RingAudioPeriod += voice->vc_PeriodSlidePeriod;
1730 voice->vc_RingAudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;
1732 if( voice->vc_RingAudioPeriod > 0x0d60 )
1733 voice->vc_RingAudioPeriod = 0x0d60;
1735 if( voice->vc_RingAudioPeriod < 0x0071 )
1736 voice->vc_RingAudioPeriod = 0x0071;
1739 // Normal period calculation
1740 voice->vc_AudioPeriod = voice->vc_InstrPeriod;
1742 if( !(voice->vc_FixedNote) )
1744 if( voice->vc_OverrideTranspose != 1000 ) // 1.5
1745 voice->vc_AudioPeriod += voice->vc_OverrideTranspose + voice->vc_TrackPeriod - 1;
1746 else
1747 voice->vc_AudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
1750 if( voice->vc_AudioPeriod > 5*12 )
1751 voice->vc_AudioPeriod = 5*12;
1753 if( voice->vc_AudioPeriod < 0 )
1754 voice->vc_AudioPeriod = 0;
1756 voice->vc_AudioPeriod = period_tab[voice->vc_AudioPeriod];
1758 if( !(voice->vc_FixedNote) )
1759 voice->vc_AudioPeriod += voice->vc_PeriodSlidePeriod;
1761 voice->vc_AudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;
1763 if( voice->vc_AudioPeriod > 0x0d60 )
1764 voice->vc_AudioPeriod = 0x0d60;
1766 if( voice->vc_AudioPeriod < 0x0071 )
1767 voice->vc_AudioPeriod = 0x0071;
1769 voice->vc_AudioVolume = (((((((voice->vc_ADSRVolume >> 8) * voice->vc_NoteMaxVolume) >> 6) * voice->vc_PerfSubVolume) >> 6) * voice->vc_TrackMasterVolume) >> 6);
1772 void hvl_set_audio( struct hvl_voice *voice, float64 freqf )
1774 if( voice->vc_TrackOn == 0 )
1776 voice->vc_VoiceVolume = 0;
1777 return;
1780 voice->vc_VoiceVolume = voice->vc_AudioVolume;
1782 if( voice->vc_PlantPeriod )
1784 float64 freq2;
1785 uint32 delta;
1787 voice->vc_PlantPeriod = 0;
1788 voice->vc_VoicePeriod = voice->vc_AudioPeriod;
1790 freq2 = Period2Freq( voice->vc_AudioPeriod );
1791 delta = (uint32)(freq2 / freqf);
1793 if( delta > (0x280<<16) ) delta -= (0x280<<16);
1794 if( delta == 0 ) delta = 1;
1795 voice->vc_Delta = delta;
1798 if( voice->vc_NewWaveform )
1800 int8 *src;
1802 src = voice->vc_AudioSource;
1804 if( voice->vc_Waveform == 4-1 )
1806 memcpy( &voice->vc_VoiceBuffer[0], src, 0x280 );
1807 } else {
1808 uint32 i, WaveLoops;
1810 WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
1812 for( i=0; i<WaveLoops; i++ )
1813 memcpy( &voice->vc_VoiceBuffer[i*4*(1<<voice->vc_WaveLength)], src, 4*(1<<voice->vc_WaveLength) );
1816 voice->vc_VoiceBuffer[0x280] = voice->vc_VoiceBuffer[0];
1817 voice->vc_MixSource = voice->vc_VoiceBuffer;
1820 /* Ring Modulation */
1821 if( voice->vc_RingPlantPeriod )
1823 float64 freq2;
1824 uint32 delta;
1826 voice->vc_RingPlantPeriod = 0;
1827 freq2 = Period2Freq( voice->vc_RingAudioPeriod );
1828 delta = (uint32)(freq2 / freqf);
1830 if( delta > (0x280<<16) ) delta -= (0x280<<16);
1831 if( delta == 0 ) delta = 1;
1832 voice->vc_RingDelta = delta;
1835 if( voice->vc_RingNewWaveform )
1837 int8 *src;
1838 uint32 i, WaveLoops;
1840 src = voice->vc_RingAudioSource;
1842 WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
1844 for( i=0; i<WaveLoops; i++ )
1845 memcpy( &voice->vc_RingVoiceBuffer[i*4*(1<<voice->vc_WaveLength)], src, 4*(1<<voice->vc_WaveLength) );
1847 voice->vc_RingVoiceBuffer[0x280] = voice->vc_RingVoiceBuffer[0];
1848 voice->vc_RingMixSource = voice->vc_RingVoiceBuffer;
1852 void hvl_play_irq( struct hvl_tune *ht )
1854 uint32 i;
1856 if( ht->ht_StepWaitFrames <= 0 )
1858 if( ht->ht_GetNewPosition )
1860 int32 nextpos = (tune->songpos+1==ht->ht_PositionNr)?0:(tune->songpos+1);
1862 for( i=0; i<ht->ht_Channels; i++ )
1864 ht->ht_Voices[i].vc_Track = ht->ht_Positions[tune->songpos].pos_Track[i];
1865 ht->ht_Voices[i].vc_Transpose = ht->ht_Positions[tune->songpos].pos_Transpose[i];
1866 ht->ht_Voices[i].vc_NextTrack = ht->ht_Positions[nextpos].pos_Track[i];
1867 ht->ht_Voices[i].vc_NextTranspose = ht->ht_Positions[nextpos].pos_Transpose[i];
1869 ht->ht_GetNewPosition = 0;
1872 for( i=0; i<ht->ht_Channels; i++ )
1873 hvl_process_step( ht, &ht->ht_Voices[i] );
1875 ht->ht_StepWaitFrames = ht->ht_Tempo;
1878 for( i=0; i<ht->ht_Channels; i++ )
1879 hvl_process_frame( ht, &ht->ht_Voices[i] );
1881 ht->ht_PlayingTime++;
1882 if( ht->ht_Tempo > 0 && --ht->ht_StepWaitFrames <= 0 )
1884 if( !ht->ht_PatternBreak )
1886 ht->ht_NoteNr++;
1887 if( ht->ht_NoteNr >= ht->ht_TrackLength )
1889 ht->ht_PosJump = tune->songpos+1;
1890 ht->ht_PosJumpNote = 0;
1891 ht->ht_PatternBreak = 1;
1895 if( ht->ht_PatternBreak )
1897 ht->ht_PatternBreak = 0;
1898 tune->songpos = ht->ht_PosJump;
1899 ht->ht_NoteNr = ht->ht_PosJumpNote;
1900 if( tune->songpos == ht->ht_PositionNr )
1902 ht->ht_SongEndReached = 1;
1903 tune->songpos = ht->ht_Restart;
1905 ht->ht_PosJumpNote = 0;
1906 ht->ht_PosJump = 0;
1908 ht->ht_GetNewPosition = 1;
1912 for( i=0; i<ht->ht_Channels; i++ )
1913 hvl_set_audio( &ht->ht_Voices[i], ht->ht_Frequency );
1916 void hvl_mixchunk( struct hvl_tune *ht, uint32 samples, int8 *buf1, int8 *buf2, int32 bufmod )
1918 int8 *src[MAX_CHANNELS];
1919 int8 *rsrc[MAX_CHANNELS];
1920 uint32 delta[MAX_CHANNELS];
1921 uint32 rdelta[MAX_CHANNELS];
1922 int32 vol[MAX_CHANNELS];
1923 uint32 pos[MAX_CHANNELS];
1924 uint32 rpos[MAX_CHANNELS];
1925 uint32 cnt;
1926 int32 panl[MAX_CHANNELS];
1927 int32 panr[MAX_CHANNELS];
1928 // uint32 vu[MAX_CHANNELS];
1929 int32 a=0, b=0, j;
1930 uint32 i, chans, loops;
1932 chans = ht->ht_Channels;
1933 for( i=0; i<chans; i++ )
1935 delta[i] = ht->ht_Voices[i].vc_Delta;
1936 vol[i] = ht->ht_Voices[i].vc_VoiceVolume;
1937 pos[i] = ht->ht_Voices[i].vc_SamplePos;
1938 src[i] = ht->ht_Voices[i].vc_MixSource;
1939 panl[i] = ht->ht_Voices[i].vc_PanMultLeft;
1940 panr[i] = ht->ht_Voices[i].vc_PanMultRight;
1942 /* Ring Modulation */
1943 rdelta[i]= ht->ht_Voices[i].vc_RingDelta;
1944 rpos[i] = ht->ht_Voices[i].vc_RingSamplePos;
1945 rsrc[i] = ht->ht_Voices[i].vc_RingMixSource;
1947 // vu[i] = 0;
1952 loops = samples;
1953 for( i=0; i<chans; i++ )
1955 if( pos[i] >= (0x280 << 16)) pos[i] -= 0x280<<16;
1956 cnt = ((0x280<<16) - pos[i] - 1) / delta[i] + 1;
1957 if( cnt < loops ) loops = cnt;
1959 if( rsrc[i] )
1961 if( rpos[i] >= (0x280<<16)) rpos[i] -= 0x280<<16;
1962 cnt = ((0x280<<16) - rpos[i] - 1) / rdelta[i] + 1;
1963 if( cnt < loops ) loops = cnt;
1968 samples -= loops;
1970 // Inner loop
1973 a=0;
1974 b=0;
1975 for( i=0; i<chans; i++ )
1977 if( rsrc[i] )
1979 /* Ring Modulation */
1980 j = ((src[i][pos[i]>>16]*rsrc[i][rpos[i]>>16])>>7)*vol[i];
1981 rpos[i] += rdelta[i];
1982 } else {
1983 j = src[i][pos[i]>>16]*vol[i];
1986 // if( abs( j ) > vu[i] ) vu[i] = abs( j );
1988 a += (j * panl[i]) >> 7;
1989 b += (j * panr[i]) >> 7;
1990 pos[i] += delta[i];
1993 a = (a*ht->ht_mixgain)>>8;
1994 b = (b*ht->ht_mixgain)>>8;
1996 *(int16 *)buf1 = a;
1997 *(int16 *)buf2 = b;
1999 loops--;
2001 buf1 += bufmod;
2002 buf2 += bufmod;
2003 } while( loops > 0 );
2004 } while( samples > 0 );
2006 for( i=0; i<chans; i++ )
2008 ht->ht_Voices[i].vc_SamplePos = pos[i];
2009 ht->ht_Voices[i].vc_RingSamplePos = rpos[i];
2010 // ht->ht_Voices[i].vc_VUMeter = vu[i];
2014 void hvl_DecodeFrame( struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod )
2016 uint32 samples, loops;
2018 samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
2019 loops = ht->ht_SpeedMultiplier;
2020 if(playsong || playtrack){
2022 hvl_play_irq( ht );
2023 hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
2024 buf1 += samples * bufmod;
2025 buf2 += samples * bufmod;
2026 loops--;
2027 }while( loops );
2031 //added for pineapple tracker
2033 void hvl_iedplonk(int note, int instr, void *t){
2034 //void hvl_playNote(struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod, struct hvl_voice *voice) {
2035 struct hvl_tune *ht;
2036 ht = (struct hvl_tune*)t;
2037 int8 *buf1 = (int8 *) ht->hivelyLeft;
2038 int8 *buf2 = (int8 *) ht->hivelyRight;
2039 int32 bufmod = 2;
2040 struct hvl_voice *voice = &ht->ht_Voices[0];
2041 uint32 samples, loops;
2043 samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
2044 loops = ht->ht_SpeedMultiplier;
2048 //hvl_play_irq( ht );
2049 //hvl_process_step( ht, &ht->ht_Voices[0] );
2050 int32 Note, Instr, donenotedel;
2051 struct hvl_step *Step;
2053 if( voice->vc_TrackOn == 0 )
2054 return;
2056 voice->vc_VolumeSlideUp = voice->vc_VolumeSlideDown = 0;
2058 Step = &ht->ht_Tracks[ht->ht_Positions[tune->songpos].pos_Track[voice->vc_VoiceNum]][ht->ht_NoteNr];
2060 Note = htTune->curNote;
2061 //Instr = Step->stp_Instrument;
2062 Instr = 01;
2064 // --------- 1.6: from here --------------
2066 donenotedel = 0;
2068 // Do notedelay here
2069 if( ((Step->stp_FX&0xf)==0xe) && ((Step->stp_FXParam&0xf0)==0xd0) )
2071 if( voice->vc_NoteDelayOn )
2073 voice->vc_NoteDelayOn = 0;
2074 donenotedel = 1;
2075 } else {
2076 if( (Step->stp_FXParam&0x0f) < ht->ht_Tempo )
2078 voice->vc_NoteDelayWait = Step->stp_FXParam & 0x0f;
2079 if( voice->vc_NoteDelayWait )
2081 voice->vc_NoteDelayOn = 1;
2082 return;
2088 if( (donenotedel==0) && ((Step->stp_FXb&0xf)==0xe) && ((Step->stp_FXbParam&0xf0)==0xd0) )
2090 if( voice->vc_NoteDelayOn )
2092 voice->vc_NoteDelayOn = 0;
2093 } else {
2094 if( (Step->stp_FXbParam&0x0f) < ht->ht_Tempo )
2096 voice->vc_NoteDelayWait = Step->stp_FXbParam & 0x0f;
2097 if( voice->vc_NoteDelayWait )
2099 voice->vc_NoteDelayOn = 1;
2100 return;
2106 // --------- 1.6: to here --------------
2108 if( Note ) voice->vc_OverrideTranspose = 1000; // 1.5
2110 //hvl_process_stepfx_1( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
2111 //hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
2113 if( ( Instr ) && ( Instr <= ht->ht_InstrumentNr ) )
2115 struct hvl_instrument *Ins;
2116 int16 SquareLower, SquareUpper, d6, d3, d4;
2118 /* 1.4: Reset panning to last set position */
2119 voice->vc_Pan = voice->vc_SetPan;
2120 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
2121 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
2123 voice->vc_PeriodSlideSpeed = voice->vc_PeriodSlidePeriod = voice->vc_PeriodSlideLimit = 0;
2125 voice->vc_PerfSubVolume = 0x40;
2126 voice->vc_ADSRVolume = 0;
2127 voice->vc_Instrument = Ins = &ht->ht_Instruments[Instr];
2128 voice->vc_SamplePos = 0;
2130 voice->vc_ADSR.aFrames = Ins->ins_Envelope.aFrames;
2131 voice->vc_ADSR.aVolume = Ins->ins_Envelope.aVolume*256/voice->vc_ADSR.aFrames;
2132 voice->vc_ADSR.dFrames = Ins->ins_Envelope.dFrames;
2133 voice->vc_ADSR.dVolume = (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume)*256/voice->vc_ADSR.dFrames;
2134 voice->vc_ADSR.sFrames = Ins->ins_Envelope.sFrames;
2135 voice->vc_ADSR.rFrames = Ins->ins_Envelope.rFrames;
2136 voice->vc_ADSR.rVolume = (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume)*256/voice->vc_ADSR.rFrames;
2138 voice->vc_WaveLength = Ins->ins_WaveLength;
2139 voice->vc_NoteMaxVolume = Ins->ins_Volume;
2141 voice->vc_VibratoCurrent = 0;
2142 voice->vc_VibratoDelay = Ins->ins_VibratoDelay;
2143 voice->vc_VibratoDepth = Ins->ins_VibratoDepth;
2144 voice->vc_VibratoSpeed = Ins->ins_VibratoSpeed;
2145 voice->vc_VibratoPeriod = 0;
2147 voice->vc_HardCutRelease = Ins->ins_HardCutRelease;
2148 voice->vc_HardCut = Ins->ins_HardCutReleaseFrames;
2150 voice->vc_IgnoreSquare = voice->vc_SquareSlidingIn = 0;
2151 voice->vc_SquareWait = voice->vc_SquareOn = 0;
2153 SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength);
2154 SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength);
2156 if( SquareUpper < SquareLower )
2158 int16 t = SquareUpper;
2159 SquareUpper = SquareLower;
2160 SquareLower = t;
2163 voice->vc_SquareUpperLimit = SquareUpper;
2164 voice->vc_SquareLowerLimit = SquareLower;
2166 voice->vc_IgnoreFilter = voice->vc_FilterWait = voice->vc_FilterOn = 0;
2167 voice->vc_FilterSlidingIn = 0;
2169 d6 = Ins->ins_FilterSpeed;
2170 d3 = Ins->ins_FilterLowerLimit;
2171 d4 = Ins->ins_FilterUpperLimit;
2173 if( d3 & 0x80 ) d6 |= 0x20;
2174 if( d4 & 0x80 ) d6 |= 0x40;
2176 voice->vc_FilterSpeed = d6;
2177 d3 &= ~0x80;
2178 d4 &= ~0x80;
2180 if( d3 > d4 )
2182 int16 t = d3;
2183 d3 = d4;
2184 d4 = t;
2187 voice->vc_FilterUpperLimit = d4;
2188 voice->vc_FilterLowerLimit = d3;
2189 voice->vc_FilterPos = 32;
2191 voice->vc_PerfWait = voice->vc_PerfCurrent = 0;
2192 voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed;
2193 voice->vc_PerfList = &voice->vc_Instrument->ins_PList;
2195 voice->vc_RingMixSource = NULL; // No ring modulation
2196 voice->vc_RingSamplePos = 0;
2197 voice->vc_RingPlantPeriod = 0;
2198 voice->vc_RingNewWaveform = 0;
2201 voice->vc_PeriodSlideOn = 0;
2203 //hvl_process_stepfx_2( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam, &Note );
2204 //hvl_process_stepfx_2( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note );
2206 if( Note )
2208 voice->vc_TrackPeriod = Note;
2209 voice->vc_PlantPeriod = 1;
2212 //hvl_process_stepfx_3( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
2213 //hvl_process_stepfx_3( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
2215 hvl_process_frame( ht, &ht->ht_Voices[0] );
2216 ht->ht_NoteNr = -1;
2217 hvl_set_audio( &ht->ht_Voices[0], ht->ht_Frequency );
2218 //hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
2219 int8 *src[MAX_CHANNELS];
2220 int8 *rsrc[MAX_CHANNELS];
2221 uint32 delta[MAX_CHANNELS];
2222 uint32 rdelta[MAX_CHANNELS];
2223 int32 vol[MAX_CHANNELS];
2224 uint32 pos[MAX_CHANNELS];
2225 uint32 rpos[MAX_CHANNELS];
2226 uint32 cnt;
2227 int32 panl[MAX_CHANNELS];
2228 int32 panr[MAX_CHANNELS];
2229 // uint32 vu[MAX_CHANNELS];
2230 int32 a=0, b=0, j;
2231 //uint32 i, chans, loops;
2232 uint32 loops2;
2234 //chans = ht->ht_Channels;
2235 //for( i=0; i<0; i++ )
2237 delta[0] = ht->ht_Voices[0].vc_Delta;
2238 vol[0] = ht->ht_Voices[0].vc_VoiceVolume;
2239 pos[0] = ht->ht_Voices[0].vc_SamplePos;
2240 src[0] = ht->ht_Voices[0].vc_MixSource;
2241 panl[0] = ht->ht_Voices[0].vc_PanMultLeft;
2242 panr[0] = ht->ht_Voices[0].vc_PanMultRight;
2244 /* Ring Modulation */
2245 rdelta[0]= ht->ht_Voices[0].vc_RingDelta;
2246 rpos[0] = ht->ht_Voices[0].vc_RingSamplePos;
2247 rsrc[0] = ht->ht_Voices[0].vc_RingMixSource;
2249 // vu[i] = 0;
2254 loops2 = samples;
2255 //for( i=0; i<chans; i++ )
2257 if( pos[0] >= (0x280 << 16)) pos[0] -= 0x280<<16;
2258 cnt = ((0x280<<16) - pos[0] - 1) / delta[0] + 1;
2259 if( cnt < loops2 ) loops2 = cnt;
2261 if( rsrc[0] )
2263 if( rpos[0] >= (0x280<<16)) rpos[0] -= 0x280<<16;
2264 cnt = ((0x280<<16) - rpos[0] - 1) / rdelta[0] + 1;
2265 if( cnt < loops2 ) loops2 = cnt;
2270 samples -= loops2;
2272 // Inner loop
2275 a=0;
2276 b=0;
2277 //for( i=0; i<chans; i++ )
2279 if( rsrc[0] )
2281 /* Ring Modulation */
2282 j = ((src[0][pos[0]>>16]*rsrc[0][rpos[0]>>16])>>7)*vol[0];
2283 rpos[0] += rdelta[0];
2284 } else {
2285 j = src[0][pos[0]>>16]*vol[0];
2288 // if( abs( j ) > vu[i] ) vu[i] = abs( j );
2290 a += (j * panl[0]) >> 7;
2291 b += (j * panr[0]) >> 7;
2292 pos[0] += delta[0];
2295 a = (a*ht->ht_mixgain)>>8;
2296 b = (b*ht->ht_mixgain)>>8;
2298 *(int16 *)buf1 = a;
2299 *(int16 *)buf2 = b;
2301 loops2--;
2303 buf1 += bufmod;
2304 buf2 += bufmod;
2305 } while( loops2 > 0 );
2306 } while( samples > 0 );
2308 //for( i=0; i<chans; i++ )
2310 ht->ht_Voices[0].vc_SamplePos = pos[0];
2311 ht->ht_Voices[0].vc_RingSamplePos = rpos[0];
2312 // ht->ht_Voices[i].vc_VUMeter = vu[i];
2315 buf1 += samples * bufmod;
2316 buf2 += samples * bufmod;
2317 loops--;
2318 } while( loops );
2321 /*int hvl_save_ahx(struct hvl_tune *ht, sturct pineapple_tune *pt){
2324 int hvl_save_hvl(struct hvl_tune *ht, sturct pineapple_tune *pt){