Small bug in lftsdlinit function. It said it was printing out requested.freq
[pineappletracker.git] / hvl_replay.c
blob9dda6a56be4c45085610c778378a1bd45aa8744f
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[] =
53 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
54 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
55 0,-24,-49,-74,-97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,-255,
56 -253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,-97,-74,-49,-24
59 uint16 period_tab[] =
61 0x0000, 0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970,
62 0x08E8, 0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4,
63 0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0,
64 0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C,
65 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D,
66 0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0,
67 0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097,
68 0x008F, 0x0087, 0x007F, 0x0078, 0x0071
71 uint32 panning_left[256], panning_right[256];
73 void hvl_GenPanningTables( void )
75 uint32 i;
76 float64 aa, ab;
78 // Sine based panning table
79 aa = (3.14159265f*2.0f)/4.0f; // Quarter of the way through the sinewave == top peak
80 ab = 0.0f; // Start of the climb from zero
82 for( i=0; i<256; i++ )
84 panning_left[i] = (uint32)(sin(aa)*255.0f);
85 panning_right[i] = (uint32)(sin(ab)*255.0f);
87 aa += (3.14159265*2.0f/4.0f)/256.0f;
88 ab += (3.14159265*2.0f/4.0f)/256.0f;
90 panning_left[255] = 0;
91 panning_right[0] = 0;
94 void hvl_GenSawtooth( int8 *buf, uint32 len )
96 uint32 i;
97 int32 val, add;
99 add = 256 / (len-1);
100 val = -128;
102 for( i=0; i<len; i++, val += add )
103 *buf++ = (int8)val;
106 void hvl_GenTriangle( int8 *buf, uint32 len )
108 uint32 i;
109 int32 d2, d5, d1, d4;
110 int32 val;
111 int8 *buf2;
113 d2 = len;
114 d5 = len >> 2;
115 d1 = 128/d5;
116 d4 = -(d2 >> 1);
117 val = 0;
119 for( i=0; i<d5; i++ )
121 *buf++ = val;
122 val += d1;
124 *buf++ = 0x7f;
126 if( d5 != 1 )
128 val = 128;
129 for( i=0; i<d5-1; i++ )
131 val -= d1;
132 *buf++ = val;
136 buf2 = buf + d4;
137 for( i=0; i<d5*2; i++ )
139 int8 c;
141 c = *buf2++;
142 if( c == 0x7f )
143 c = 0x80;
144 else
145 c = -c;
147 *buf++ = c;
151 void hvl_GenSquare( int8 *buf )
153 uint32 i, j;
155 for( i=1; i<=0x20; i++ )
157 for( j=0; j<(0x40-i)*2; j++ )
158 *buf++ = 0x80;
159 for( j=0; j<i*2; j++ )
160 *buf++ = 0x7f;
164 static inline float64 clip( float64 x )
166 if( x > 127.f )
167 x = 127.f;
168 else if( x < -128.f )
169 x = -128.f;
170 return x;
173 void hvl_GenFilterWaves( int8 *buf, int8 *lowbuf, int8 *highbuf )
175 static const uint16 lentab[45] = { 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 3, 7, 0xf, 0x1f, 0x3f, 0x7f,
176 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
177 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
178 (0x280*3)-1 };
180 float64 freq;
181 uint32 temp;
183 for( temp=0, freq=8.f; temp<31; temp++, freq+=3.f )
185 uint32 wv;
186 int8 *a0 = buf;
188 for( wv=0; wv<6+6+0x20+1; wv++ )
190 float64 fre, high, mid, low;
191 uint32 i;
193 mid = 0.f;
194 low = 0.f;
195 fre = freq * 1.25f / 100.0f;
197 for( i=0; i<=lentab[wv]; i++ )
199 high = a0[i] - mid - low;
200 high = clip( high );
201 mid += high * fre;
202 mid = clip( mid );
203 low += mid * fre;
204 low = clip( low );
207 for( i=0; i<=lentab[wv]; i++ )
209 high = a0[i] - mid - low;
210 high = clip( high );
211 mid += high * fre;
212 mid = clip( mid );
213 low += mid * fre;
214 low = clip( low );
215 *lowbuf++ = (int8)low;
216 *highbuf++ = (int8)high;
219 a0 += lentab[wv]+1;
224 void hvl_GenWhiteNoise( int8 *buf, uint32 len )
226 uint32 ays;
228 ays = 0x41595321;
230 do {
231 uint16 ax, bx;
232 int8 s;
234 s = ays;
236 if( ays & 0x100 )
238 s = 0x80;
240 if( (int32)(ays & 0xffff) >= 0 )
241 s = 0x7f;
244 *buf++ = s;
245 len--;
247 ays = (ays >> 5) | (ays << 27);
248 ays = (ays & 0xffffff00) | ((ays & 0xff) ^ 0x9a);
249 bx = ays;
250 ays = (ays << 2) | (ays >> 30);
251 ax = ays;
252 bx += ax;
253 ax ^= bx;
254 ays = (ays & 0xffff0000) | ax;
255 ays = (ays >> 3) | (ays << 29);
256 } while( len );
259 void hvl_reset_some_stuff( struct hvl_tune *ht )
261 uint32 i;
263 for( i=0; i<MAX_CHANNELS; i++ )
265 ht->ht_Voices[i].vc_Delta=1;
266 ht->ht_Voices[i].vc_OverrideTranspose=1000; // 1.5
267 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;
268 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;
269 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;
270 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;
271 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;
272 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;
273 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;
274 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;
275 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;
276 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;
277 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;
278 ht->ht_Voices[i].vc_PerfList=0;
279 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;
281 ht->ht_Voices[i].vc_RingMixSource = NULL;
282 ht->ht_Voices[i].vc_RingAudioSource = NULL;
284 memset(&ht->ht_Voices[i].vc_SquareTempBuffer,0,0x80);
285 memset(&ht->ht_Voices[i].vc_ADSR,0,sizeof(struct hvl_envelope));
286 memset(&ht->ht_Voices[i].vc_VoiceBuffer,0,0x281);
287 memset(&ht->ht_Voices[i].vc_RingVoiceBuffer,0,0x281);
290 for( i=0; i<MAX_CHANNELS; i++ )
292 ht->ht_Voices[i].vc_WNRandom = 0x280;
293 ht->ht_Voices[i].vc_VoiceNum = i;
294 ht->ht_Voices[i].vc_TrackMasterVolume = 0x40;
295 ht->ht_Voices[i].vc_TrackOn = 1;
296 ht->ht_Voices[i].vc_MixSource = ht->ht_Voices[i].vc_VoiceBuffer;
300 BOOL hvl_InitSubsong( struct hvl_tune *ht, uint32 nr )
302 uint32 PosNr, i;
304 if( nr > ht->ht_SubsongNr )
305 return FALSE;
307 ht->ht_SongNum = nr;
309 PosNr = 0;
310 if( nr ) PosNr = ht->ht_Subsongs[nr-1];
312 ht->ht_PosNr = PosNr;
313 ht->ht_PosJump = 0;
314 ht->ht_PatternBreak = 0;
315 ht->ht_NoteNr = 0;
316 ht->ht_PosJumpNote = 0;
317 ht->ht_Tempo = 6;
318 ht->ht_StepWaitFrames = 0;
319 ht->ht_GetNewPosition = 1;
320 ht->ht_SongEndReached = 0;
321 ht->ht_PlayingTime = 0;
323 for( i=0; i<MAX_CHANNELS; i+=4 )
325 ht->ht_Voices[i+0].vc_Pan = ht->ht_defpanleft;
326 ht->ht_Voices[i+0].vc_SetPan = ht->ht_defpanleft; // 1.4
327 ht->ht_Voices[i+0].vc_PanMultLeft = panning_left[ht->ht_defpanleft];
328 ht->ht_Voices[i+0].vc_PanMultRight = panning_right[ht->ht_defpanleft];
329 ht->ht_Voices[i+1].vc_Pan = ht->ht_defpanright;
330 ht->ht_Voices[i+1].vc_SetPan = ht->ht_defpanright; // 1.4
331 ht->ht_Voices[i+1].vc_PanMultLeft = panning_left[ht->ht_defpanright];
332 ht->ht_Voices[i+1].vc_PanMultRight = panning_right[ht->ht_defpanright];
333 ht->ht_Voices[i+2].vc_Pan = ht->ht_defpanright;
334 ht->ht_Voices[i+2].vc_SetPan = ht->ht_defpanright; // 1.4
335 ht->ht_Voices[i+2].vc_PanMultLeft = panning_left[ht->ht_defpanright];
336 ht->ht_Voices[i+2].vc_PanMultRight = panning_right[ht->ht_defpanright];
337 ht->ht_Voices[i+3].vc_Pan = ht->ht_defpanleft;
338 ht->ht_Voices[i+3].vc_SetPan = ht->ht_defpanleft; // 1.4
339 ht->ht_Voices[i+3].vc_PanMultLeft = panning_left[ht->ht_defpanleft];
340 ht->ht_Voices[i+3].vc_PanMultRight = panning_right[ht->ht_defpanleft];
343 hvl_reset_some_stuff( ht );
345 return TRUE;
348 void hvl_InitReplayer( void )
350 hvl_GenPanningTables();
351 hvl_GenSawtooth( &waves[WO_SAWTOOTH_04], 0x04 );
352 hvl_GenSawtooth( &waves[WO_SAWTOOTH_08], 0x08 );
353 hvl_GenSawtooth( &waves[WO_SAWTOOTH_10], 0x10 );
354 hvl_GenSawtooth( &waves[WO_SAWTOOTH_20], 0x20 );
355 hvl_GenSawtooth( &waves[WO_SAWTOOTH_40], 0x40 );
356 hvl_GenSawtooth( &waves[WO_SAWTOOTH_80], 0x80 );
357 hvl_GenTriangle( &waves[WO_TRIANGLE_04], 0x04 );
358 hvl_GenTriangle( &waves[WO_TRIANGLE_08], 0x08 );
359 hvl_GenTriangle( &waves[WO_TRIANGLE_10], 0x10 );
360 hvl_GenTriangle( &waves[WO_TRIANGLE_20], 0x20 );
361 hvl_GenTriangle( &waves[WO_TRIANGLE_40], 0x40 );
362 hvl_GenTriangle( &waves[WO_TRIANGLE_80], 0x80 );
363 hvl_GenSquare( &waves[WO_SQUARES] );
364 hvl_GenWhiteNoise( &waves[WO_WHITENOISE], WHITENOISELEN );
365 hvl_GenFilterWaves( &waves[WO_TRIANGLE_04], &waves[WO_LOWPASSES], &waves[WO_HIGHPASSES] );
368 struct hvl_tune *hvl_load_ahx( uint8 *buf, uint32 buflen, uint32 defstereo, uint32 freq )
370 uint8 *bptr;
371 TEXT *nptr;
372 uint32 i, j, k, l, posn, insn, ssn, hs, trkn, trkl;
373 struct hvl_tune *ht;
374 struct hvl_plsentry *ple;
375 int32 defgain[] = { 71, 72, 76, 85, 100 };
377 posn = ((buf[6]&0x0f)<<8)|buf[7];
378 insn = buf[12];
379 ssn = buf[13];
380 trkl = buf[10];
381 trkn = buf[11];
383 hs = sizeof( struct hvl_tune );
384 hs += sizeof( struct hvl_position ) * posn;
385 hs += sizeof( struct hvl_instrument ) * (insn+1);
386 hs += sizeof( uint16 ) * ssn;
388 // Calculate the size of all instrument PList buffers
389 bptr = &buf[14];
390 bptr += ssn*2; // Skip past the subsong list
391 bptr += posn*4*2; // Skip past the positions
392 bptr += trkn*trkl*3;
393 if((buf[6]&0x80)==0) bptr += trkl*3;
395 // *NOW* we can finally calculate PList space
396 for( i=1; i<=insn; i++ )
398 hs += bptr[21] * sizeof( struct hvl_plsentry );
399 bptr += 22 + bptr[21]*4;
402 ht = malloc( hs );
403 if( !ht )
405 free( buf );
406 printf( "Out of memory!\n" );
407 return NULL;
410 ht->ht_Frequency = freq;
411 ht->ht_FreqF = (float64)freq;
413 ht->ht_Positions = (struct hvl_position *)(&ht[1]);
414 ht->ht_Instruments = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
415 ht->ht_Subsongs = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
416 ple = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
418 ht->ht_WaveformTab[0] = &waves[WO_TRIANGLE_04];
419 ht->ht_WaveformTab[1] = &waves[WO_SAWTOOTH_04];
420 ht->ht_WaveformTab[3] = &waves[WO_WHITENOISE];
422 ht->ht_Channels = 4;
423 ht->ht_PositionNr = posn;
424 ht->ht_Restart = (buf[8]<<8)|buf[9];
425 ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
426 ht->ht_TrackLength = trkl;
427 ht->ht_TrackNr = trkn;
428 ht->ht_InstrumentNr = insn;
429 ht->ht_SubsongNr = ssn;
430 ht->ht_defstereo = defstereo;
431 ht->ht_defpanleft = stereopan_left[ht->ht_defstereo];
432 ht->ht_defpanright = stereopan_right[ht->ht_defstereo];
433 ht->ht_mixgain = (defgain[ht->ht_defstereo]*256)/100;
435 if( ht->ht_Restart >= ht->ht_PositionNr )
436 ht->ht_Restart = ht->ht_PositionNr-1;
438 // Do some validation
439 if( ( ht->ht_PositionNr > 1000 ) ||
440 ( ht->ht_TrackLength > 64 ) ||
441 ( ht->ht_InstrumentNr > 64 ) )
443 printf( "%d,%d,%d\n", ht->ht_PositionNr,
444 ht->ht_TrackLength,
445 ht->ht_InstrumentNr );
446 free( ht );
447 free( buf );
448 printf( "Invalid file.\n" );
449 return NULL;
452 strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
453 nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
455 bptr = &buf[14];
457 // Subsongs
458 for( i=0; i<ht->ht_SubsongNr; i++ )
460 ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
461 if( ht->ht_Subsongs[i] >= ht->ht_PositionNr )
462 ht->ht_Subsongs[i] = 0;
463 bptr += 2;
466 // Position list
467 for( i=0; i<ht->ht_PositionNr; i++ )
469 for( j=0; j<4; j++ )
471 ht->ht_Positions[i].pos_Track[j] = *bptr++;
472 ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
476 // Tracks
477 for( i=0; i<=ht->ht_TrackNr; i++ )
479 if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
481 for( j=0; j<ht->ht_TrackLength; j++ )
483 ht->ht_Tracks[i][j].stp_Note = 0;
484 ht->ht_Tracks[i][j].stp_Instrument = 0;
485 ht->ht_Tracks[i][j].stp_FX = 0;
486 ht->ht_Tracks[i][j].stp_FXParam = 0;
487 ht->ht_Tracks[i][j].stp_FXb = 0;
488 ht->ht_Tracks[i][j].stp_FXbParam = 0;
490 continue;
493 for( j=0; j<ht->ht_TrackLength; j++ )
495 ht->ht_Tracks[i][j].stp_Note = (bptr[0]>>2)&0x3f;
496 ht->ht_Tracks[i][j].stp_Instrument = ((bptr[0]&0x3)<<4) | (bptr[1]>>4);
497 ht->ht_Tracks[i][j].stp_FX = bptr[1]&0xf;
498 ht->ht_Tracks[i][j].stp_FXParam = bptr[2];
499 ht->ht_Tracks[i][j].stp_FXb = 0;
500 ht->ht_Tracks[i][j].stp_FXbParam = 0;
501 bptr += 3;
505 // Instruments
506 for( i=1; i<=ht->ht_InstrumentNr; i++ )
508 if( nptr < (TEXT *)(buf+buflen) )
510 strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
511 nptr += strlen( nptr )+1;
512 } else {
513 ht->ht_Instruments[i].ins_Name[0] = 0;
516 ht->ht_Instruments[i].ins_Volume = bptr[0];
517 ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
518 ht->ht_Instruments[i].ins_WaveLength = bptr[1]&0x07;
520 ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
521 ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
522 ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
523 ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
524 ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
525 ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
526 ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
528 ht->ht_Instruments[i].ins_FilterLowerLimit = bptr[12]&0x7f;
529 ht->ht_Instruments[i].ins_VibratoDelay = bptr[13];
530 ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
531 ht->ht_Instruments[i].ins_HardCutRelease = bptr[14]&0x80?1:0;
532 ht->ht_Instruments[i].ins_VibratoDepth = bptr[14]&0x0f;
533 ht->ht_Instruments[i].ins_VibratoSpeed = bptr[15];
534 ht->ht_Instruments[i].ins_SquareLowerLimit = bptr[16];
535 ht->ht_Instruments[i].ins_SquareUpperLimit = bptr[17];
536 ht->ht_Instruments[i].ins_SquareSpeed = bptr[18];
537 ht->ht_Instruments[i].ins_FilterUpperLimit = bptr[19]&0x3f;
538 ht->ht_Instruments[i].ins_PList.pls_Speed = bptr[20];
539 ht->ht_Instruments[i].ins_PList.pls_Length = bptr[21];
541 ht->ht_Instruments[i].ins_PList.pls_Entries = ple;
542 ple += bptr[21];
544 bptr += 22;
545 for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
547 k = (bptr[0]>>5)&7;
548 if( k == 6 ) k = 12;
549 if( k == 7 ) k = 15;
550 l = (bptr[0]>>2)&7;
551 if( l == 6 ) l = 12;
552 if( l == 7 ) l = 15;
553 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1] = k;
554 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0] = l;
555 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform = ((bptr[0]<<1)&6) | (bptr[1]>>7);
556 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed = (bptr[1]>>6)&1;
557 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note = bptr[1]&0x3f;
558 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[2];
559 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[3];
561 // 1.6: Strip "toggle filter" commands if the module is
562 // version 0 (pre-filters). This is what AHX also does.
563 if( ( buf[3] == 0 ) && ( l == 4 ) && ( (bptr[2]&0xf0) != 0 ) )
564 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] &= 0x0f;
565 if( ( buf[3] == 0 ) && ( k == 4 ) && ( (bptr[3]&0xf0) != 0 ) )
566 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] &= 0x0f;
568 bptr += 4;
572 hvl_InitSubsong( ht, 0 );
573 free( buf );
574 return ht;
577 struct hvl_tune *hvl_LoadTune( TEXT *name, uint32 freq, uint32 defstereo )
579 struct hvl_tune *ht;
580 uint8 *buf, *bptr;
581 TEXT *nptr;
582 uint32 buflen, i, j, posn, insn, ssn, chnn, hs, trkl, trkn;
583 FILE *fh;
584 struct hvl_plsentry *ple;
586 fh = fopen( name, "rb" );
587 if( !fh )
589 printf( "Can't open file\n" );
590 return NULL;
593 fseek( fh, 0, SEEK_END );
594 buflen = ftell( fh );
595 fseek( fh, 0, SEEK_SET );
597 buf = malloc( buflen );
598 if( !buf )
600 fclose( fh );
601 printf( "Out of memory!\n" );
602 return NULL;
605 if( fread( buf, 1, buflen, fh ) != buflen )
607 fclose( fh );
608 free( buf );
609 printf( "Unable to read from file!\n" );
610 return NULL;
612 fclose( fh );
614 if( ( buf[0] == 'T' ) &&
615 ( buf[1] == 'H' ) &&
616 ( buf[2] == 'X' ) &&
617 ( buf[3] < 3 ) )
618 return hvl_load_ahx( buf, buflen, defstereo, freq );
620 if( ( buf[0] != 'H' ) ||
621 ( buf[1] != 'V' ) ||
622 ( buf[2] != 'L' ) ||
623 ( buf[3] > 1 ) )
625 free( buf );
626 printf( "Invalid file.\n" );
627 return NULL;
630 posn = ((buf[6]&0x0f)<<8)|buf[7];
631 insn = buf[12];
632 ssn = buf[13];
633 chnn = (buf[8]>>2)+4;
634 trkl = buf[10];
635 trkn = buf[11];
637 hs = sizeof( struct hvl_tune );
638 hs += sizeof( struct hvl_position ) * posn;
639 hs += sizeof( struct hvl_instrument ) * (insn+1);
640 hs += sizeof( uint16 ) * ssn;
642 // Calculate the size of all instrument PList buffers
643 bptr = &buf[16];
644 bptr += ssn*2; // Skip past the subsong list
645 bptr += posn*chnn*2; // Skip past the positions
647 // Skip past the tracks
648 // 1.4: Fixed two really stupid bugs that cancelled each other
649 // out if the module had a blank first track (which is how
650 // come they were missed.
651 for( i=((buf[6]&0x80)==0x80)?1:0; i<=trkn; i++ )
652 for( j=0; j<trkl; j++ )
654 if( bptr[0] == 0x3f )
656 bptr++;
657 continue;
659 bptr += 5;
662 // *NOW* we can finally calculate PList space
663 for( i=1; i<=insn; i++ )
665 hs += bptr[21] * sizeof( struct hvl_plsentry );
666 bptr += 22 + bptr[21]*5;
669 ht = malloc( hs );
670 if( !ht )
672 free( buf );
673 printf( "Out of memory!\n" );
674 return NULL;
677 ht->ht_Version = buf[3]; // 1.5
678 ht->ht_Frequency = freq;
679 ht->ht_FreqF = (float64)freq;
681 ht->ht_Positions = (struct hvl_position *)(&ht[1]);
682 ht->ht_Instruments = (struct hvl_instrument *)(&ht->ht_Positions[posn]);
683 ht->ht_Subsongs = (uint16 *)(&ht->ht_Instruments[(insn+1)]);
684 ple = (struct hvl_plsentry *)(&ht->ht_Subsongs[ssn]);
686 ht->ht_WaveformTab[0] = &waves[WO_TRIANGLE_04];
687 ht->ht_WaveformTab[1] = &waves[WO_SAWTOOTH_04];
688 ht->ht_WaveformTab[3] = &waves[WO_WHITENOISE];
690 ht->ht_PositionNr = posn;
691 ht->ht_Channels = (buf[8]>>2)+4;
692 ht->ht_Restart = ((buf[8]&3)<<8)|buf[9];
693 ht->ht_SpeedMultiplier = ((buf[6]>>5)&3)+1;
694 ht->ht_TrackLength = buf[10];
695 ht->ht_TrackNr = buf[11];
696 ht->ht_InstrumentNr = insn;
697 ht->ht_SubsongNr = ssn;
698 ht->ht_mixgain = (buf[14]<<8)/100;
699 ht->ht_defstereo = buf[15];
700 ht->ht_defpanleft = stereopan_left[ht->ht_defstereo];
701 ht->ht_defpanright = stereopan_right[ht->ht_defstereo];
703 if( ht->ht_Restart >= ht->ht_PositionNr )
704 ht->ht_Restart = ht->ht_PositionNr-1;
706 // Do some validation
707 if( ( ht->ht_PositionNr > 1000 ) ||
708 ( ht->ht_TrackLength > 64 ) ||
709 ( ht->ht_InstrumentNr > 64 ) )
711 printf( "%d,%d,%d\n", ht->ht_PositionNr,
712 ht->ht_TrackLength,
713 ht->ht_InstrumentNr );
714 free( ht );
715 free( buf );
716 printf( "Invalid file.\n" );
717 return NULL;
720 strncpy( ht->ht_Name, (TEXT *)&buf[(buf[4]<<8)|buf[5]], 128 );
721 nptr = (TEXT *)&buf[((buf[4]<<8)|buf[5])+strlen( ht->ht_Name )+1];
723 bptr = &buf[16];
725 // Subsongs
726 for( i=0; i<ht->ht_SubsongNr; i++ )
728 ht->ht_Subsongs[i] = (bptr[0]<<8)|bptr[1];
729 bptr += 2;
732 // Position list
733 for( i=0; i<ht->ht_PositionNr; i++ )
735 for( j=0; j<ht->ht_Channels; j++ )
737 ht->ht_Positions[i].pos_Track[j] = *bptr++;
738 ht->ht_Positions[i].pos_Transpose[j] = *(int8 *)bptr++;
742 // Tracks
743 for( i=0; i<=ht->ht_TrackNr; i++ )
745 if( ( ( buf[6]&0x80 ) == 0x80 ) && ( i == 0 ) )
747 for( j=0; j<ht->ht_TrackLength; j++ )
749 ht->ht_Tracks[i][j].stp_Note = 0;
750 ht->ht_Tracks[i][j].stp_Instrument = 0;
751 ht->ht_Tracks[i][j].stp_FX = 0;
752 ht->ht_Tracks[i][j].stp_FXParam = 0;
753 ht->ht_Tracks[i][j].stp_FXb = 0;
754 ht->ht_Tracks[i][j].stp_FXbParam = 0;
756 continue;
759 for( j=0; j<ht->ht_TrackLength; j++ )
761 if( bptr[0] == 0x3f )
763 ht->ht_Tracks[i][j].stp_Note = 0;
764 ht->ht_Tracks[i][j].stp_Instrument = 0;
765 ht->ht_Tracks[i][j].stp_FX = 0;
766 ht->ht_Tracks[i][j].stp_FXParam = 0;
767 ht->ht_Tracks[i][j].stp_FXb = 0;
768 ht->ht_Tracks[i][j].stp_FXbParam = 0;
769 bptr++;
770 continue;
773 ht->ht_Tracks[i][j].stp_Note = bptr[0];
774 ht->ht_Tracks[i][j].stp_Instrument = bptr[1];
775 ht->ht_Tracks[i][j].stp_FX = bptr[2]>>4;
776 ht->ht_Tracks[i][j].stp_FXParam = bptr[3];
777 ht->ht_Tracks[i][j].stp_FXb = bptr[2]&0xf;
778 ht->ht_Tracks[i][j].stp_FXbParam = bptr[4];
779 bptr += 5;
784 // Instruments
785 for( i=1; i<=ht->ht_InstrumentNr; i++ )
787 if( nptr < (TEXT *)(buf+buflen) )
789 strncpy( ht->ht_Instruments[i].ins_Name, nptr, 128 );
790 nptr += strlen( nptr )+1;
791 } else {
792 ht->ht_Instruments[i].ins_Name[0] = 0;
795 ht->ht_Instruments[i].ins_Volume = bptr[0];
796 ht->ht_Instruments[i].ins_FilterSpeed = ((bptr[1]>>3)&0x1f)|((bptr[12]>>2)&0x20);
797 ht->ht_Instruments[i].ins_WaveLength = bptr[1]&0x07;
799 ht->ht_Instruments[i].ins_Envelope.aFrames = bptr[2];
800 ht->ht_Instruments[i].ins_Envelope.aVolume = bptr[3];
801 ht->ht_Instruments[i].ins_Envelope.dFrames = bptr[4];
802 ht->ht_Instruments[i].ins_Envelope.dVolume = bptr[5];
803 ht->ht_Instruments[i].ins_Envelope.sFrames = bptr[6];
804 ht->ht_Instruments[i].ins_Envelope.rFrames = bptr[7];
805 ht->ht_Instruments[i].ins_Envelope.rVolume = bptr[8];
807 ht->ht_Instruments[i].ins_FilterLowerLimit = bptr[12]&0x7f;
808 ht->ht_Instruments[i].ins_VibratoDelay = bptr[13];
809 ht->ht_Instruments[i].ins_HardCutReleaseFrames = (bptr[14]>>4)&0x07;
810 ht->ht_Instruments[i].ins_HardCutRelease = bptr[14]&0x80?1:0;
811 ht->ht_Instruments[i].ins_VibratoDepth = bptr[14]&0x0f;
812 ht->ht_Instruments[i].ins_VibratoSpeed = bptr[15];
813 ht->ht_Instruments[i].ins_SquareLowerLimit = bptr[16];
814 ht->ht_Instruments[i].ins_SquareUpperLimit = bptr[17];
815 ht->ht_Instruments[i].ins_SquareSpeed = bptr[18];
816 ht->ht_Instruments[i].ins_FilterUpperLimit = bptr[19]&0x3f;
817 ht->ht_Instruments[i].ins_PList.pls_Speed = bptr[20];
818 ht->ht_Instruments[i].ins_PList.pls_Length = bptr[21];
820 ht->ht_Instruments[i].ins_PList.pls_Entries = ple;
821 ple += bptr[21];
823 bptr += 22;
824 for( j=0; j<ht->ht_Instruments[i].ins_PList.pls_Length; j++ )
826 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[0] = bptr[0]&0xf;
827 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FX[1] = (bptr[1]>>3)&0xf;
828 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Waveform = bptr[1]&7;
829 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Fixed = (bptr[2]>>6)&1;
830 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_Note = bptr[2]&0x3f;
831 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[0] = bptr[3];
832 ht->ht_Instruments[i].ins_PList.pls_Entries[j].ple_FXParam[1] = bptr[4];
833 bptr += 5;
837 hvl_InitSubsong( ht, 0 );
838 free( buf );
839 return ht;
842 void hvl_FreeTune( struct hvl_tune *ht )
844 if( !ht ) return;
845 free( ht );
848 void hvl_process_stepfx_1( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
850 switch( FX )
852 case 0x0: // Position Jump HI
853 if( ((FXParam&0x0f) > 0) && ((FXParam&0x0f) <= 9) )
854 ht->ht_PosJump = FXParam & 0xf;
855 break;
857 case 0x5: // Volume Slide + Tone Portamento
858 case 0xa: // Volume Slide
859 voice->vc_VolumeSlideDown = FXParam & 0x0f;
860 voice->vc_VolumeSlideUp = FXParam >> 4;
861 break;
863 case 0x7: // Panning
864 if( FXParam > 127 )
865 FXParam -= 256;
866 voice->vc_Pan = (FXParam+128);
867 voice->vc_SetPan = (FXParam+128); // 1.4
868 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
869 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
870 break;
872 case 0xb: // Position jump
873 ht->ht_PosJump = ht->ht_PosJump*100 + (FXParam & 0x0f) + (FXParam >> 4)*10;
874 ht->ht_PatternBreak = 1;
875 if( ht->ht_PosJump <= ht->ht_PosNr )
876 ht->ht_SongEndReached = 1;
877 break;
879 case 0xd: // Pattern break
880 ht->ht_PosJump = ht->ht_PosNr+1;
881 ht->ht_PosJumpNote = (FXParam & 0x0f) + (FXParam>>4)*10;
882 ht->ht_PatternBreak = 1;
883 if( ht->ht_PosJumpNote > ht->ht_TrackLength )
884 ht->ht_PosJumpNote = 0;
885 break;
887 case 0xe: // Extended commands
888 switch( FXParam >> 4 )
890 case 0xc: // Note cut
891 if( (FXParam & 0x0f) < ht->ht_Tempo )
893 voice->vc_NoteCutWait = FXParam & 0x0f;
894 if( voice->vc_NoteCutWait )
896 voice->vc_NoteCutOn = 1;
897 voice->vc_HardCutRelease = 0;
900 break;
902 // 1.6: 0xd case removed
904 break;
906 case 0xf: // Speed
907 ht->ht_Tempo = FXParam;
908 if( FXParam == 0 )
909 ht->ht_SongEndReached = 1;
910 break;
914 void hvl_process_stepfx_2( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam, int32 *Note )
916 switch( FX )
918 case 0x9: // Set squarewave offset
919 voice->vc_SquarePos = FXParam >> (5 - voice->vc_WaveLength);
920 voice->vc_PlantSquare = 1;
921 voice->vc_IgnoreSquare = 1;
922 break;
924 case 0x5: // Tone portamento + volume slide
925 case 0x3: // Tone portamento
926 if( FXParam != 0 ) voice->vc_PeriodSlideSpeed = FXParam;
928 if( *Note )
930 int32 new, diff;
932 new = period_tab[*Note];
933 diff = period_tab[voice->vc_TrackPeriod];
934 diff -= new;
935 new = diff + voice->vc_PeriodSlidePeriod;
937 if( new )
938 voice->vc_PeriodSlideLimit = -diff;
940 voice->vc_PeriodSlideOn = 1;
941 voice->vc_PeriodSlideWithLimit = 1;
942 *Note = 0;
943 break;
947 void hvl_process_stepfx_3( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
949 int32 i;
951 switch( FX )
953 case 0x01: // Portamento up (period slide down)
954 voice->vc_PeriodSlideSpeed = -FXParam;
955 voice->vc_PeriodSlideOn = 1;
956 voice->vc_PeriodSlideWithLimit = 0;
957 break;
958 case 0x02: // Portamento down
959 voice->vc_PeriodSlideSpeed = FXParam;
960 voice->vc_PeriodSlideOn = 1;
961 voice->vc_PeriodSlideWithLimit = 0;
962 break;
963 case 0x04: // Filter override
964 if( ( FXParam == 0 ) || ( FXParam == 0x40 ) ) break;
965 if( FXParam < 0x40 )
967 voice->vc_IgnoreFilter = FXParam;
968 break;
970 if( FXParam > 0x7f ) break;
971 voice->vc_FilterPos = FXParam - 0x40;
972 break;
973 case 0x0c: // Volume
974 FXParam &= 0xff;
975 if( FXParam <= 0x40 )
977 voice->vc_NoteMaxVolume = FXParam;
978 break;
981 if( (FXParam -= 0x50) < 0 ) break; // 1.6
983 if( FXParam <= 0x40 )
985 for( i=0; i<ht->ht_Channels; i++ )
986 ht->ht_Voices[i].vc_TrackMasterVolume = FXParam;
987 break;
990 if( (FXParam -= 0xa0-0x50) < 0 ) break; // 1.6
992 if( FXParam <= 0x40 )
993 voice->vc_TrackMasterVolume = FXParam;
994 break;
996 case 0xe: // Extended commands;
997 switch( FXParam >> 4 )
999 case 0x1: // Fineslide up
1000 voice->vc_PeriodSlidePeriod = -(FXParam & 0x0f);
1001 voice->vc_PlantPeriod = 1;
1002 break;
1004 case 0x2: // Fineslide down
1005 voice->vc_PeriodSlidePeriod = (FXParam & 0x0f);
1006 voice->vc_PlantPeriod = 1;
1007 break;
1009 case 0x4: // Vibrato control
1010 voice->vc_VibratoDepth = FXParam & 0x0f;
1011 break;
1013 case 0x0a: // Fine volume up
1014 voice->vc_NoteMaxVolume += FXParam & 0x0f;
1016 if( voice->vc_NoteMaxVolume > 0x40 )
1017 voice->vc_NoteMaxVolume = 0x40;
1018 break;
1020 case 0x0b: // Fine volume down
1021 voice->vc_NoteMaxVolume -= FXParam & 0x0f;
1023 if( voice->vc_NoteMaxVolume < 0 )
1024 voice->vc_NoteMaxVolume = 0;
1025 break;
1027 case 0x0f: // Misc flags (1.5)
1028 if( ht->ht_Version < 1 ) break;
1029 switch( FXParam & 0xf )
1031 case 1:
1032 voice->vc_OverrideTranspose = voice->vc_Transpose;
1033 break;
1035 break;
1037 break;
1041 void hvl_process_step( struct hvl_tune *ht, struct hvl_voice *voice )
1043 int32 Note, Instr, donenotedel;
1044 struct hvl_step *Step;
1046 if( voice->vc_TrackOn == 0 )
1047 return;
1049 voice->vc_VolumeSlideUp = voice->vc_VolumeSlideDown = 0;
1051 Step = &ht->ht_Tracks[ht->ht_Positions[ht->ht_PosNr].pos_Track[voice->vc_VoiceNum]][ht->ht_NoteNr];
1053 Note = Step->stp_Note;
1054 Instr = Step->stp_Instrument;
1056 // --------- 1.6: from here --------------
1058 donenotedel = 0;
1060 // Do notedelay here
1061 if( ((Step->stp_FX&0xf)==0xe) && ((Step->stp_FXParam&0xf0)==0xd0) )
1063 if( voice->vc_NoteDelayOn )
1065 voice->vc_NoteDelayOn = 0;
1066 donenotedel = 1;
1067 } else {
1068 if( (Step->stp_FXParam&0x0f) < ht->ht_Tempo )
1070 voice->vc_NoteDelayWait = Step->stp_FXParam & 0x0f;
1071 if( voice->vc_NoteDelayWait )
1073 voice->vc_NoteDelayOn = 1;
1074 return;
1080 if( (donenotedel==0) && ((Step->stp_FXb&0xf)==0xe) && ((Step->stp_FXbParam&0xf0)==0xd0) )
1082 if( voice->vc_NoteDelayOn )
1084 voice->vc_NoteDelayOn = 0;
1085 } else {
1086 if( (Step->stp_FXbParam&0x0f) < ht->ht_Tempo )
1088 voice->vc_NoteDelayWait = Step->stp_FXbParam & 0x0f;
1089 if( voice->vc_NoteDelayWait )
1091 voice->vc_NoteDelayOn = 1;
1092 return;
1098 // --------- 1.6: to here --------------
1100 if( Note ) voice->vc_OverrideTranspose = 1000; // 1.5
1102 hvl_process_stepfx_1( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
1103 hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
1105 if( ( Instr ) && ( Instr <= ht->ht_InstrumentNr ) )
1107 struct hvl_instrument *Ins;
1108 int16 SquareLower, SquareUpper, d6, d3, d4;
1110 /* 1.4: Reset panning to last set position */
1111 voice->vc_Pan = voice->vc_SetPan;
1112 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
1113 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
1115 voice->vc_PeriodSlideSpeed = voice->vc_PeriodSlidePeriod = voice->vc_PeriodSlideLimit = 0;
1117 voice->vc_PerfSubVolume = 0x40;
1118 voice->vc_ADSRVolume = 0;
1119 voice->vc_Instrument = Ins = &ht->ht_Instruments[Instr];
1120 voice->vc_SamplePos = 0;
1122 voice->vc_ADSR.aFrames = Ins->ins_Envelope.aFrames;
1123 voice->vc_ADSR.aVolume = Ins->ins_Envelope.aVolume*256/voice->vc_ADSR.aFrames;
1124 voice->vc_ADSR.dFrames = Ins->ins_Envelope.dFrames;
1125 voice->vc_ADSR.dVolume = (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume)*256/voice->vc_ADSR.dFrames;
1126 voice->vc_ADSR.sFrames = Ins->ins_Envelope.sFrames;
1127 voice->vc_ADSR.rFrames = Ins->ins_Envelope.rFrames;
1128 voice->vc_ADSR.rVolume = (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume)*256/voice->vc_ADSR.rFrames;
1130 voice->vc_WaveLength = Ins->ins_WaveLength;
1131 voice->vc_NoteMaxVolume = Ins->ins_Volume;
1133 voice->vc_VibratoCurrent = 0;
1134 voice->vc_VibratoDelay = Ins->ins_VibratoDelay;
1135 voice->vc_VibratoDepth = Ins->ins_VibratoDepth;
1136 voice->vc_VibratoSpeed = Ins->ins_VibratoSpeed;
1137 voice->vc_VibratoPeriod = 0;
1139 voice->vc_HardCutRelease = Ins->ins_HardCutRelease;
1140 voice->vc_HardCut = Ins->ins_HardCutReleaseFrames;
1142 voice->vc_IgnoreSquare = voice->vc_SquareSlidingIn = 0;
1143 voice->vc_SquareWait = voice->vc_SquareOn = 0;
1145 SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength);
1146 SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength);
1148 if( SquareUpper < SquareLower )
1150 int16 t = SquareUpper;
1151 SquareUpper = SquareLower;
1152 SquareLower = t;
1155 voice->vc_SquareUpperLimit = SquareUpper;
1156 voice->vc_SquareLowerLimit = SquareLower;
1158 voice->vc_IgnoreFilter = voice->vc_FilterWait = voice->vc_FilterOn = 0;
1159 voice->vc_FilterSlidingIn = 0;
1161 d6 = Ins->ins_FilterSpeed;
1162 d3 = Ins->ins_FilterLowerLimit;
1163 d4 = Ins->ins_FilterUpperLimit;
1165 if( d3 & 0x80 ) d6 |= 0x20;
1166 if( d4 & 0x80 ) d6 |= 0x40;
1168 voice->vc_FilterSpeed = d6;
1169 d3 &= ~0x80;
1170 d4 &= ~0x80;
1172 if( d3 > d4 )
1174 int16 t = d3;
1175 d3 = d4;
1176 d4 = t;
1179 voice->vc_FilterUpperLimit = d4;
1180 voice->vc_FilterLowerLimit = d3;
1181 voice->vc_FilterPos = 32;
1183 voice->vc_PerfWait = voice->vc_PerfCurrent = 0;
1184 voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed;
1185 voice->vc_PerfList = &voice->vc_Instrument->ins_PList;
1187 voice->vc_RingMixSource = NULL; // No ring modulation
1188 voice->vc_RingSamplePos = 0;
1189 voice->vc_RingPlantPeriod = 0;
1190 voice->vc_RingNewWaveform = 0;
1193 voice->vc_PeriodSlideOn = 0;
1195 hvl_process_stepfx_2( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam, &Note );
1196 hvl_process_stepfx_2( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note );
1198 if( Note )
1200 voice->vc_TrackPeriod = Note;
1201 voice->vc_PlantPeriod = 1;
1204 hvl_process_stepfx_3( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
1205 hvl_process_stepfx_3( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
1208 void hvl_plist_command_parse( struct hvl_tune *ht, struct hvl_voice *voice, int32 FX, int32 FXParam )
1210 switch( FX )
1212 case 0:
1213 if( ( FXParam > 0 ) && ( FXParam < 0x40 ) )
1215 if( voice->vc_IgnoreFilter )
1217 voice->vc_FilterPos = voice->vc_IgnoreFilter;
1218 voice->vc_IgnoreFilter = 0;
1219 } else {
1220 voice->vc_FilterPos = FXParam;
1222 voice->vc_NewWaveform = 1;
1224 break;
1226 case 1:
1227 voice->vc_PeriodPerfSlideSpeed = FXParam;
1228 voice->vc_PeriodPerfSlideOn = 1;
1229 break;
1231 case 2:
1232 voice->vc_PeriodPerfSlideSpeed = -FXParam;
1233 voice->vc_PeriodPerfSlideOn = 1;
1234 break;
1236 case 3:
1237 if( voice->vc_IgnoreSquare == 0 )
1238 voice->vc_SquarePos = FXParam >> (5-voice->vc_WaveLength);
1239 else
1240 voice->vc_IgnoreSquare = 0;
1241 break;
1243 case 4:
1244 if( FXParam == 0 )
1246 voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
1247 voice->vc_SquareSign = 1;
1248 } else {
1250 if( FXParam & 0x0f )
1252 voice->vc_SquareInit = (voice->vc_SquareOn ^= 1);
1253 voice->vc_SquareSign = 1;
1254 if(( FXParam & 0x0f ) == 0x0f )
1255 voice->vc_SquareSign = -1;
1258 if( FXParam & 0xf0 )
1260 voice->vc_FilterInit = (voice->vc_FilterOn ^= 1);
1261 voice->vc_FilterSign = 1;
1262 if(( FXParam & 0xf0 ) == 0xf0 )
1263 voice->vc_FilterSign = -1;
1266 break;
1268 case 5:
1269 voice->vc_PerfCurrent = FXParam;
1270 break;
1272 case 7:
1273 // Ring modulate with triangle
1274 if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
1276 voice->vc_RingBasePeriod = FXParam;
1277 voice->vc_RingFixedPeriod = 1;
1278 } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
1279 voice->vc_RingBasePeriod = FXParam-0x80;
1280 voice->vc_RingFixedPeriod = 0;
1281 } else {
1282 voice->vc_RingBasePeriod = 0;
1283 voice->vc_RingFixedPeriod = 0;
1284 voice->vc_RingNewWaveform = 0;
1285 voice->vc_RingAudioSource = NULL; // turn it off
1286 voice->vc_RingMixSource = NULL;
1287 break;
1289 voice->vc_RingWaveform = 0;
1290 voice->vc_RingNewWaveform = 1;
1291 voice->vc_RingPlantPeriod = 1;
1292 break;
1294 case 8: // Ring modulate with sawtooth
1295 if(( FXParam >= 1 ) && ( FXParam <= 0x3C ))
1297 voice->vc_RingBasePeriod = FXParam;
1298 voice->vc_RingFixedPeriod = 1;
1299 } else if(( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) {
1300 voice->vc_RingBasePeriod = FXParam-0x80;
1301 voice->vc_RingFixedPeriod = 0;
1302 } else {
1303 voice->vc_RingBasePeriod = 0;
1304 voice->vc_RingFixedPeriod = 0;
1305 voice->vc_RingNewWaveform = 0;
1306 voice->vc_RingAudioSource = NULL;
1307 voice->vc_RingMixSource = NULL;
1308 break;
1311 voice->vc_RingWaveform = 1;
1312 voice->vc_RingNewWaveform = 1;
1313 voice->vc_RingPlantPeriod = 1;
1314 break;
1316 /* New in HivelyTracker 1.4 */
1317 case 9:
1318 if( FXParam > 127 )
1319 FXParam -= 256;
1320 voice->vc_Pan = (FXParam+128);
1321 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
1322 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
1323 break;
1325 case 12:
1326 if( FXParam <= 0x40 )
1328 voice->vc_NoteMaxVolume = FXParam;
1329 break;
1332 if( (FXParam -= 0x50) < 0 ) break;
1334 if( FXParam <= 0x40 )
1336 voice->vc_PerfSubVolume = FXParam;
1337 break;
1340 if( (FXParam -= 0xa0-0x50) < 0 ) break;
1342 if( FXParam <= 0x40 )
1343 voice->vc_TrackMasterVolume = FXParam;
1344 break;
1346 case 15:
1347 voice->vc_PerfSpeed = voice->vc_PerfWait = FXParam;
1348 break;
1352 void hvl_process_frame( struct hvl_tune *ht, struct hvl_voice *voice )
1354 static uint8 Offsets[] = {0x00,0x04,0x04+0x08,0x04+0x08+0x10,0x04+0x08+0x10+0x20,0x04+0x08+0x10+0x20+0x40};
1356 if( voice->vc_TrackOn == 0 )
1357 return;
1359 if( voice->vc_NoteDelayOn )
1361 if( voice->vc_NoteDelayWait <= 0 )
1362 hvl_process_step( ht, voice );
1363 else
1364 voice->vc_NoteDelayWait--;
1367 if( voice->vc_HardCut )
1369 int32 nextinst;
1371 if( ht->ht_NoteNr+1 < ht->ht_TrackLength )
1372 nextinst = ht->ht_Tracks[voice->vc_Track][ht->ht_NoteNr+1].stp_Instrument;
1373 else
1374 nextinst = ht->ht_Tracks[voice->vc_NextTrack][0].stp_Instrument;
1376 if( nextinst )
1378 int32 d1;
1380 d1 = ht->ht_Tempo - voice->vc_HardCut;
1382 if( d1 < 0 ) d1 = 0;
1384 if( !voice->vc_NoteCutOn )
1386 voice->vc_NoteCutOn = 1;
1387 voice->vc_NoteCutWait = d1;
1388 voice->vc_HardCutReleaseF = -(d1-ht->ht_Tempo);
1389 } else {
1390 voice->vc_HardCut = 0;
1395 if( voice->vc_NoteCutOn )
1397 if( voice->vc_NoteCutWait <= 0 )
1399 voice->vc_NoteCutOn = 0;
1401 if( voice->vc_HardCutRelease )
1403 voice->vc_ADSR.rVolume = -(voice->vc_ADSRVolume - (voice->vc_Instrument->ins_Envelope.rVolume << 8)) / voice->vc_HardCutReleaseF;
1404 voice->vc_ADSR.rFrames = voice->vc_HardCutReleaseF;
1405 voice->vc_ADSR.aFrames = voice->vc_ADSR.dFrames = voice->vc_ADSR.sFrames = 0;
1406 } else {
1407 voice->vc_NoteMaxVolume = 0;
1409 } else {
1410 voice->vc_NoteCutWait--;
1414 // ADSR envelope
1415 if( voice->vc_ADSR.aFrames )
1417 voice->vc_ADSRVolume += voice->vc_ADSR.aVolume;
1419 if( --voice->vc_ADSR.aFrames <= 0 )
1420 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.aVolume << 8;
1422 } else if( voice->vc_ADSR.dFrames ) {
1424 voice->vc_ADSRVolume += voice->vc_ADSR.dVolume;
1426 if( --voice->vc_ADSR.dFrames <= 0 )
1427 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.dVolume << 8;
1429 } else if( voice->vc_ADSR.sFrames ) {
1431 voice->vc_ADSR.sFrames--;
1433 } else if( voice->vc_ADSR.rFrames ) {
1435 voice->vc_ADSRVolume += voice->vc_ADSR.rVolume;
1437 if( --voice->vc_ADSR.rFrames <= 0 )
1438 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.rVolume << 8;
1441 // VolumeSlide
1442 voice->vc_NoteMaxVolume = voice->vc_NoteMaxVolume + voice->vc_VolumeSlideUp - voice->vc_VolumeSlideDown;
1444 if( voice->vc_NoteMaxVolume < 0 )
1445 voice->vc_NoteMaxVolume = 0;
1446 else if( voice->vc_NoteMaxVolume > 0x40 )
1447 voice->vc_NoteMaxVolume = 0x40;
1449 // Portamento
1450 if( voice->vc_PeriodSlideOn )
1452 if( voice->vc_PeriodSlideWithLimit )
1454 int32 d0, d2;
1456 d0 = voice->vc_PeriodSlidePeriod - voice->vc_PeriodSlideLimit;
1457 d2 = voice->vc_PeriodSlideSpeed;
1459 if( d0 > 0 )
1460 d2 = -d2;
1462 if( d0 )
1464 int32 d3;
1466 d3 = (d0 + d2) ^ d0;
1468 if( d3 >= 0 )
1469 d0 = voice->vc_PeriodSlidePeriod + d2;
1470 else
1471 d0 = voice->vc_PeriodSlideLimit;
1473 voice->vc_PeriodSlidePeriod = d0;
1474 voice->vc_PlantPeriod = 1;
1476 } else {
1477 voice->vc_PeriodSlidePeriod += voice->vc_PeriodSlideSpeed;
1478 voice->vc_PlantPeriod = 1;
1482 // Vibrato
1483 if( voice->vc_VibratoDepth )
1485 if( voice->vc_VibratoDelay <= 0 )
1487 voice->vc_VibratoPeriod = (vib_tab[voice->vc_VibratoCurrent] * voice->vc_VibratoDepth) >> 7;
1488 voice->vc_PlantPeriod = 1;
1489 voice->vc_VibratoCurrent = (voice->vc_VibratoCurrent + voice->vc_VibratoSpeed) & 0x3f;
1490 } else {
1491 voice->vc_VibratoDelay--;
1495 // PList
1496 if( voice->vc_PerfList != 0 )
1498 if( voice->vc_Instrument && voice->vc_PerfCurrent < voice->vc_Instrument->ins_PList.pls_Length )
1500 if( --voice->vc_PerfWait <= 0 )
1502 uint32 i;
1503 int32 cur;
1505 cur = voice->vc_PerfCurrent++;
1506 voice->vc_PerfWait = voice->vc_PerfSpeed;
1508 if( voice->vc_PerfList->pls_Entries[cur].ple_Waveform )
1510 voice->vc_Waveform = voice->vc_PerfList->pls_Entries[cur].ple_Waveform-1;
1511 voice->vc_NewWaveform = 1;
1512 voice->vc_PeriodPerfSlideSpeed = voice->vc_PeriodPerfSlidePeriod = 0;
1515 // Holdwave
1516 voice->vc_PeriodPerfSlideOn = 0;
1518 for( i=0; i<2; i++ )
1519 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 );
1521 // GetNote
1522 if( voice->vc_PerfList->pls_Entries[cur].ple_Note )
1524 voice->vc_InstrPeriod = voice->vc_PerfList->pls_Entries[cur].ple_Note;
1525 voice->vc_PlantPeriod = 1;
1526 voice->vc_FixedNote = voice->vc_PerfList->pls_Entries[cur].ple_Fixed;
1529 } else {
1530 if( voice->vc_PerfWait )
1531 voice->vc_PerfWait--;
1532 else
1533 voice->vc_PeriodPerfSlideSpeed = 0;
1537 // PerfPortamento
1538 if( voice->vc_PeriodPerfSlideOn )
1540 voice->vc_PeriodPerfSlidePeriod -= voice->vc_PeriodPerfSlideSpeed;
1542 if( voice->vc_PeriodPerfSlidePeriod )
1543 voice->vc_PlantPeriod = 1;
1546 if( voice->vc_Waveform == 3-1 && voice->vc_SquareOn )
1548 if( --voice->vc_SquareWait <= 0 )
1550 int32 d1, d2, d3;
1552 d1 = voice->vc_SquareLowerLimit;
1553 d2 = voice->vc_SquareUpperLimit;
1554 d3 = voice->vc_SquarePos;
1556 if( voice->vc_SquareInit )
1558 voice->vc_SquareInit = 0;
1560 if( d3 <= d1 )
1562 voice->vc_SquareSlidingIn = 1;
1563 voice->vc_SquareSign = 1;
1564 } else if( d3 >= d2 ) {
1565 voice->vc_SquareSlidingIn = 1;
1566 voice->vc_SquareSign = -1;
1570 // NoSquareInit
1571 if( d1 == d3 || d2 == d3 )
1573 if( voice->vc_SquareSlidingIn )
1574 voice->vc_SquareSlidingIn = 0;
1575 else
1576 voice->vc_SquareSign = -voice->vc_SquareSign;
1579 d3 += voice->vc_SquareSign;
1580 voice->vc_SquarePos = d3;
1581 voice->vc_PlantSquare = 1;
1582 voice->vc_SquareWait = voice->vc_Instrument->ins_SquareSpeed;
1586 if( voice->vc_FilterOn && --voice->vc_FilterWait <= 0 )
1588 uint32 i, FMax;
1589 int32 d1, d2, d3;
1591 d1 = voice->vc_FilterLowerLimit;
1592 d2 = voice->vc_FilterUpperLimit;
1593 d3 = voice->vc_FilterPos;
1595 if( voice->vc_FilterInit )
1597 voice->vc_FilterInit = 0;
1598 if( d3 <= d1 )
1600 voice->vc_FilterSlidingIn = 1;
1601 voice->vc_FilterSign = 1;
1602 } else if( d3 >= d2 ) {
1603 voice->vc_FilterSlidingIn = 1;
1604 voice->vc_FilterSign = -1;
1608 // NoFilterInit
1609 FMax = (voice->vc_FilterSpeed < 3) ? (5-voice->vc_FilterSpeed) : 1;
1611 for( i=0; i<FMax; i++ )
1613 if( ( d1 == d3 ) || ( d2 == d3 ) )
1615 if( voice->vc_FilterSlidingIn )
1616 voice->vc_FilterSlidingIn = 0;
1617 else
1618 voice->vc_FilterSign = -voice->vc_FilterSign;
1620 d3 += voice->vc_FilterSign;
1623 if( d3 < 1 ) d3 = 1;
1624 if( d3 > 63 ) d3 = 63;
1625 voice->vc_FilterPos = d3;
1626 voice->vc_NewWaveform = 1;
1627 voice->vc_FilterWait = voice->vc_FilterSpeed - 3;
1629 if( voice->vc_FilterWait < 1 )
1630 voice->vc_FilterWait = 1;
1633 if( voice->vc_Waveform == 3-1 || voice->vc_PlantSquare )
1635 // CalcSquare
1636 uint32 i;
1637 int32 Delta;
1638 int8 *SquarePtr;
1639 int32 X;
1641 SquarePtr = &waves[WO_SQUARES+(voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3)];
1642 X = voice->vc_SquarePos << (5 - voice->vc_WaveLength);
1644 if( X > 0x20 )
1646 X = 0x40 - X;
1647 voice->vc_SquareReverse = 1;
1650 // OkDownSquare
1651 if( X > 0 )
1652 SquarePtr += (X-1) << 7;
1654 Delta = 32 >> voice->vc_WaveLength;
1655 ht->ht_WaveformTab[2] = voice->vc_SquareTempBuffer;
1657 for( i=0; i<(1<<voice->vc_WaveLength)*4; i++ )
1659 voice->vc_SquareTempBuffer[i] = *SquarePtr;
1660 SquarePtr += Delta;
1663 voice->vc_NewWaveform = 1;
1664 voice->vc_Waveform = 3-1;
1665 voice->vc_PlantSquare = 0;
1668 if( voice->vc_Waveform == 4-1 )
1669 voice->vc_NewWaveform = 1;
1671 if( voice->vc_RingNewWaveform )
1673 int8 *rasrc;
1675 if( voice->vc_RingWaveform > 1 ) voice->vc_RingWaveform = 1;
1677 rasrc = ht->ht_WaveformTab[voice->vc_RingWaveform];
1678 rasrc += Offsets[voice->vc_WaveLength];
1680 voice->vc_RingAudioSource = rasrc;
1684 if( voice->vc_NewWaveform )
1686 int8 *AudioSource;
1688 AudioSource = ht->ht_WaveformTab[voice->vc_Waveform];
1690 if( voice->vc_Waveform != 3-1 )
1691 AudioSource += (voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3);
1693 if( voice->vc_Waveform < 3-1)
1695 // GetWLWaveformlor2
1696 AudioSource += Offsets[voice->vc_WaveLength];
1699 if( voice->vc_Waveform == 4-1 )
1701 // AddRandomMoving
1702 AudioSource += ( voice->vc_WNRandom & (2*0x280-1) ) & ~1;
1703 // GoOnRandom
1704 voice->vc_WNRandom += 2239384;
1705 voice->vc_WNRandom = ((((voice->vc_WNRandom >> 8) | (voice->vc_WNRandom << 24)) + 782323) ^ 75) - 6735;
1708 voice->vc_AudioSource = AudioSource;
1711 // Ring modulation period calculation
1712 if( voice->vc_RingAudioSource )
1714 voice->vc_RingAudioPeriod = voice->vc_RingBasePeriod;
1716 if( !(voice->vc_RingFixedPeriod) )
1718 if( voice->vc_OverrideTranspose != 1000 ) // 1.5
1719 voice->vc_RingAudioPeriod += voice->vc_OverrideTranspose + voice->vc_TrackPeriod - 1;
1720 else
1721 voice->vc_RingAudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
1724 if( voice->vc_RingAudioPeriod > 5*12 )
1725 voice->vc_RingAudioPeriod = 5*12;
1727 if( voice->vc_RingAudioPeriod < 0 )
1728 voice->vc_RingAudioPeriod = 0;
1730 voice->vc_RingAudioPeriod = period_tab[voice->vc_RingAudioPeriod];
1732 if( !(voice->vc_RingFixedPeriod) )
1733 voice->vc_RingAudioPeriod += voice->vc_PeriodSlidePeriod;
1735 voice->vc_RingAudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;
1737 if( voice->vc_RingAudioPeriod > 0x0d60 )
1738 voice->vc_RingAudioPeriod = 0x0d60;
1740 if( voice->vc_RingAudioPeriod < 0x0071 )
1741 voice->vc_RingAudioPeriod = 0x0071;
1744 // Normal period calculation
1745 voice->vc_AudioPeriod = voice->vc_InstrPeriod;
1747 if( !(voice->vc_FixedNote) )
1749 if( voice->vc_OverrideTranspose != 1000 ) // 1.5
1750 voice->vc_AudioPeriod += voice->vc_OverrideTranspose + voice->vc_TrackPeriod - 1;
1751 else
1752 voice->vc_AudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1;
1755 if( voice->vc_AudioPeriod > 5*12 )
1756 voice->vc_AudioPeriod = 5*12;
1758 if( voice->vc_AudioPeriod < 0 )
1759 voice->vc_AudioPeriod = 0;
1761 voice->vc_AudioPeriod = period_tab[voice->vc_AudioPeriod];
1763 if( !(voice->vc_FixedNote) )
1764 voice->vc_AudioPeriod += voice->vc_PeriodSlidePeriod;
1766 voice->vc_AudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod;
1768 if( voice->vc_AudioPeriod > 0x0d60 )
1769 voice->vc_AudioPeriod = 0x0d60;
1771 if( voice->vc_AudioPeriod < 0x0071 )
1772 voice->vc_AudioPeriod = 0x0071;
1774 voice->vc_AudioVolume = (((((((voice->vc_ADSRVolume >> 8) * voice->vc_NoteMaxVolume) >> 6) * voice->vc_PerfSubVolume) >> 6) * voice->vc_TrackMasterVolume) >> 6);
1777 void hvl_set_audio( struct hvl_voice *voice, float64 freqf )
1779 if( voice->vc_TrackOn == 0 )
1781 voice->vc_VoiceVolume = 0;
1782 return;
1785 voice->vc_VoiceVolume = voice->vc_AudioVolume;
1787 if( voice->vc_PlantPeriod )
1789 float64 freq2;
1790 uint32 delta;
1792 voice->vc_PlantPeriod = 0;
1793 voice->vc_VoicePeriod = voice->vc_AudioPeriod;
1795 freq2 = Period2Freq( voice->vc_AudioPeriod );
1796 delta = (uint32)(freq2 / freqf);
1798 if( delta > (0x280<<16) ) delta -= (0x280<<16);
1799 if( delta == 0 ) delta = 1;
1800 voice->vc_Delta = delta;
1803 if( voice->vc_NewWaveform )
1805 int8 *src;
1807 src = voice->vc_AudioSource;
1809 if( voice->vc_Waveform == 4-1 )
1811 memcpy( &voice->vc_VoiceBuffer[0], src, 0x280 );
1812 } else {
1813 uint32 i, WaveLoops;
1815 WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
1817 for( i=0; i<WaveLoops; i++ )
1818 memcpy( &voice->vc_VoiceBuffer[i*4*(1<<voice->vc_WaveLength)], src, 4*(1<<voice->vc_WaveLength) );
1821 voice->vc_VoiceBuffer[0x280] = voice->vc_VoiceBuffer[0];
1822 voice->vc_MixSource = voice->vc_VoiceBuffer;
1825 /* Ring Modulation */
1826 if( voice->vc_RingPlantPeriod )
1828 float64 freq2;
1829 uint32 delta;
1831 voice->vc_RingPlantPeriod = 0;
1832 freq2 = Period2Freq( voice->vc_RingAudioPeriod );
1833 delta = (uint32)(freq2 / freqf);
1835 if( delta > (0x280<<16) ) delta -= (0x280<<16);
1836 if( delta == 0 ) delta = 1;
1837 voice->vc_RingDelta = delta;
1840 if( voice->vc_RingNewWaveform )
1842 int8 *src;
1843 uint32 i, WaveLoops;
1845 src = voice->vc_RingAudioSource;
1847 WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5;
1849 for( i=0; i<WaveLoops; i++ )
1850 memcpy( &voice->vc_RingVoiceBuffer[i*4*(1<<voice->vc_WaveLength)], src, 4*(1<<voice->vc_WaveLength) );
1852 voice->vc_RingVoiceBuffer[0x280] = voice->vc_RingVoiceBuffer[0];
1853 voice->vc_RingMixSource = voice->vc_RingVoiceBuffer;
1857 void hvl_play_irq( struct hvl_tune *ht )
1859 uint32 i;
1861 if( ht->ht_StepWaitFrames <= 0 )
1863 if( ht->ht_GetNewPosition )
1865 int32 nextpos = (ht->ht_PosNr+1==ht->ht_PositionNr)?0:(ht->ht_PosNr+1);
1867 for( i=0; i<ht->ht_Channels; i++ )
1869 ht->ht_Voices[i].vc_Track = ht->ht_Positions[ht->ht_PosNr].pos_Track[i];
1870 ht->ht_Voices[i].vc_Transpose = ht->ht_Positions[ht->ht_PosNr].pos_Transpose[i];
1871 ht->ht_Voices[i].vc_NextTrack = ht->ht_Positions[nextpos].pos_Track[i];
1872 ht->ht_Voices[i].vc_NextTranspose = ht->ht_Positions[nextpos].pos_Transpose[i];
1874 ht->ht_GetNewPosition = 0;
1877 for( i=0; i<ht->ht_Channels; i++ )
1878 hvl_process_step( ht, &ht->ht_Voices[i] );
1880 ht->ht_StepWaitFrames = ht->ht_Tempo;
1883 for( i=0; i<ht->ht_Channels; i++ )
1884 hvl_process_frame( ht, &ht->ht_Voices[i] );
1886 ht->ht_PlayingTime++;
1887 if( ht->ht_Tempo > 0 && --ht->ht_StepWaitFrames <= 0 )
1889 if( !ht->ht_PatternBreak )
1891 ht->ht_NoteNr++;
1892 if( ht->ht_NoteNr >= ht->ht_TrackLength )
1894 ht->ht_PosJump = ht->ht_PosNr+1;
1895 ht->ht_PosJumpNote = 0;
1896 ht->ht_PatternBreak = 1;
1900 if( ht->ht_PatternBreak )
1902 ht->ht_PatternBreak = 0;
1903 ht->ht_PosNr = ht->ht_PosJump;
1904 ht->ht_NoteNr = ht->ht_PosJumpNote;
1905 if( ht->ht_PosNr == ht->ht_PositionNr )
1907 ht->ht_SongEndReached = 1;
1908 ht->ht_PosNr = ht->ht_Restart;
1910 ht->ht_PosJumpNote = 0;
1911 ht->ht_PosJump = 0;
1913 ht->ht_GetNewPosition = 1;
1917 for( i=0; i<ht->ht_Channels; i++ )
1918 hvl_set_audio( &ht->ht_Voices[i], ht->ht_Frequency );
1921 void hvl_mixchunk( struct hvl_tune *ht, uint32 samples, int8 *buf1, int8 *buf2, int32 bufmod )
1923 int8 *src[MAX_CHANNELS];
1924 int8 *rsrc[MAX_CHANNELS];
1925 uint32 delta[MAX_CHANNELS];
1926 uint32 rdelta[MAX_CHANNELS];
1927 int32 vol[MAX_CHANNELS];
1928 uint32 pos[MAX_CHANNELS];
1929 uint32 rpos[MAX_CHANNELS];
1930 uint32 cnt;
1931 int32 panl[MAX_CHANNELS];
1932 int32 panr[MAX_CHANNELS];
1933 // uint32 vu[MAX_CHANNELS];
1934 int32 a=0, b=0, j;
1935 uint32 i, chans, loops;
1937 chans = ht->ht_Channels;
1938 for( i=0; i<chans; i++ )
1940 delta[i] = ht->ht_Voices[i].vc_Delta;
1941 vol[i] = ht->ht_Voices[i].vc_VoiceVolume;
1942 pos[i] = ht->ht_Voices[i].vc_SamplePos;
1943 src[i] = ht->ht_Voices[i].vc_MixSource;
1944 panl[i] = ht->ht_Voices[i].vc_PanMultLeft;
1945 panr[i] = ht->ht_Voices[i].vc_PanMultRight;
1947 /* Ring Modulation */
1948 rdelta[i]= ht->ht_Voices[i].vc_RingDelta;
1949 rpos[i] = ht->ht_Voices[i].vc_RingSamplePos;
1950 rsrc[i] = ht->ht_Voices[i].vc_RingMixSource;
1952 // vu[i] = 0;
1957 loops = samples;
1958 for( i=0; i<chans; i++ )
1960 if( pos[i] >= (0x280 << 16)) pos[i] -= 0x280<<16;
1961 cnt = ((0x280<<16) - pos[i] - 1) / delta[i] + 1;
1962 if( cnt < loops ) loops = cnt;
1964 if( rsrc[i] )
1966 if( rpos[i] >= (0x280<<16)) rpos[i] -= 0x280<<16;
1967 cnt = ((0x280<<16) - rpos[i] - 1) / rdelta[i] + 1;
1968 if( cnt < loops ) loops = cnt;
1973 samples -= loops;
1975 // Inner loop
1978 a=0;
1979 b=0;
1980 for( i=0; i<chans; i++ )
1982 if( rsrc[i] )
1984 /* Ring Modulation */
1985 j = ((src[i][pos[i]>>16]*rsrc[i][rpos[i]>>16])>>7)*vol[i];
1986 rpos[i] += rdelta[i];
1987 } else {
1988 j = src[i][pos[i]>>16]*vol[i];
1991 // if( abs( j ) > vu[i] ) vu[i] = abs( j );
1993 a += (j * panl[i]) >> 7;
1994 b += (j * panr[i]) >> 7;
1995 pos[i] += delta[i];
1998 a = (a*ht->ht_mixgain)>>8;
1999 b = (b*ht->ht_mixgain)>>8;
2001 *(int16 *)buf1 = a;
2002 *(int16 *)buf2 = b;
2004 loops--;
2006 buf1 += bufmod;
2007 buf2 += bufmod;
2008 } while( loops > 0 );
2009 } while( samples > 0 );
2011 for( i=0; i<chans; i++ )
2013 ht->ht_Voices[i].vc_SamplePos = pos[i];
2014 ht->ht_Voices[i].vc_RingSamplePos = rpos[i];
2015 // ht->ht_Voices[i].vc_VUMeter = vu[i];
2019 void hvl_DecodeFrame( struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod )
2021 uint32 samples, loops;
2023 samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
2024 loops = ht->ht_SpeedMultiplier;
2028 hvl_play_irq( ht );
2029 hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
2030 buf1 += samples * 4;
2031 buf2 += samples * 4;
2032 loops--;
2033 } while( loops );
2036 //added for pineapple tracker
2038 void hvl_playNote(struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod, struct hvl_voice *voice) {
2039 uint32 samples, loops;
2041 samples = ht->ht_Frequency/50/ht->ht_SpeedMultiplier;
2042 loops = ht->ht_SpeedMultiplier;
2046 //hvl_play_irq( ht );
2047 //hvl_process_step( ht, &ht->ht_Voices[0] );
2048 int32 Note, Instr, donenotedel;
2049 struct hvl_step *Step;
2051 if( voice->vc_TrackOn == 0 )
2052 return;
2054 voice->vc_VolumeSlideUp = voice->vc_VolumeSlideDown = 0;
2056 Step = &ht->ht_Tracks[ht->ht_Positions[ht->ht_PosNr].pos_Track[voice->vc_VoiceNum]][ht->ht_NoteNr];
2058 Note = htTune->curNote;
2059 Instr = Step->stp_Instrument;
2061 // --------- 1.6: from here --------------
2063 donenotedel = 0;
2065 // Do notedelay here
2066 if( ((Step->stp_FX&0xf)==0xe) && ((Step->stp_FXParam&0xf0)==0xd0) )
2068 if( voice->vc_NoteDelayOn )
2070 voice->vc_NoteDelayOn = 0;
2071 donenotedel = 1;
2072 } else {
2073 if( (Step->stp_FXParam&0x0f) < ht->ht_Tempo )
2075 voice->vc_NoteDelayWait = Step->stp_FXParam & 0x0f;
2076 if( voice->vc_NoteDelayWait )
2078 voice->vc_NoteDelayOn = 1;
2079 return;
2085 if( (donenotedel==0) && ((Step->stp_FXb&0xf)==0xe) && ((Step->stp_FXbParam&0xf0)==0xd0) )
2087 if( voice->vc_NoteDelayOn )
2089 voice->vc_NoteDelayOn = 0;
2090 } else {
2091 if( (Step->stp_FXbParam&0x0f) < ht->ht_Tempo )
2093 voice->vc_NoteDelayWait = Step->stp_FXbParam & 0x0f;
2094 if( voice->vc_NoteDelayWait )
2096 voice->vc_NoteDelayOn = 1;
2097 return;
2103 // --------- 1.6: to here --------------
2105 if( Note ) voice->vc_OverrideTranspose = 1000; // 1.5
2107 //hvl_process_stepfx_1( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
2108 //hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
2110 if( ( Instr ) && ( Instr <= ht->ht_InstrumentNr ) )
2112 struct hvl_instrument *Ins;
2113 int16 SquareLower, SquareUpper, d6, d3, d4;
2115 /* 1.4: Reset panning to last set position */
2116 voice->vc_Pan = voice->vc_SetPan;
2117 voice->vc_PanMultLeft = panning_left[voice->vc_Pan];
2118 voice->vc_PanMultRight = panning_right[voice->vc_Pan];
2120 voice->vc_PeriodSlideSpeed = voice->vc_PeriodSlidePeriod = voice->vc_PeriodSlideLimit = 0;
2122 voice->vc_PerfSubVolume = 0x40;
2123 voice->vc_ADSRVolume = 0;
2124 voice->vc_Instrument = Ins = &ht->ht_Instruments[Instr];
2125 voice->vc_SamplePos = 0;
2127 voice->vc_ADSR.aFrames = Ins->ins_Envelope.aFrames;
2128 voice->vc_ADSR.aVolume = Ins->ins_Envelope.aVolume*256/voice->vc_ADSR.aFrames;
2129 voice->vc_ADSR.dFrames = Ins->ins_Envelope.dFrames;
2130 voice->vc_ADSR.dVolume = (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume)*256/voice->vc_ADSR.dFrames;
2131 voice->vc_ADSR.sFrames = Ins->ins_Envelope.sFrames;
2132 voice->vc_ADSR.rFrames = Ins->ins_Envelope.rFrames;
2133 voice->vc_ADSR.rVolume = (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume)*256/voice->vc_ADSR.rFrames;
2135 voice->vc_WaveLength = Ins->ins_WaveLength;
2136 voice->vc_NoteMaxVolume = Ins->ins_Volume;
2138 voice->vc_VibratoCurrent = 0;
2139 voice->vc_VibratoDelay = Ins->ins_VibratoDelay;
2140 voice->vc_VibratoDepth = Ins->ins_VibratoDepth;
2141 voice->vc_VibratoSpeed = Ins->ins_VibratoSpeed;
2142 voice->vc_VibratoPeriod = 0;
2144 voice->vc_HardCutRelease = Ins->ins_HardCutRelease;
2145 voice->vc_HardCut = Ins->ins_HardCutReleaseFrames;
2147 voice->vc_IgnoreSquare = voice->vc_SquareSlidingIn = 0;
2148 voice->vc_SquareWait = voice->vc_SquareOn = 0;
2150 SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength);
2151 SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength);
2153 if( SquareUpper < SquareLower )
2155 int16 t = SquareUpper;
2156 SquareUpper = SquareLower;
2157 SquareLower = t;
2160 voice->vc_SquareUpperLimit = SquareUpper;
2161 voice->vc_SquareLowerLimit = SquareLower;
2163 voice->vc_IgnoreFilter = voice->vc_FilterWait = voice->vc_FilterOn = 0;
2164 voice->vc_FilterSlidingIn = 0;
2166 d6 = Ins->ins_FilterSpeed;
2167 d3 = Ins->ins_FilterLowerLimit;
2168 d4 = Ins->ins_FilterUpperLimit;
2170 if( d3 & 0x80 ) d6 |= 0x20;
2171 if( d4 & 0x80 ) d6 |= 0x40;
2173 voice->vc_FilterSpeed = d6;
2174 d3 &= ~0x80;
2175 d4 &= ~0x80;
2177 if( d3 > d4 )
2179 int16 t = d3;
2180 d3 = d4;
2181 d4 = t;
2184 voice->vc_FilterUpperLimit = d4;
2185 voice->vc_FilterLowerLimit = d3;
2186 voice->vc_FilterPos = 32;
2188 voice->vc_PerfWait = voice->vc_PerfCurrent = 0;
2189 voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed;
2190 voice->vc_PerfList = &voice->vc_Instrument->ins_PList;
2192 voice->vc_RingMixSource = NULL; // No ring modulation
2193 voice->vc_RingSamplePos = 0;
2194 voice->vc_RingPlantPeriod = 0;
2195 voice->vc_RingNewWaveform = 0;
2198 voice->vc_PeriodSlideOn = 0;
2200 //hvl_process_stepfx_2( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam, &Note );
2201 //hvl_process_stepfx_2( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note );
2203 if( Note )
2205 voice->vc_TrackPeriod = Note;
2206 voice->vc_PlantPeriod = 1;
2209 //hvl_process_stepfx_3( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam );
2210 //hvl_process_stepfx_3( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam );
2212 hvl_process_frame( ht, &ht->ht_Voices[0] );
2213 ht->ht_NoteNr = -1;
2214 hvl_set_audio( &ht->ht_Voices[0], ht->ht_Frequency );
2215 //hvl_mixchunk( ht, samples, buf1, buf2, bufmod );
2216 int8 *src[MAX_CHANNELS];
2217 int8 *rsrc[MAX_CHANNELS];
2218 uint32 delta[MAX_CHANNELS];
2219 uint32 rdelta[MAX_CHANNELS];
2220 int32 vol[MAX_CHANNELS];
2221 uint32 pos[MAX_CHANNELS];
2222 uint32 rpos[MAX_CHANNELS];
2223 uint32 cnt;
2224 int32 panl[MAX_CHANNELS];
2225 int32 panr[MAX_CHANNELS];
2226 // uint32 vu[MAX_CHANNELS];
2227 int32 a=0, b=0, j;
2228 //uint32 i, chans, loops;
2229 uint32 loops2;
2231 //chans = ht->ht_Channels;
2232 //for( i=0; i<0; i++ )
2234 delta[0] = ht->ht_Voices[0].vc_Delta;
2235 vol[0] = ht->ht_Voices[0].vc_VoiceVolume;
2236 pos[0] = ht->ht_Voices[0].vc_SamplePos;
2237 src[0] = ht->ht_Voices[0].vc_MixSource;
2238 panl[0] = ht->ht_Voices[0].vc_PanMultLeft;
2239 panr[0] = ht->ht_Voices[0].vc_PanMultRight;
2241 /* Ring Modulation */
2242 rdelta[0]= ht->ht_Voices[0].vc_RingDelta;
2243 rpos[0] = ht->ht_Voices[0].vc_RingSamplePos;
2244 rsrc[0] = ht->ht_Voices[0].vc_RingMixSource;
2246 // vu[i] = 0;
2251 loops2 = samples;
2252 //for( i=0; i<chans; i++ )
2254 if( pos[0] >= (0x280 << 16)) pos[0] -= 0x280<<16;
2255 cnt = ((0x280<<16) - pos[0] - 1) / delta[0] + 1;
2256 if( cnt < loops2 ) loops2 = cnt;
2258 if( rsrc[0] )
2260 if( rpos[0] >= (0x280<<16)) rpos[0] -= 0x280<<16;
2261 cnt = ((0x280<<16) - rpos[0] - 1) / rdelta[0] + 1;
2262 if( cnt < loops2 ) loops2 = cnt;
2267 samples -= loops2;
2269 // Inner loop
2272 a=0;
2273 b=0;
2274 //for( i=0; i<chans; i++ )
2276 if( rsrc[0] )
2278 /* Ring Modulation */
2279 j = ((src[0][pos[0]>>16]*rsrc[0][rpos[0]>>16])>>7)*vol[0];
2280 rpos[0] += rdelta[0];
2281 } else {
2282 j = src[0][pos[0]>>16]*vol[0];
2285 // if( abs( j ) > vu[i] ) vu[i] = abs( j );
2287 a += (j * panl[0]) >> 7;
2288 b += (j * panr[0]) >> 7;
2289 pos[0] += delta[0];
2292 a = (a*ht->ht_mixgain)>>8;
2293 b = (b*ht->ht_mixgain)>>8;
2295 *(int16 *)buf1 = a;
2296 *(int16 *)buf2 = b;
2298 loops2--;
2300 buf1 += bufmod;
2301 buf2 += bufmod;
2302 } while( loops2 > 0 );
2303 } while( samples > 0 );
2305 //for( i=0; i<chans; i++ )
2307 ht->ht_Voices[0].vc_SamplePos = pos[0];
2308 ht->ht_Voices[0].vc_RingSamplePos = rpos[0];
2309 // ht->ht_Voices[i].vc_VUMeter = vu[i];
2312 buf1 += samples * 4;
2313 buf2 += samples * 4;
2314 loops--;
2315 } while( loops );
2318 /*int hvl_save_ahx(struct hvl_tune *ht, sturct pineapple_tune *pt){
2321 int hvl_save_hvl(struct hvl_tune *ht, sturct pineapple_tune *pt){