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
];
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
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 )
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;
94 void hvl_GenSawtooth( int8
*buf
, uint32 len
)
102 for( i
=0; i
<len
; i
++, val
+= add
)
106 void hvl_GenTriangle( int8
*buf
, uint32 len
)
109 int32 d2
, d5
, d1
, d4
;
119 for( i
=0; i
<d5
; i
++ )
129 for( i
=0; i
<d5
-1; i
++ )
137 for( i
=0; i
<d5
*2; i
++ )
151 void hvl_GenSquare( int8
*buf
)
155 for( i
=1; i
<=0x20; i
++ )
157 for( j
=0; j
<(0x40-i
)*2; j
++ )
159 for( j
=0; j
<i
*2; j
++ )
164 static inline float64
clip( float64 x
)
168 else if( x
< -128.f
)
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,
183 for( temp
=0, freq
=8.f
; temp
<31; temp
++, freq
+=3.f
)
188 for( wv
=0; wv
<6+6+0x20+1; wv
++ )
190 float64 fre
, high
, mid
, low
;
195 fre
= freq
* 1.25f
/ 100.0f
;
197 for( i
=0; i
<=lentab
[wv
]; i
++ )
199 high
= a0
[i
] - mid
- low
;
207 for( i
=0; i
<=lentab
[wv
]; i
++ )
209 high
= a0
[i
] - mid
- low
;
215 *lowbuf
++ = (int8
)low
;
216 *highbuf
++ = (int8
)high
;
224 void hvl_GenWhiteNoise( int8
*buf
, uint32 len
)
240 if( (int32
)(ays
& 0xffff) >= 0 )
247 ays
= (ays
>> 5) | (ays
<< 27);
248 ays
= (ays
& 0xffffff00) | ((ays
& 0xff) ^ 0x9a);
250 ays
= (ays
<< 2) | (ays
>> 30);
254 ays
= (ays
& 0xffff0000) | ax
;
255 ays
= (ays
>> 3) | (ays
<< 29);
259 void hvl_reset_some_stuff( struct hvl_tune
*ht
)
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
)
304 if( nr
> ht
->ht_SubsongNr
)
310 if( nr
) PosNr
= ht
->ht_Subsongs
[nr
-1];
312 ht
->ht_PosNr
= PosNr
;
314 ht
->ht_PatternBreak
= 0;
316 ht
->ht_PosJumpNote
= 0;
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
);
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
)
372 uint32 i
, j
, k
, l
, posn
, insn
, ssn
, hs
, trkn
, trkl
;
374 struct hvl_plsentry
*ple
;
375 int32 defgain
[] = { 71, 72, 76, 85, 100 };
377 posn
= ((buf
[6]&0x0f)<<8)|buf
[7];
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
390 bptr
+= ssn
*2; // Skip past the subsong list
391 bptr
+= posn
*4*2; // Skip past the positions
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;
406 printf( "Out of memory!\n" );
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
];
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
,
445 ht
->ht_InstrumentNr
);
448 printf( "Invalid file.\n" );
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];
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;
467 for( i
=0; i
<ht
->ht_PositionNr
; i
++ )
471 ht
->ht_Positions
[i
].pos_Track
[j
] = *bptr
++;
472 ht
->ht_Positions
[i
].pos_Transpose
[j
] = *(int8
*)bptr
++;
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;
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;
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;
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
;
545 for( j
=0; j
<ht
->ht_Instruments
[i
].ins_PList
.pls_Length
; j
++ )
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;
572 hvl_InitSubsong( ht
, 0 );
577 struct hvl_tune
*hvl_LoadTune( TEXT
*name
, uint32 freq
, uint32 defstereo
)
582 uint32 buflen
, i
, j
, posn
, insn
, ssn
, chnn
, hs
, trkl
, trkn
;
584 struct hvl_plsentry
*ple
;
586 fh
= fopen( name
, "rb" );
589 printf( "Can't open file\n" );
593 fseek( fh
, 0, SEEK_END
);
594 buflen
= ftell( fh
);
595 fseek( fh
, 0, SEEK_SET
);
597 buf
= malloc( buflen
);
601 printf( "Out of memory!\n" );
605 if( fread( buf
, 1, buflen
, fh
) != buflen
)
609 printf( "Unable to read from file!\n" );
614 if( ( buf
[0] == 'T' ) &&
618 return hvl_load_ahx( buf
, buflen
, defstereo
, freq
);
620 if( ( buf
[0] != 'H' ) ||
626 printf( "Invalid file.\n" );
630 posn
= ((buf
[6]&0x0f)<<8)|buf
[7];
633 chnn
= (buf
[8]>>2)+4;
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
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 )
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;
673 printf( "Out of memory!\n" );
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
,
713 ht
->ht_InstrumentNr
);
716 printf( "Invalid file.\n" );
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];
726 for( i
=0; i
<ht
->ht_SubsongNr
; i
++ )
728 ht
->ht_Subsongs
[i
] = (bptr
[0]<<8)|bptr
[1];
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
++;
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;
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;
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];
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;
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
;
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];
837 hvl_InitSubsong( ht
, 0 );
842 void hvl_FreeTune( struct hvl_tune
*ht
)
848 void hvl_process_stepfx_1( struct hvl_tune
*ht
, struct hvl_voice
*voice
, int32 FX
, int32 FXParam
)
852 case 0x0: // Position Jump HI
853 if( ((FXParam
&0x0f) > 0) && ((FXParam
&0x0f) <= 9) )
854 ht
->ht_PosJump
= FXParam
& 0xf;
857 case 0x5: // Volume Slide + Tone Portamento
858 case 0xa: // Volume Slide
859 voice
->vc_VolumeSlideDown
= FXParam
& 0x0f;
860 voice
->vc_VolumeSlideUp
= FXParam
>> 4;
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
];
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;
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;
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;
902 // 1.6: 0xd case removed
907 ht
->ht_Tempo
= FXParam
;
909 ht
->ht_SongEndReached
= 1;
914 void hvl_process_stepfx_2( struct hvl_tune
*ht
, struct hvl_voice
*voice
, int32 FX
, int32 FXParam
, int32
*Note
)
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;
924 case 0x5: // Tone portamento + volume slide
925 case 0x3: // Tone portamento
926 if( FXParam
!= 0 ) voice
->vc_PeriodSlideSpeed
= FXParam
;
932 new = period_tab
[*Note
];
933 diff
= period_tab
[voice
->vc_TrackPeriod
];
935 new = diff
+ voice
->vc_PeriodSlidePeriod
;
938 voice
->vc_PeriodSlideLimit
= -diff
;
940 voice
->vc_PeriodSlideOn
= 1;
941 voice
->vc_PeriodSlideWithLimit
= 1;
947 void hvl_process_stepfx_3( struct hvl_tune
*ht
, struct hvl_voice
*voice
, int32 FX
, int32 FXParam
)
953 case 0x01: // Portamento up (period slide down)
954 voice
->vc_PeriodSlideSpeed
= -FXParam
;
955 voice
->vc_PeriodSlideOn
= 1;
956 voice
->vc_PeriodSlideWithLimit
= 0;
958 case 0x02: // Portamento down
959 voice
->vc_PeriodSlideSpeed
= FXParam
;
960 voice
->vc_PeriodSlideOn
= 1;
961 voice
->vc_PeriodSlideWithLimit
= 0;
963 case 0x04: // Filter override
964 if( ( FXParam
== 0 ) || ( FXParam
== 0x40 ) ) break;
967 voice
->vc_IgnoreFilter
= FXParam
;
970 if( FXParam
> 0x7f ) break;
971 voice
->vc_FilterPos
= FXParam
- 0x40;
975 if( FXParam
<= 0x40 )
977 voice
->vc_NoteMaxVolume
= FXParam
;
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
;
990 if( (FXParam
-= 0xa0-0x50) < 0 ) break; // 1.6
992 if( FXParam
<= 0x40 )
993 voice
->vc_TrackMasterVolume
= FXParam
;
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;
1004 case 0x2: // Fineslide down
1005 voice
->vc_PeriodSlidePeriod
= (FXParam
& 0x0f);
1006 voice
->vc_PlantPeriod
= 1;
1009 case 0x4: // Vibrato control
1010 voice
->vc_VibratoDepth
= FXParam
& 0x0f;
1013 case 0x0a: // Fine volume up
1014 voice
->vc_NoteMaxVolume
+= FXParam
& 0x0f;
1016 if( voice
->vc_NoteMaxVolume
> 0x40 )
1017 voice
->vc_NoteMaxVolume
= 0x40;
1020 case 0x0b: // Fine volume down
1021 voice
->vc_NoteMaxVolume
-= FXParam
& 0x0f;
1023 if( voice
->vc_NoteMaxVolume
< 0 )
1024 voice
->vc_NoteMaxVolume
= 0;
1027 case 0x0f: // Misc flags (1.5)
1028 if( ht
->ht_Version
< 1 ) break;
1029 switch( FXParam
& 0xf )
1032 voice
->vc_OverrideTranspose
= voice
->vc_Transpose
;
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 )
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 --------------
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;
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;
1080 if( (donenotedel
==0) && ((Step
->stp_FXb
&0xf)==0xe) && ((Step
->stp_FXbParam
&0xf0)==0xd0) )
1082 if( voice
->vc_NoteDelayOn
)
1084 voice
->vc_NoteDelayOn
= 0;
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;
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
;
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
;
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
);
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
)
1213 if( ( FXParam
> 0 ) && ( FXParam
< 0x40 ) )
1215 if( voice
->vc_IgnoreFilter
)
1217 voice
->vc_FilterPos
= voice
->vc_IgnoreFilter
;
1218 voice
->vc_IgnoreFilter
= 0;
1220 voice
->vc_FilterPos
= FXParam
;
1222 voice
->vc_NewWaveform
= 1;
1227 voice
->vc_PeriodPerfSlideSpeed
= FXParam
;
1228 voice
->vc_PeriodPerfSlideOn
= 1;
1232 voice
->vc_PeriodPerfSlideSpeed
= -FXParam
;
1233 voice
->vc_PeriodPerfSlideOn
= 1;
1237 if( voice
->vc_IgnoreSquare
== 0 )
1238 voice
->vc_SquarePos
= FXParam
>> (5-voice
->vc_WaveLength
);
1240 voice
->vc_IgnoreSquare
= 0;
1246 voice
->vc_SquareInit
= (voice
->vc_SquareOn
^= 1);
1247 voice
->vc_SquareSign
= 1;
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;
1269 voice
->vc_PerfCurrent
= FXParam
;
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;
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
;
1289 voice
->vc_RingWaveform
= 0;
1290 voice
->vc_RingNewWaveform
= 1;
1291 voice
->vc_RingPlantPeriod
= 1;
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;
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
;
1311 voice
->vc_RingWaveform
= 1;
1312 voice
->vc_RingNewWaveform
= 1;
1313 voice
->vc_RingPlantPeriod
= 1;
1316 /* New in HivelyTracker 1.4 */
1320 voice
->vc_Pan
= (FXParam
+128);
1321 voice
->vc_PanMultLeft
= panning_left
[voice
->vc_Pan
];
1322 voice
->vc_PanMultRight
= panning_right
[voice
->vc_Pan
];
1326 if( FXParam
<= 0x40 )
1328 voice
->vc_NoteMaxVolume
= FXParam
;
1332 if( (FXParam
-= 0x50) < 0 ) break;
1334 if( FXParam
<= 0x40 )
1336 voice
->vc_PerfSubVolume
= FXParam
;
1340 if( (FXParam
-= 0xa0-0x50) < 0 ) break;
1342 if( FXParam
<= 0x40 )
1343 voice
->vc_TrackMasterVolume
= FXParam
;
1347 voice
->vc_PerfSpeed
= voice
->vc_PerfWait
= FXParam
;
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 )
1359 if( voice
->vc_NoteDelayOn
)
1361 if( voice
->vc_NoteDelayWait
<= 0 )
1362 hvl_process_step( ht
, voice
);
1364 voice
->vc_NoteDelayWait
--;
1367 if( voice
->vc_HardCut
)
1371 if( ht
->ht_NoteNr
+1 < ht
->ht_TrackLength
)
1372 nextinst
= ht
->ht_Tracks
[voice
->vc_Track
][ht
->ht_NoteNr
+1].stp_Instrument
;
1374 nextinst
= ht
->ht_Tracks
[voice
->vc_NextTrack
][0].stp_Instrument
;
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
);
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;
1407 voice
->vc_NoteMaxVolume
= 0;
1410 voice
->vc_NoteCutWait
--;
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;
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;
1450 if( voice
->vc_PeriodSlideOn
)
1452 if( voice
->vc_PeriodSlideWithLimit
)
1456 d0
= voice
->vc_PeriodSlidePeriod
- voice
->vc_PeriodSlideLimit
;
1457 d2
= voice
->vc_PeriodSlideSpeed
;
1466 d3
= (d0
+ d2
) ^ d0
;
1469 d0
= voice
->vc_PeriodSlidePeriod
+ d2
;
1471 d0
= voice
->vc_PeriodSlideLimit
;
1473 voice
->vc_PeriodSlidePeriod
= d0
;
1474 voice
->vc_PlantPeriod
= 1;
1477 voice
->vc_PeriodSlidePeriod
+= voice
->vc_PeriodSlideSpeed
;
1478 voice
->vc_PlantPeriod
= 1;
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;
1491 voice
->vc_VibratoDelay
--;
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 )
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;
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 );
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
;
1530 if( voice
->vc_PerfWait
)
1531 voice
->vc_PerfWait
--;
1533 voice
->vc_PeriodPerfSlideSpeed
= 0;
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 )
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;
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;
1571 if( d1
== d3
|| d2
== d3
)
1573 if( voice
->vc_SquareSlidingIn
)
1574 voice
->vc_SquareSlidingIn
= 0;
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 )
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;
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;
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;
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
)
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
);
1647 voice
->vc_SquareReverse
= 1;
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
;
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
)
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
)
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 )
1702 AudioSource
+= ( voice
->vc_WNRandom
& (2*0x280-1) ) & ~1;
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;
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;
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;
1785 voice
->vc_VoiceVolume
= voice
->vc_AudioVolume
;
1787 if( voice
->vc_PlantPeriod
)
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
)
1807 src
= voice
->vc_AudioSource
;
1809 if( voice
->vc_Waveform
== 4-1 )
1811 memcpy( &voice
->vc_VoiceBuffer
[0], src
, 0x280 );
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
)
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
)
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
)
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
)
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;
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
];
1931 int32 panl
[MAX_CHANNELS
];
1932 int32 panr
[MAX_CHANNELS
];
1933 // uint32 vu[MAX_CHANNELS];
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
;
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
;
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
;
1980 for( i
=0; i
<chans
; i
++ )
1984 /* Ring Modulation */
1985 j
= ((src
[i
][pos
[i
]>>16]*rsrc
[i
][rpos
[i
]>>16])>>7)*vol
[i
];
1986 rpos
[i
] += rdelta
[i
];
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;
1998 a
= (a
*ht
->ht_mixgain
)>>8;
1999 b
= (b
*ht
->ht_mixgain
)>>8;
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
;
2029 hvl_mixchunk( ht
, samples
, buf1
, buf2
, bufmod
);
2030 buf1
+= samples
* 4;
2031 buf2
+= samples
* 4;
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 )
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 --------------
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;
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;
2085 if( (donenotedel
==0) && ((Step
->stp_FXb
&0xf)==0xe) && ((Step
->stp_FXbParam
&0xf0)==0xd0) )
2087 if( voice
->vc_NoteDelayOn
)
2089 voice
->vc_NoteDelayOn
= 0;
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;
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
;
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
;
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 );
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] );
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
];
2224 int32 panl
[MAX_CHANNELS
];
2225 int32 panr
[MAX_CHANNELS
];
2226 // uint32 vu[MAX_CHANNELS];
2228 //uint32 i, chans, loops;
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
;
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
;
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
;
2274 //for( i=0; i<chans; i++ )
2278 /* Ring Modulation */
2279 j
= ((src
[0][pos
[0]>>16]*rsrc
[0][rpos
[0]>>16])>>7)*vol
[0];
2280 rpos
[0] += rdelta
[0];
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;
2292 a
= (a
*ht
->ht_mixgain
)>>8;
2293 b
= (b
*ht
->ht_mixgain
)>>8;
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;
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){