1 /* AHX originally by Pink/Abyss and bigup Xeron for Hivelytracker! */
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
8 ** Changes for 1.5 are marked also.
10 ** ... as are those for 1.6
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 };
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
];
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){
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;
90 void hvl_GenSawtooth(int8
*buf
, uint32 len
){
97 for( i
=0; i
<len
; i
++, val
+= add
)
101 void hvl_GenTriangle( int8
*buf
, uint32 len
)
104 int32 d2
, d5
, d1
, d4
;
114 for( i
=0; i
<d5
; i
++ )
124 for( i
=0; i
<d5
-1; i
++ )
132 for( i
=0; i
<d5
*2; i
++ )
146 void hvl_GenSquare( int8
*buf
)
150 for( i
=1; i
<=0x20; i
++ )
152 for( j
=0; j
<(0x40-i
)*2; j
++ )
154 for( j
=0; j
<i
*2; j
++ )
159 static inline float64
clip( float64 x
)
163 else if( x
< -128.f
)
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,
178 for( temp
=0, freq
=8.f
; temp
<31; temp
++, freq
+=3.f
)
183 for( wv
=0; wv
<6+6+0x20+1; wv
++ )
185 float64 fre
, high
, mid
, low
;
190 fre
= freq
* 1.25f
/ 100.0f
;
192 for( i
=0; i
<=lentab
[wv
]; i
++ )
194 high
= a0
[i
] - mid
- low
;
202 for( i
=0; i
<=lentab
[wv
]; i
++ )
204 high
= a0
[i
] - mid
- low
;
210 *lowbuf
++ = (int8
)low
;
211 *highbuf
++ = (int8
)high
;
219 void hvl_GenWhiteNoise( int8
*buf
, uint32 len
)
235 if( (int32
)(ays
& 0xffff) >= 0 )
242 ays
= (ays
>> 5) | (ays
<< 27);
243 ays
= (ays
& 0xffffff00) | ((ays
& 0xff) ^ 0x9a);
245 ays
= (ays
<< 2) | (ays
>> 30);
249 ays
= (ays
& 0xffff0000) | ax
;
250 ays
= (ays
>> 3) | (ays
<< 29);
254 void hvl_reset_some_stuff( struct hvl_tune
*ht
)
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
)
299 if( nr
> ht
->ht_SubsongNr
)
305 if( nr
) PosNr
= ht
->ht_Subsongs
[nr
-1];
307 tune
->songpos
= PosNr
;
309 ht
->ht_PatternBreak
= 0;
311 ht
->ht_PosJumpNote
= 0;
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
);
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
)
367 uint32 i
, j
, k
, l
, posn
, insn
, ssn
, hs
, trkn
, trkl
;
369 struct hvl_plsentry
*ple
;
370 int32 defgain
[] = { 71, 72, 76, 85, 100 };
372 posn
= ((buf
[6]&0x0f)<<8)|buf
[7];
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
385 bptr
+= ssn
*2; // Skip past the subsong list
386 bptr
+= posn
*4*2; // Skip past the positions
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;
401 printf( "Out of memory!\n" );
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
];
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
,
440 ht
->ht_InstrumentNr
);
443 printf( "Invalid file.\n" );
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];
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;
462 for( i
=0; i
<ht
->ht_PositionNr
; i
++ )
466 ht
->ht_Positions
[i
].pos_Track
[j
] = *bptr
++;
467 ht
->ht_Positions
[i
].pos_Transpose
[j
] = *(int8
*)bptr
++;
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;
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;
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;
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
;
540 for( j
=0; j
<ht
->ht_Instruments
[i
].ins_PList
.pls_Length
; j
++ )
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;
567 //hvl_InitSubsong( ht, 0 );
572 struct hvl_tune
*hvl_LoadTune( TEXT
*name
, uint32 freq
, uint32 defstereo
)
577 uint32 buflen
, i
, j
, posn
, insn
, ssn
, chnn
, hs
, trkl
, trkn
;
579 struct hvl_plsentry
*ple
;
581 fh
= fopen( name
, "rb" );
584 printf( "Can't open file\n" );
588 fseek( fh
, 0, SEEK_END
);
589 buflen
= ftell( fh
);
590 fseek( fh
, 0, SEEK_SET
);
592 buf
= malloc( buflen
);
596 printf( "Out of memory!\n" );
600 if( fread( buf
, 1, buflen
, fh
) != buflen
)
604 printf( "Unable to read from file!\n" );
609 if( ( buf
[0] == 'T' ) &&
613 return hvl_load_ahx( buf
, buflen
, defstereo
, freq
);
615 if( ( buf
[0] != 'H' ) ||
621 printf( "Invalid file.\n" );
625 posn
= ((buf
[6]&0x0f)<<8)|buf
[7];
628 chnn
= (buf
[8]>>2)+4;
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
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 )
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;
668 printf( "Out of memory!\n" );
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
,
708 ht
->ht_InstrumentNr
);
711 printf( "Invalid file.\n" );
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];
721 for( i
=0; i
<ht
->ht_SubsongNr
; i
++ )
723 ht
->ht_Subsongs
[i
] = (bptr
[0]<<8)|bptr
[1];
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
++;
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;
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;
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];
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;
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
;
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];
832 //hvl_InitSubsong( ht, 0 );
837 void hvl_FreeTune( struct hvl_tune
*ht
)
843 void hvl_process_stepfx_1( struct hvl_tune
*ht
, struct hvl_voice
*voice
, int32 FX
, int32 FXParam
)
847 case 0x0: // Position Jump HI
848 if( ((FXParam
&0x0f) > 0) && ((FXParam
&0x0f) <= 9) )
849 ht
->ht_PosJump
= FXParam
& 0xf;
852 case 0x5: // Volume Slide + Tone Portamento
853 case 0xa: // Volume Slide
854 voice
->vc_VolumeSlideDown
= FXParam
& 0x0f;
855 voice
->vc_VolumeSlideUp
= FXParam
>> 4;
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
];
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;
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;
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;
897 // 1.6: 0xd case removed
902 ht
->ht_Tempo
= FXParam
;
904 ht
->ht_SongEndReached
= 1;
909 void hvl_process_stepfx_2( struct hvl_tune
*ht
, struct hvl_voice
*voice
, int32 FX
, int32 FXParam
, int32
*Note
)
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;
919 case 0x5: // Tone portamento + volume slide
920 case 0x3: // Tone portamento
921 if( FXParam
!= 0 ) voice
->vc_PeriodSlideSpeed
= FXParam
;
927 new = period_tab
[*Note
];
928 diff
= period_tab
[voice
->vc_TrackPeriod
];
930 new = diff
+ voice
->vc_PeriodSlidePeriod
;
933 voice
->vc_PeriodSlideLimit
= -diff
;
935 voice
->vc_PeriodSlideOn
= 1;
936 voice
->vc_PeriodSlideWithLimit
= 1;
942 void hvl_process_stepfx_3( struct hvl_tune
*ht
, struct hvl_voice
*voice
, int32 FX
, int32 FXParam
)
948 case 0x01: // Portamento up (period slide down)
949 voice
->vc_PeriodSlideSpeed
= -FXParam
;
950 voice
->vc_PeriodSlideOn
= 1;
951 voice
->vc_PeriodSlideWithLimit
= 0;
953 case 0x02: // Portamento down
954 voice
->vc_PeriodSlideSpeed
= FXParam
;
955 voice
->vc_PeriodSlideOn
= 1;
956 voice
->vc_PeriodSlideWithLimit
= 0;
958 case 0x04: // Filter override
959 if( ( FXParam
== 0 ) || ( FXParam
== 0x40 ) ) break;
962 voice
->vc_IgnoreFilter
= FXParam
;
965 if( FXParam
> 0x7f ) break;
966 voice
->vc_FilterPos
= FXParam
- 0x40;
970 if( FXParam
<= 0x40 )
972 voice
->vc_NoteMaxVolume
= FXParam
;
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
;
985 if( (FXParam
-= 0xa0-0x50) < 0 ) break; // 1.6
987 if( FXParam
<= 0x40 )
988 voice
->vc_TrackMasterVolume
= FXParam
;
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;
999 case 0x2: // Fineslide down
1000 voice
->vc_PeriodSlidePeriod
= (FXParam
& 0x0f);
1001 voice
->vc_PlantPeriod
= 1;
1004 case 0x4: // Vibrato control
1005 voice
->vc_VibratoDepth
= FXParam
& 0x0f;
1008 case 0x0a: // Fine volume up
1009 voice
->vc_NoteMaxVolume
+= FXParam
& 0x0f;
1011 if( voice
->vc_NoteMaxVolume
> 0x40 )
1012 voice
->vc_NoteMaxVolume
= 0x40;
1015 case 0x0b: // Fine volume down
1016 voice
->vc_NoteMaxVolume
-= FXParam
& 0x0f;
1018 if( voice
->vc_NoteMaxVolume
< 0 )
1019 voice
->vc_NoteMaxVolume
= 0;
1022 case 0x0f: // Misc flags (1.5)
1023 if( ht
->ht_Version
< 1 ) break;
1024 switch( FXParam
& 0xf )
1027 voice
->vc_OverrideTranspose
= voice
->vc_Transpose
;
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 )
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 --------------
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;
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;
1075 if( (donenotedel
==0) && ((Step
->stp_FXb
&0xf)==0xe) && ((Step
->stp_FXbParam
&0xf0)==0xd0) )
1077 if( voice
->vc_NoteDelayOn
)
1079 voice
->vc_NoteDelayOn
= 0;
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;
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
;
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
;
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
);
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
)
1208 if( ( FXParam
> 0 ) && ( FXParam
< 0x40 ) )
1210 if( voice
->vc_IgnoreFilter
)
1212 voice
->vc_FilterPos
= voice
->vc_IgnoreFilter
;
1213 voice
->vc_IgnoreFilter
= 0;
1215 voice
->vc_FilterPos
= FXParam
;
1217 voice
->vc_NewWaveform
= 1;
1222 voice
->vc_PeriodPerfSlideSpeed
= FXParam
;
1223 voice
->vc_PeriodPerfSlideOn
= 1;
1227 voice
->vc_PeriodPerfSlideSpeed
= -FXParam
;
1228 voice
->vc_PeriodPerfSlideOn
= 1;
1232 if( voice
->vc_IgnoreSquare
== 0 )
1233 voice
->vc_SquarePos
= FXParam
>> (5-voice
->vc_WaveLength
);
1235 voice
->vc_IgnoreSquare
= 0;
1241 voice
->vc_SquareInit
= (voice
->vc_SquareOn
^= 1);
1242 voice
->vc_SquareSign
= 1;
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;
1264 voice
->vc_PerfCurrent
= FXParam
;
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;
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
;
1284 voice
->vc_RingWaveform
= 0;
1285 voice
->vc_RingNewWaveform
= 1;
1286 voice
->vc_RingPlantPeriod
= 1;
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;
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
;
1306 voice
->vc_RingWaveform
= 1;
1307 voice
->vc_RingNewWaveform
= 1;
1308 voice
->vc_RingPlantPeriod
= 1;
1311 /* New in HivelyTracker 1.4 */
1315 voice
->vc_Pan
= (FXParam
+128);
1316 voice
->vc_PanMultLeft
= panning_left
[voice
->vc_Pan
];
1317 voice
->vc_PanMultRight
= panning_right
[voice
->vc_Pan
];
1321 if( FXParam
<= 0x40 )
1323 voice
->vc_NoteMaxVolume
= FXParam
;
1327 if( (FXParam
-= 0x50) < 0 ) break;
1329 if( FXParam
<= 0x40 )
1331 voice
->vc_PerfSubVolume
= FXParam
;
1335 if( (FXParam
-= 0xa0-0x50) < 0 ) break;
1337 if( FXParam
<= 0x40 )
1338 voice
->vc_TrackMasterVolume
= FXParam
;
1342 voice
->vc_PerfSpeed
= voice
->vc_PerfWait
= FXParam
;
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 )
1354 if( voice
->vc_NoteDelayOn
)
1356 if( voice
->vc_NoteDelayWait
<= 0 )
1357 hvl_process_step( ht
, voice
);
1359 voice
->vc_NoteDelayWait
--;
1362 if( voice
->vc_HardCut
)
1366 if( ht
->ht_NoteNr
+1 < ht
->ht_TrackLength
)
1367 nextinst
= ht
->ht_Tracks
[voice
->vc_Track
][ht
->ht_NoteNr
+1].stp_Instrument
;
1369 nextinst
= ht
->ht_Tracks
[voice
->vc_NextTrack
][0].stp_Instrument
;
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
);
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;
1402 voice
->vc_NoteMaxVolume
= 0;
1405 voice
->vc_NoteCutWait
--;
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;
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;
1445 if( voice
->vc_PeriodSlideOn
)
1447 if( voice
->vc_PeriodSlideWithLimit
)
1451 d0
= voice
->vc_PeriodSlidePeriod
- voice
->vc_PeriodSlideLimit
;
1452 d2
= voice
->vc_PeriodSlideSpeed
;
1461 d3
= (d0
+ d2
) ^ d0
;
1464 d0
= voice
->vc_PeriodSlidePeriod
+ d2
;
1466 d0
= voice
->vc_PeriodSlideLimit
;
1468 voice
->vc_PeriodSlidePeriod
= d0
;
1469 voice
->vc_PlantPeriod
= 1;
1472 voice
->vc_PeriodSlidePeriod
+= voice
->vc_PeriodSlideSpeed
;
1473 voice
->vc_PlantPeriod
= 1;
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;
1486 voice
->vc_VibratoDelay
--;
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 )
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;
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 );
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
;
1525 if( voice
->vc_PerfWait
)
1526 voice
->vc_PerfWait
--;
1528 voice
->vc_PeriodPerfSlideSpeed
= 0;
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 )
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;
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;
1566 if( d1
== d3
|| d2
== d3
)
1568 if( voice
->vc_SquareSlidingIn
)
1569 voice
->vc_SquareSlidingIn
= 0;
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 )
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;
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;
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;
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
)
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
);
1642 voice
->vc_SquareReverse
= 1;
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
;
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
)
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
)
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 )
1697 AudioSource
+= ( voice
->vc_WNRandom
& (2*0x280-1) ) & ~1;
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;
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;
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;
1780 voice
->vc_VoiceVolume
= voice
->vc_AudioVolume
;
1782 if( voice
->vc_PlantPeriod
)
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
)
1802 src
= voice
->vc_AudioSource
;
1804 if( voice
->vc_Waveform
== 4-1 )
1806 memcpy( &voice
->vc_VoiceBuffer
[0], src
, 0x280 );
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
)
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
)
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
)
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
)
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;
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
];
1926 int32 panl
[MAX_CHANNELS
];
1927 int32 panr
[MAX_CHANNELS
];
1928 // uint32 vu[MAX_CHANNELS];
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
;
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
;
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
;
1975 for( i
=0; i
<chans
; i
++ )
1979 /* Ring Modulation */
1980 j
= ((src
[i
][pos
[i
]>>16]*rsrc
[i
][rpos
[i
]>>16])>>7)*vol
[i
];
1981 rpos
[i
] += rdelta
[i
];
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;
1993 a
= (a
*ht
->ht_mixgain
)>>8;
1994 b
= (b
*ht
->ht_mixgain
)>>8;
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
){
2023 hvl_mixchunk( ht
, samples
, buf1
, buf2
, bufmod
);
2024 buf1
+= samples
* bufmod
;
2025 buf2
+= samples
* bufmod
;
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
;
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 )
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;
2064 // --------- 1.6: from here --------------
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;
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;
2088 if( (donenotedel
==0) && ((Step
->stp_FXb
&0xf)==0xe) && ((Step
->stp_FXbParam
&0xf0)==0xd0) )
2090 if( voice
->vc_NoteDelayOn
)
2092 voice
->vc_NoteDelayOn
= 0;
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;
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
;
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
;
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 );
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] );
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
];
2227 int32 panl
[MAX_CHANNELS
];
2228 int32 panr
[MAX_CHANNELS
];
2229 // uint32 vu[MAX_CHANNELS];
2231 //uint32 i, chans, loops;
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
;
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
;
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
;
2277 //for( i=0; i<chans; i++ )
2281 /* Ring Modulation */
2282 j
= ((src
[0][pos
[0]>>16]*rsrc
[0][rpos
[0]>>16])>>7)*vol
[0];
2283 rpos
[0] += rdelta
[0];
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;
2295 a
= (a
*ht
->ht_mixgain
)>>8;
2296 b
= (b
*ht
->ht_mixgain
)>>8;
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
;
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){