unit hvl;
{$mode objfpc}{$H+}
interface
uses
ctypes;
const
MAX_CHANNELS = 16;
AMIGA_PAL_XTAL = 28375160;
AMIGA_NTSC_XTAL = 28636360;
AMIGA_CPU_PAL_CLK = (AMIGA_PAL_XTAL div 4);
AMIGA_CPU_NTSC_CLK = (AMIGA_NTSC_XTAL div 4);
AMIGA_CIA_PAL_CLK = (AMIGA_CPU_PAL_CLK div 10);
AMIGA_CIA_NTSC_CLK = (AMIGA_CPU_NTSC_CLK div 10);
AMIGA_PAULA_PAL_CLK = (AMIGA_CPU_PAL_CLK div 2);
AMIGA_PAULA_NTSC_CLK = (AMIGA_CPU_NTSC_CLK div 2);
function Period2Freq(period: Double): Double; inline;
type
int8 = ShortInt;
uint8 = Byte;
int16 = SmallInt;
uint16 = Word;
int32 = LongInt;
uint32 = Cardinal;
float64 = Double;
TEXT = PChar;
hvl_malloc_callback = function(Size: csize_t): Pointer; cdecl;
hvl_free_callback = procedure(Ptr: Pointer); cdecl;
Phvl_envelope = ^hvl_envelope;
hvl_envelope = record
aFrames, aVolume: int16;
dFrames, dVolume: int16;
sFrames: int16;
rFrames, rVolume: int16;
pad: int16;
end;
Phvl_plsentry = ^hvl_plsentry;
hvl_plsentry = record
ple_Note: uint8;
ple_Waveform: uint8;
ple_Fixed: int16;
ple_FX: array[0..1] of int8;
ple_FXParam: array[0..1] of int8;
end;
Phvl_plist = ^hvl_plist;
hvl_plist = record
pls_Speed: int16;
pls_Length: int16;
pls_Entries: Phvl_plsentry;
end;
Phvl_instrument = ^hvl_instrument;
hvl_instrument = record
ins_Name: array[0..127] of TEXT;
ins_Volume: uint8;
ins_WaveLength: uint8;
ins_FilterLowerLimit: uint8;
ins_FilterUpperLimit: uint8;
ins_FilterSpeed: uint8;
ins_SquareLowerLimit: uint8;
ins_SquareUpperLimit: uint8;
ins_SquareSpeed: uint8;
ins_VibratoDelay: uint8;
ins_VibratoSpeed: uint8;
ins_VibratoDepth: uint8;
ins_HardCutRelease: uint8;
ins_HardCutReleaseFrames: uint8;
ins_Envelope: hvl_envelope;
ins_PList: hvl_plist;
end;
Phvl_position = ^hvl_position;
hvl_position = record
pos_Track: array[0..MAX_CHANNELS-1] of uint8;
pos_Transpose: array[0..MAX_CHANNELS-1] of int8;
end;
Phvl_step = ^hvl_step;
hvl_step = record
stp_Note: uint8;
stp_Instrument: uint8;
stp_FX: uint8;
stp_FXParam: uint8;
stp_FXb: uint8;
stp_FXbParam: uint8;
end;
Phvl_voice = ^hvl_voice;
hvl_voice = record
vc_Track, vc_NextTrack: int16;
vc_Transpose, vc_NextTranspose, vc_OverrideTranspose: int16;
vc_ADSRVolume: int32;
vc_ADSR: hvl_envelope;
vc_Instrument: Phvl_instrument;
vc_SamplePos, vc_Delta: uint32;
vc_InstrPeriod, vc_TrackPeriod, vc_VibratoPeriod, vc_WaveLength: uint16;
vc_NoteMaxVolume: int16;
vc_PerfSubVolume: uint16;
vc_NewWaveform, vc_Waveform, vc_PlantPeriod, vc_VoiceVolume: uint8;
vc_PlantSquare, vc_IgnoreSquare, vc_FixedNote: uint8;
vc_VolumeSlideUp, vc_VolumeSlideDown, vc_HardCut: int16;
vc_HardCutRelease: uint8;
vc_HardCutReleaseF: int16;
vc_PeriodSlideOn: uint8;
vc_PeriodSlideSpeed, vc_PeriodSlidePeriod, vc_PeriodSlideLimit: int16;
vc_PeriodSlideWithLimit, vc_PeriodPerfSlideSpeed, vc_PeriodPerfSlidePeriod: int16;
vc_PeriodPerfSlideOn: uint8;
vc_VibratoDelay, vc_VibratoSpeed, vc_VibratoCurrent, vc_VibratoDepth: int16;
vc_SquareOn, vc_SquareInit, vc_SquareWait: int16;
vc_SquareLowerLimit, vc_SquareUpperLimit, vc_SquarePos, vc_SquareSign: int16;
vc_SquareSlidingIn, vc_SquareReverse: int16;
vc_FilterOn, vc_FilterInit: uint8;
vc_FilterWait, vc_FilterSpeed, vc_FilterUpperLimit, vc_FilterLowerLimit: int16;
vc_FilterPos, vc_FilterSign, vc_FilterSlidingIn, vc_IgnoreFilter: int16;
vc_PerfCurrent, vc_PerfSpeed, vc_PerfWait: int16;
vc_PerfList: Phvl_plist;
vc_AudioPointer, vc_AudioSource: PInt8;
vc_NoteDelayOn, vc_NoteCutOn: uint8;
vc_NoteDelayWait, vc_NoteCutWait, vc_AudioPeriod, vc_AudioVolume: int16;
vc_WNRandom: int32;
vc_MixSource: PInt8;
vc_SquareTempBuffer: array[0..$7F] of int8;
vc_VoiceBuffer: array[0..$282*4-1] of int8;
vc_VoiceNum, vc_TrackMasterVolume, vc_TrackOn: uint8;
vc_VoicePeriod: int16;
vc_Pan, vc_SetPan, vc_PanMultLeft, vc_PanMultRight: uint32;
vc_RingSamplePos, vc_RingDelta: uint32;
vc_RingMixSource: PInt8;
vc_RingPlantPeriod: uint8;
vc_RingInstrPeriod, vc_RingBasePeriod, vc_RingAudioPeriod: int16;
vc_RingAudioSource: PInt8;
vc_RingNewWaveform, vc_RingWaveform, vc_RingFixedPeriod: uint8;
vc_RingVoiceBuffer: array[0..$282*4-1] of int8;
end;
Phvl_tune = ^hvl_tune;
hvl_tune = record
ht_Name: array[0..127] of Char; // TEXT ht_Name[128];
ht_SongNum: UInt16; // uint16 ht_SongNum;
ht_Frequency: UInt32; // uint32 ht_Frequency;
ht_FreqF: Double; // float64 ht_FreqF;
ht_WaveformTab: array[0..MAX_CHANNELS-1] of PInt8; // const int8 *ht_WaveformTab[MAX_CHANNELS];
ht_Restart: UInt16; // uint16 ht_Restart;
ht_PositionNr: UInt16; // uint16 ht_PositionNr;
ht_SpeedMultiplier: UInt8; // uint8 ht_SpeedMultiplier;
ht_TrackLength: UInt8; // uint8 ht_TrackLength;
ht_TrackNr: UInt8; // uint8 ht_TrackNr;
ht_InstrumentNr: UInt8; // uint8 ht_InstrumentNr;
ht_SubsongNr: UInt8; // uint8 ht_SubsongNr;
ht_PosJump: UInt16; // uint16 ht_PosJump;
ht_PlayingTime: UInt32; // uint32 ht_PlayingTime;
ht_Tempo: Int16; // int16 ht_Tempo;
ht_PosNr: Int16; // int16 ht_PosNr;
ht_StepWaitFrames: UInt16; // uint16 ht_StepWaitFrames;
ht_NoteNr: Int16; // int16 ht_NoteNr;
ht_PosJumpNote: UInt16; // uint16 ht_PosJumpNote;
ht_GetNewPosition: UInt8; // uint8 ht_GetNewPosition;
ht_PatternBreak: UInt8; // uint8 ht_PatternBreak;
ht_SongEndReached: UInt8; // uint8 ht_SongEndReached;
ht_Stereo: UInt8; // uint8 ht_Stereo;
ht_Subsongs: PUInt16; // uint16 *ht_Subsongs;
ht_Channels: UInt16; // uint16 ht_Channels;
ht_Positions: ^hvl_position; // struct hvl_position *ht_Positions;
ht_Tracks: array[0..255, 0..63] of hvl_step; // struct hvl_step ht_Tracks[256][64];
ht_Instruments: ^hvl_instrument; // struct hvl_instrument *ht_Instruments;
ht_Voices: array[0..MAX_CHANNELS-1] of hvl_voice; // struct hvl_voice ht_Voices[MAX_CHANNELS];
ht_defstereo: Int32; // int32 ht_defstereo;
ht_defpanleft: Int32; // int32 ht_defpanleft;
ht_defpanright: Int32; // int32 ht_defpanright;
ht_mixgain: Int32; // int32 ht_mixgain;
ht_Version: UInt8; // uint8 ht_Version;
end;
procedure hvl_DecodeFrame(ht: Pointer; buf1, buf2: PAnsiChar; bufmod: int32); cdecl; external 'hvl.dll';
procedure hvl_InitReplayer; cdecl; external 'hvl.dll';
function hvl_InitSubsong(ht: Pointer; nr: uint32): Boolean; cdecl; external 'hvl.dll';
function hvl_LoadTune(name: PAnsiChar; freq, defstereo: uint32): Phvl_tune; cdecl; external 'hvl.dll';
function hvl_ParseTune(buf: PByte; buflen, freq, defstereo: uint32): Pointer; cdecl; external 'hvl.dll';
procedure hvl_FreeTune(ht: Pointer); cdecl; external 'hvl.dll';
implementation
function Period2Freq(period: Double): Double; inline;
begin
Result := (AMIGA_PAULA_PAL_CLK * 65536.0) / period;
end;
end.