Directly from BeRoTracker src (sorry for the german variable names etc. from my old coding style, the code base is very old)

[pascal]
TYPE TITSignatur=ARRAY[1..4] OF CHAR;

TITHeader=PACKED RECORD
Signatur:TITSignatur; {IMPM}
Name:ARRAY[1..26] OF CHAR;
RowHilightMinor,RowHilightMajor:BYTE;
TrackLaenge:WORD;
AnzahlDerInstrumente:WORD;
AnzahlDerSamples:WORD;
AnzahlDerPatterns:WORD;
TrackerVersion:WORD;
KompatibelMitVersion:WORD;
Flags:WORD;
SpezialFlag:WORD;
GlobalLautstaerke:BYTE; {0-128}
MixingLautstaerke:BYTE; {0-128}
Speed:BYTE;
BPM:BYTE;
PanSeparation:BYTE; {0-128,128=Max. Separation}
MIDIPitchDepth:BYTE;
KommentarLaenge:WORD;
KommentarPosition:LONGWORD;
ExtendedDataOffset:LONGWORD; {Reserviert}
KanalPan:ARRAY[0..64-1] OF BYTE;
KanalLautstaerke:ARRAY[0..64-1] OF BYTE;
END;

TITEnvNode=PACKED RECORD
Env:BYTE;
KnotenPunkt:WORD;
END;

TITEnvelope=PACKED RECORD
Flags:BYTE;
AnzahlDerKnoten:BYTE;
SchleifeStart:BYTE;
SchleifeEnde:BYTE;
SustainSchleifeStart:BYTE;
SustainSchleifeEnde:BYTE;
Knoten:ARRAY[0..25-1] OF TITEnvNode;
Reserviert:BYTE;
END;

TITAlterInstrumentHeader=PACKED RECORD
Signatur:TITSignatur; {IMPI}
DateiName:ARRAY[1..12] OF CHAR;
LeerUndReserviert:BYTE;
Flags:BYTE;
VolSchleifeStart:BYTE;
VolSchleifeEnde:BYTE;
SustainSchleifeStart:BYTE;
SustainSchleifeEnde:BYTE;
Reserviert:WORD;
FadeOut:WORD;
NNA:BYTE;
DNC:BYTE;
TrackerVersion:WORD;
AnzahlDerSamples:BYTE;
Reserviert2:BYTE;
Name:ARRAY[1..26] OF CHAR;
Reserviert3:ARRAY[0..6-1] OF CHAR;
NoteSampleTabelle:ARRAY[0..240-1] OF BYTE;
VolEnvelope:ARRAY[0..200-1] OF BYTE;
KnotenPunkte:ARRAY[0..2*25-1] OF BYTE;
END;

TITInstrumentHeader=PACKED RECORD
Signatur:TITSignatur; {IMPI}
DateiName:ARRAY[1..12] OF CHAR;
LeerUndReserviert:BYTE;
NNA:BYTE;
DCT:BYTE;
DCA:BYTE;
FadeOut:WORD;
PPS:BYTE;
PPC:BYTE;
GbV:BYTE;
DfP:BYTE;
RV:BYTE;
RP:BYTE;
TrackerVersion:WORD;
AnzahlDerSamples:BYTE;
Reserviert:BYTE;
Name:ARRAY[1..26] OF CHAR;
IFC:BYTE;
IFR:BYTE;
MCh:BYTE;
MPr:BYTE;
MidiBank:WORD;
NoteSampleTabelle:ARRAY[0..240-1] OF BYTE;
VolEnv:TITEnvelope;
PanEnv:TITEnvelope;
PitchEnv:TITEnvelope;
Leer:LONGWORD;
END;

TITPattern=PACKED RECORD
DatenGroesse:WORD;
Zeilen:WORD;
Reserviert:LONGWORD;
END;

TITSampleHeader=PACKED RECORD
Signatur:TITSignatur; {IMPS}
DateiName:ARRAY[1..12] OF CHAR;
LeerUndReserviert:BYTE;
GvL:BYTE;
Flags:BYTE;
Lautstaerke:BYTE;
Name:ARRAY[1..26] OF CHAR;
KonvertierFlag:BYTE;
Panning:BYTE;
Laenge:LONGWORD;
SchleifeStart:LONGWORD;
SchleifeEnde:LONGWORD;
C5Speed:LONGWORD;
SustainSchleifeStart:LONGWORD;
SustainSchleifeEnde:LONGWORD;
SampleDatenPosition:LONGWORD;
VibratoSpeed:BYTE;
VibratoDepth:BYTE;
VibratoRate:BYTE;
VibratoWaveForm:BYTE;
END;
[/pascal]

[pascal]
FUNCTION TEngineSample.LeseITBits(ABitWidth:BYTE):LONGWORD;
VAR Wert:LONGWORD;
B:BYTE;
BitWidth:BYTE;
BEGIN
Wert:=0;
IF LONGWORD(SourcePosition)<LONGWORD(SourceEnd) THEN BEGIN
BitWidth:=ABitWidth;
B:=0;
WHILE BitWidth>SourceRemainBits DO BEGIN
Wert:=Wert OR (SourcePosition^ SHL B);
IF LONGWORD(SourcePosition)>=LONGWORD(SourceEnd) THEN BEGIN
RESULT:=Wert;
EXIT;
END;
INC(LONGWORD(SourcePosition));
INC(B,SourceRemainBits);
DEC(BitWidth,SourceRemainBits);
SourceRemainBits:=8;
END;
Wert:=Wert OR ((SourcePosition^ AND ((1 SHL BitWidth)-1)) SHL B);
SourcePosition^:=SourcePosition^ SHR BitWidth;
DEC(SourceRemainBits,BitWidth);
END;
RESULT:=Wert;
END;

FUNCTION TEngineSample.LeseITBlock(Daten:TEngineStream):BOO LEAN;
VAR S:WORD;
BEGIN
RESULT:=FALSE;
IF Daten.Read(S,2)<>2 THEN EXIT;
GETMEM(SourceBuffer,S);
IF NOT ASSIGNED(SourceBuffer) THEN EXIT;
IF Daten.Read(SourceBuffer^,S)<>S THEN BEGIN
FREEMEM(SourceBuffer);
EXIT;
END;
SourcePosition:=SourceBuffer;
LONGWORD(SourceEnd):=LONGWORD(SourceBuffer)+S;
SourceRemainBits:=8;
RESULT:=TRUE;
END;

FUNCTION TEngineSample.GebeITBlockFrei:BOOLEAN;
BEGIN
RESULT:=FALSE;
IF ASSIGNED(SourceBuffer) THEN BEGIN
FREEMEM(SourceBuffer);
SourceBuffer:=NIL;
RESULT:=TRUE;
EXIT;
END;
END;

PROCEDURE TEngineSample.LeseITSample8BitPacked(Daten:TEngine Stream;Groesse:LONGWORD;bIT215,Stereo:BOOLEAN);
VAR DestPosSHORTINT;
BlockLength:WORD;
BlockPosition:WORD;
Width:BYTE;
Value:WORD;
D1HORTINT;
D2HORTINT;
VHORTINT;
L:LONGINT;
Border:BYTE;
Shift:BYTE;
BEGIN
Bits:=8;
IF Stereo THEN BEGIN
Kaenale:=2;
END ELSE BEGIN
Kaenale:=1;
END;
Vergroessern(Groesse);
FILLCHAR(DataPointer^,Groesse,#0);

DestPos:=DataPointer;

L:=Groesse;
WHILE L>0 DO BEGIN
IF NOT LeseITBlock(Daten) THEN EXIT;
IF L<$8000 THEN BEGIN
BlockLength:=L;
END ELSE BEGIN
BlockLength:=$8000;
END;
BlockPosition:=0;

Width:=9;
D1:=0;
D2:=0;
WHILE BlockPosition<BlockLength DO BEGIN
Value:=LeseITBits(Width);
IF Width<7 THEN BEGIN
IF Value=(1 SHL (Width-1)) THEN BEGIN
Value:=LeseITBits(3)+1;
IF Value<Width THEN BEGIN
Width:=Value;
END ELSE BEGIN
Width:=Value+1;
END;
CONTINUE;
END;
END ELSE IF Width<9 THEN BEGIN
Border:=($FF SHR (9-Width))-4;
IF (Value>Border) AND (Value<=(Border+) THEN BEGIN
DEC(Value,Border);
IF Value<Width THEN BEGIN
Width:=Value;
END ELSE BEGIN
Width:=Value+1;
END;
CONTINUE;
END;
END ELSE IF Width=9 THEN BEGIN
IF (Value AND $100)<>0 THEN BEGIN
Width:=(Value+1) AND $FF;
CONTINUE;
END;
END ELSE BEGIN
GebeITBlockFrei;
EXIT;
END;
IF Width<8 THEN BEGIN
Shift:=8-Width;
V:=SHORTINT(Value SHL Shift);
V:=V SHR Shift;
END ELSE BEGIN
V:=SHORTINT(Value);
END;
INC(D1,V);
INC(D2,D1);
IF bIT215 THEN BEGIN
DestPos^:=D2;
INC(DestPos);
END ELSE BEGIN
DestPos^:=D1;
INC(DestPos);
END;
INC(BlockPosition);
END;
GebeITBlockFrei;
DEC(L,BlockLength);
END;
ConvertStereo;
END;

PROCEDURE TEngineSample.LeseITSample16BitPacked(Daten:TEngin eStream;Groesse:LONGWORD;bIT215,Stereo:BOOLEAN);
VAR DestPosSMALLINT;
BlockLength:WORD;
BlockPosition:WORD;
Width:BYTE;
Value:LONGWORD;
D1MALLINT;
D2MALLINT;
VMALLINT;
L:LONGINT;
Border:WORD;
Shift:BYTE;
BEGIN
Bits:=16;
IF Stereo THEN BEGIN
Kaenale:=2;
END ELSE BEGIN
Kaenale:=1;
END;
Vergroessern(Groesse);
FILLCHAR(DataPointer^,Groesse,#0);

DestPos:=DataPointer;

L:=Groesse SHR 1;
WHILE L>0 DO BEGIN
IF NOT LeseITBlock(Daten) THEN EXIT;
IF L<$4000 THEN BEGIN
BlockLength:=L;
END ELSE BEGIN
BlockLength:=$4000;
END;
BlockPosition:=0;

Width:=17;
D1:=0;
D2:=0;
WHILE BlockPosition<BlockLength DO BEGIN
Value:=LeseITBits(Width);
IF Width<7 THEN BEGIN
IF Value=(1 SHL (Width-1)) THEN BEGIN
Value:=LeseITBits(4)+1;
IF Value<Width THEN BEGIN
Width:=Value;
END ELSE BEGIN
Width:=Value+1;
END;
CONTINUE;
END;
END ELSE IF Width<17 THEN BEGIN
Border:=($FFFF SHR (17-Width))-8;
IF (Value>Border) AND (Value<=(Border+16)) THEN BEGIN
DEC(Value,Border);
IF Value<Width THEN BEGIN
Width:=Value;
END ELSE BEGIN
Width:=Value+1;
END;
CONTINUE;
END;
END ELSE IF Width=17 THEN BEGIN
IF (Value AND $10000)<>0 THEN BEGIN
Width:=(Value+1) AND $FF;
CONTINUE;
END;
END ELSE BEGIN
GebeITBlockFrei;
EXIT;
END;
IF Width<16 THEN BEGIN
Shift:=16-Width;
V:=SMALLINT(Value SHL Shift);
V:=V SHR Shift;
END ELSE BEGIN
V:=SMALLINT(Value);
END;
INC(D1,V);
INC(D2,D1);
IF bIT215 THEN BEGIN
DestPos^:=D2;
INC(DestPos);
END ELSE BEGIN
DestPos^:=D1;
INC(DestPos);
END;
INC(BlockPosition);
END;
GebeITBlockFrei;
DEC(L,BlockLength);
END;
ConvertStereo;
END;

PROCEDURE TEngineSample.LeseSample8BitADPCM4(Daten:TEngineSt ream;Groesse:LONGWORD;Signed,Stereo:BOOLEAN);
VAR BSHORTINT;
RB:BYTE;
DHORTINT;
I,L:LONGWORD;
Tabelle:ARRAY[0..15] OF BYTE;
BEGIN
Bits:=8;
IF Stereo THEN BEGIN
Kaenale:=2;
END ELSE BEGIN
Kaenale:=1;
END;
Vergroessern(Groesse);
Daten.Read(Tabelle,16);
I:=0;
L:=(Groesse+1) DIV 2;
B:=DataPointer;
D:=0;
WHILE I<L DO BEGIN
RB:=Daten.ReadByte;
D:=SHORTINT(BYTE(BYTE(D)+Tabelle[RB AND $F]));
B^:=D;
INC(B);
D:=SHORTINT(BYTE(BYTE(D)+Tabelle[RB SHR 4]));
B^:=D;
INC(B);
INC(I);
END;
IF NOT Signed THEN BEGIN
I:=0;
B:=DataPointer;
WHILE I<Groesse DO BEGIN
BYTE(B^):=BYTE(B^)+128;
INC(B);
INC(I);
END;
END;
ConvertStereo;
END;

PROCEDURE TEngineSample.ConvertStereo;
VAR Counter,SampleSize,SampleLength:INTEGER;
SampleBufferOINTER;
PQB,PZBBYTE;
PQW,PZWWORD;
BEGIN
TRY
IF (Bits IN [8,16]) AND (Kaenale=2) THEN BEGIN
SampleSize:=RealSize;
SampleLength:=SampleSize DIV (2*(Bits DIV );
GETMEM(SampleBuffer,SampleSize);
IF Bits=8 THEN BEGIN
PQB:=DataPointer;
PZB:=SampleBuffer;
FOR Counter:=1 TO SampleLength DO BEGIN
PZB^:=PQB^;
INC(PQB);
INC(PZB,2);
END;
PZB:=SampleBuffer;
INC(PZB);
FOR Counter:=1 TO SampleLength DO BEGIN
PZB^:=PQB^;
INC(PQB);
INC(PZB,2);
END;
END ELSE IF Bits=16 THEN BEGIN
PQW:=DataPointer;
PZW:=SampleBuffer;
FOR Counter:=1 TO SampleLength DO BEGIN
PZW^:=PQW^;
INC(PQW);
INC(PZW,2);
END;
PZW:=SampleBuffer;
INC(PZW);
FOR Counter:=1 TO SampleLength DO BEGIN
PZW^:=PQW^;
INC(PQW);
INC(PZW,2);
END;
END;
MOVE(SampleBuffer^,DataPointer^,SampleSize);
FREEMEM(SampleBuffer);
END;
EXCEPT
END;
END;
[/pascal]

[pascal]
FUNCTION TEngineTrack.LadeIT(Daten:TEngineStream):BOOLEAN;
VAR Header:TITHeader;
I,N,AltePosition,NLP,NLS:INTEGER;
J,Note,Ins,EV,L,LP,LW,ExtendedDataOffset:LONGWORD;
W:WORD;
C:CHAR;
IOfs,SOfs,POfs:ARRAY[0..256] OF LONGWORD;
PatOrd:ARRAY[0..255] OF BYTE;
AltesInstrument:TITAlterInstrumentHeader;
NeuesInstrument:TITInstrumentHeader;
EinSample:TITSampleHeader;
Signatur:TITSignatur;
C32:ARRAY[0..32-1] OF CHAR;
FUNCTION LesePattern(PI:BYTE):BOOLEAN;
VAR LeereNote,EineNote:TEnginePatternNote;
ITPattern:TITPattern;
Row,J,K:WORD;
KanalMaske:ARRAY[0..63] OF BYTE;
LetzterWert:ARRAY[0..63] OF TEnginePatternNote;
EinByte,EinWeiteresByte,Flag,KanalNr:BYTE;
PDaten:TEngineStream;
PDatenBufferOINTER;
BEGIN
RESULT:=TRUE;
IF POfs[PI]=0 THEN BEGIN
IF TrackerModus THEN BEGIN
Pattern[PI].Vergroessern(64,AnzahlDerKaenale);
END ELSE BEGIN
Pattern[PI].Vergroessern(0,AnzahlDerKaenale);
END;
EXIT;
END;

Daten.Seek(POfs[PI]);
IF Daten.Read(ITPattern,SIZEOF(TITPattern))<>SIZEOF(T ITPattern) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;

SwapLittleEndianData16(ITPattern.DatenGroesse);
SwapLittleEndianData16(ITPattern.Zeilen);
SwapLittleEndianData32(ITPattern.Reserviert);

IF (Daten.Position+ITPattern.DatenGroesse)>Daten.Size THEN BEGIN
RESULT:=FALSE;
EXIT;
END;

GETMEM(PDatenBuffer,ITPattern.DatenGroesse);
IF Daten.Read(PDatenBuffer^,ITPattern.DatenGroesse)<> ITPattern.DatenGroesse THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
PDaten:=TEngineStream.Create;
PDaten.Seek(0);
PDaten.Write(PDatenBuffer^,ITPattern.DatenGroesse) ;
FREEMEM(PDatenBuffer,ITPattern.DatenGroesse);

Pattern[PI].Vergroessern(ITPattern.Zeilen,AnzahlDerKaenale);

LeereNote.Note:=0;
LeereNote.SampleInstrument:=0;
LeereNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_KEI N;
LeereNote.Lautstaerke:=0;
LeereNote.Panning:=$FF;
LeereNote.Filter:=$FF;
LeereNote.Effekt:=EFFEKT_KEIN;
LeereNote.EffektParameter:=0;

FOR J:=0 TO AnzahlDerKaenale-1 DO BEGIN
FOR K:=0 TO Pattern[I].AnzahlDerZeilen-1 DO Pattern[PI].SetzeNote(K,J,LeereNote);
END;

PDaten.Seek(0);
Row:=0;
FOR J:=0 TO 63 DO KanalMaske[J]:=0;
FILLCHAR(LetzterWert,SIZEOF(LetzterWert),#0);
WHILE (Row<Pattern[PI].AnzahlDerZeilen) AND (PDaten.Position<PDaten.Size) DO BEGIN
IF PDaten.Read(EinByte,1)<>1 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
Flag:=EinByte;
IF Flag=0 THEN BEGIN
INC(Row);
END ELSE BEGIN
KanalNr:=EinByte AND $7F;
IF KanalNr<>0 THEN KanalNr:=(Flag-1) AND $3F;

EineNote:=LeereNote;

IF (Flag AND $80)<>0 THEN BEGIN
IF PDaten.Read(EinByte,1)=0 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
KanalMaske[KanalNr]:=EinByte;
END;

IF (KanalMaske[KanalNr] AND 1)<>0 THEN BEGIN
IF PDaten.Read(EinByte,1)=0 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
IF KanalNr<AnzahlDerKaenale THEN BEGIN
IF EinByte<$80 THEN INC(EinByte);
EineNote.Note:=EinByte;
LetzterWert[KanalNr].Note:=EinByte;
END;
END;

IF (KanalMaske[KanalNr] AND 2)<>0 THEN BEGIN
IF PDaten.Read(EinByte,1)=0 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
IF KanalNr<AnzahlDerKaenale THEN BEGIN
EineNote.SampleInstrument:=EinByte;
LetzterWert[KanalNr].SampleInstrument:=EinByte;
END;
END;

IF (KanalMaske[KanalNr] AND 4)<>0 THEN BEGIN
IF PDaten.Read(EinByte,1)=0 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
IF KanalNr<AnzahlDerKaenale THEN BEGIN
IF EinByte<=64 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_VOLU ME;
EineNote.Lautstaerke:=EinByte;
END ELSE IF EinByte<75 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_FINE VOLUP;
EineNote.Lautstaerke:=EinByte-65;
END ELSE IF EinByte<85 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_FINE VOLDOWN;
EineNote.Lautstaerke:=EinByte-75;
END ELSE IF EinByte<95 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_VOLS LIDEUP;
EineNote.Lautstaerke:=EinByte-85;
END ELSE IF EinByte<105 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_VOLS LIDEDOWN;
EineNote.Lautstaerke:=EinByte-95;
END ELSE IF EinByte<115 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_PORT ADOWN;
EineNote.Lautstaerke:=EinByte-105;
END ELSE IF EinByte<125 THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_PORT AUP;
EineNote.Lautstaerke:=EinByte-115;
END ELSE IF (EinByte>=12 AND (EinByte<=192) THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_PANN ING;
EineNote.Lautstaerke:=EinByte-128;
END ELSE IF (EinByte>=193) AND (EinByte<=202) THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_TONE PORTAMENTO;
EineNote.Lautstaerke:=ImpulseTrackerPortaVolCmd[EinByte-193];
END ELSE IF (EinByte>=203) AND (EinByte<=212) THEN BEGIN
EineNote.LautstaerkeBefehl:=LAUTSTAERKEEFFEKT_VIBR ATO;
EineNote.Lautstaerke:=EinByte-203;
END;
LetzterWert[KanalNr].LautstaerkeBefehl:=EineNote.LautstaerkeBefehl;
LetzterWert[KanalNr].Lautstaerke:=EineNote.Lautstaerke;
END;
END;

IF (KanalMaske[KanalNr] AND <>0 THEN BEGIN
IF PDaten.Read(EinByte,1)=0 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
IF PDaten.Read(EinWeiteresByte,1)=0 THEN BEGIN
RESULT:=FALSE;
BREAK;
END;
IF KanalNr<AnzahlDerKaenale THEN BEGIN
IF EinByte<>0 THEN BEGIN
EineNote.Effekt:=EinByte;
EineNote.EffektParameter:=EinWeiteresByte;
KonvertiereS3MEffekt(EineNote,TRUE);
LetzterWert[KanalNr].Effekt:=EineNote.Effekt;
LetzterWert[KanalNr].EffektParameter:=EineNote.EffektParameter;
END;
END;
END;

IF ((KanalMaske[KanalNr] AND $10)<>0) AND (KanalNr<AnzahlDerKaenale) THEN BEGIN
EineNote.Note:=LetzterWert[KanalNr].Note;
END;

IF ((KanalMaske[KanalNr] AND $20)<>0) AND (KanalNr<AnzahlDerKaenale) THEN BEGIN
EineNote.SampleInstrument:=LetzterWert[KanalNr].SampleInstrument;
END;

IF ((KanalMaske[KanalNr] AND $40)<>0) AND (KanalNr<AnzahlDerKaenale) THEN BEGIN
EineNote.LautstaerkeBefehl:=LetzterWert[KanalNr].LautstaerkeBefehl;
EineNote.Lautstaerke:=LetzterWert[KanalNr].Lautstaerke;
END;

IF ((KanalMaske[KanalNr] AND $80)<>0) AND (KanalNr<AnzahlDerKaenale) THEN BEGIN
EineNote.Effekt:=LetzterWert[KanalNr].Effekt;
EineNote.EffektParameter:=LetzterWert[KanalNr].EffektParameter;
END;

IF KanalNr<AnzahlDerKaenale THEN Pattern[PI].SetzeNote(Row,KanalNr,EineNote);
END;
END;
PDaten.Free;
END;
BEGIN
IF (Daten.Size<$100) OR NOT ASSIGNED(Daten) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;

Daten.Seek(0);
IF Daten.Read(Header,SIZEOF(TITHeader))<>SIZEOF(TITHe ader) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
SwapLittleEndianData16(Header.TrackLaenge);
SwapLittleEndianData16(Header.AnzahlDerInstrumente );
SwapLittleEndianData16(Header.AnzahlDerSamples);
SwapLittleEndianData16(Header.AnzahlDerPatterns);
SwapLittleEndianData16(Header.TrackerVersion);
SwapLittleEndianData16(Header.KompatibelMitVersion );
SwapLittleEndianData16(Header.Flags);
SwapLittleEndianData16(Header.SpezialFlag);
SwapLittleEndianData16(Header.KommentarLaenge);
SwapLittleEndianData32(Header.KommentarPosition);
SwapLittleEndianData32(Header.ExtendedDataOffset);
IF (Header.Signatur<>'IMPM') OR (Header.AnzahlDerInstrumente>MaximumAnzahlDerDatei Instrumente) OR (Header.AnzahlDerSamples>MaximumAnzahlDerDateiSamp les) OR (Header.AnzahlDerPatterns>MaximumAnzahlDerDateiPat terns) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;

RowHilightMinor:=Header.RowHilightMinor;
RowHilightMajor:=Header.RowHilightMajor;

ExtendedDataOffset:=Header.ExtendedDataOffset;

AnzahlDerInstrumente:=Header.AnzahlDerInstrumente;
AnzahlDerSamples:=Header.AnzahlDerSamples;
AnzahlDerPatterns:=Header.AnzahlDerPatterns;

Stereo:=(Header.Flags AND $1)<>0;
NullVolumeOptimization:=(Header.Flags AND $2)<>0;
Instruments:=(Header.Flags AND $4)<>0;
LinearSlides:=(Header.Flags AND $<>0;
OldEffects:=(Header.Flags AND $10)<>0;
CompatibleMode:=(Header.Flags AND $20)<>0;
EmbeddedMIDIConfig:=(Header.Flags AND $80)<>0;
ExtendedFilterRange:=(Header.Flags AND $1000)<>0;
StartNullFilterOptimization:=(Header.Flags AND $8000)=0;
OriginalImpulseTrackerFilter:=((Header.TrackerVers ion>=$214) AND (Header.TrackerVersion<=$216)) OR (Header.KompatibelMitVersion>=$214);

Name:='';
FOR I:=1 TO 26 DO IF Header.Name[I]<>#0 THEN Name:=Name+Header.Name[I];

IF Header.GlobalLautstaerke<>0 THEN BEGIN
StartGlobalLautstaerke:=Header.GlobalLautstaerke SHL 1;
IF StartGlobalLautstaerke=0 THEN StartGlobalLautstaerke:=256;
IF StartGlobalLautstaerke>256 THEN StartGlobalLautstaerke:=256;
END;

IF Header.Speed<>0 THEN StartSpeed:=Header.Speed;
IF Header.BPM<>0 THEN StartBPM:=Header.BPM;
Speed:=StartSpeed;
BPM:=StartBPM;
StartRowsPerBeat:=0;
RowsPerBeat:=StartRowsPerBeat;

MixingLautstaerke:=Header.MixingLautstaerke;

SetTrackChannels(64);

AnzahlDerKaenale:=0;
FOR I:=0 TO 63 DO IF Header.KanalPan[I]<>$FF THEN BEGIN
KanalEinstellungen[I].Lautstaerke:=Header.KanalLautstaerke[I];
KanalEinstellungen[I].Pan:=128;
KanalEinstellungen[I].Mute:=(Header.KanalPan[I] AND $80)<>0;
N:=Header.KanalPan[I] AND $7F;
IF N<=64 THEN KanalEinstellungen[I].Pan:=N SHL 2;
KanalEinstellungen[I].Surround:=N=100;
INC(AnzahlDerKaenale);
END;
IF AnzahlDerKaenale<1 THEN AnzahlDerKaenale:=1;

SetTrackChannels(AnzahlDerKaenale);

IF ((Header.SpezialFlag AND 1)<>0) AND (Header.KommentarLaenge<>0) AND (INTEGER(Header.KommentarPosition+Header.Kommentar Laenge)<Daten.Size) THEN BEGIN
AltePosition:=Daten.Position;
IF LONGWORD(Daten.Seek(Header.KommentarPosition))<>He ader.KommentarPosition THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
J:=0;
WHILE J<Header.KommentarLaenge DO BEGIN
IF Daten.Read(C,1)<>1 THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
Message:=Message+C;
{$IFDEF vcltracker}
IF C=#13 THEN Message:=Message+#10;
{$ENDIF}
INC(J);
END;
Daten.Seek(AltePosition);
END;

IF Header.TrackLaenge>256 THEN BEGIN
RESULT:=FALSE;
EXIT;
END;

TrackLaenge:=Header.TrackLaenge-1;
TrackRealLaenge:=TrackLaenge;
IF Daten.Read(PatOrd,Header.TrackLaenge)<>Header.Trac kLaenge THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
PatternOrder.KopierenVonByte(PatOrd,TrackLaenge);

IF Daten.Read(IOfs,4*Header.AnzahlDerInstrumente)<>(4 *Header.AnzahlDerInstrumente) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF Daten.Read(SOfs,4*Header.AnzahlDerSamples)<>(4*Hea der.AnzahlDerSamples) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF Daten.Read(POfs,4*Header.AnzahlDerPatterns)<>(4*He ader.AnzahlDerPatterns) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF Daten.Read(W,SIZEOF(WORD))<>SIZEOF(WORD) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;

IF (Daten.Position+(W SHL 3))<Daten.Size THEN BEGIN
Daten.Seek(Daten.Position+(W SHL 3));
END;

IF EmbeddedMIDIConfig THEN BEGIN
LP:=Daten.Position;
IF Daten.Read(MIDIConfig,SIZEOF(TMIDIConfig))<>SIZEOF (TMIDIConfig) THEN BEGIN
{ ResetMIDIConfig;
Daten.Seek(LP);}
RESULT:=FALSE;
EXIT;
END;
END;

LP:=Daten.Position;

FOR I:=1 TO Header.AnzahlDerInstrumente DO BEGIN
Daten.Seek(IOfs[I-1]);
IF NOT ASSIGNED(Instrument[I]) THEN Instrument[I]:=TEngineInstrument.Create(I);
Instrument[I].Clear;
IF (Header.TrackerVersion<$200) THEN BEGIN
IF Daten.Read(AltesInstrument,SIZEOF(TITAlterInstrume ntHeader))<>SIZEOF(TITAlterInstrumentHeader) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF AltesInstrument.Signatur<>'IMPI' THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
SwapLittleEndianData16(AltesInstrument.Reserviert) ;
SwapLittleEndianData16(AltesInstrument.FadeOut);
SwapLittleEndianData16(AltesInstrument.TrackerVers ion);
Instrument[I].Name:=TRIMRIGHT(AltesInstrument.Name);
Instrument[I].DateiName:=TRIMRIGHT(AltesInstrument.DateiName);
Instrument[I].FadeOut:=AltesInstrument.FadeOut SHL 6;
Instrument[I].GlobalLautstaerke:=128;
FOR J:=0 TO 119 DO BEGIN
Note:=AltesInstrument.NoteSampleTabelle[J*2];
Ins:=AltesInstrument.NoteSampleTabelle[J*2+1];
IF Ins<MaximumAnzahlDerDateiSamples THEN BEGIN
Instrument[I].NoteMapper.SampleMap[J]:=Ins;
END;
IF Note<128 THEN BEGIN
Instrument[I].NoteMapper.NoteMap[J]:=Note+1;
END ELSE IF Note>=$FE THEN BEGIN
Instrument[I].NoteMapper.NoteMap[J]:=Note;
END;
END;
Instrument[I].VolEnv.Aktiv:=(AltesInstrument.Flags AND 1)<>0;
Instrument[I].VolEnv.Schleife:=(AltesInstrument.Flags AND 2)<>0;
Instrument[I].VolEnv.SustainSchleife:=(AltesInstrument.Flags AND 4)<>0;
Instrument[I].VolEnv.SchleifeStart:=AltesInstrument.VolSchleife Start;
Instrument[I].VolEnv.SchleifeEnde:=AltesInstrument.VolSchleifeE nde;
Instrument[I].VolEnv.SustainSchleifeStart:=AltesInstrument.Sust ainSchleifeStart;
Instrument[I].VolEnv.SustainSchleifeEnde:=AltesInstrument.Susta inSchleifeEnde;
FOR ev:=0 TO 25-1 DO BEGIN
Instrument[I].VolEnv.Knoten[ev]:=AltesInstrument.KnotenPunkte[ev*2];
Instrument[I].VolEnv.Env[ev]:=AltesInstrument.KnotenPunkte[ev*2+1];
IF Instrument[I].VolEnv.Knoten[ev]=$FE THEN BEGIN
Instrument[I].VolEnv.AnzahlDerKnoten:=ev;
BREAK;
END;
END;
Instrument[I].NNA:=AltesInstrument.NNA;
Instrument[I].DCT:=AltesInstrument.DNC;
Instrument[I].Pan:=$80;
END ELSE BEGIN
IF Daten.Read(NeuesInstrument,SIZEOF(TITInstrumentHea der))<>SIZEOF(TITInstrumentHeader) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF NeuesInstrument.Signatur<>'IMPI' THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
SwapLittleEndianData16(NeuesInstrument.FadeOut);
SwapLittleEndianData16(NeuesInstrument.TrackerVers ion);
SwapLittleEndianData16(NeuesInstrument.MIDIBank);
Instrument[I].Name:=TRIMRIGHT(NeuesInstrument.Name);
Instrument[I].DateiName:=TRIMRIGHT(NeuesInstrument.DateiName);
Instrument[I].MIDIProgramm:=NeuesInstrument.MPr;
Instrument[I].MIDIKanal:=NeuesInstrument.MCh;
Instrument[I].MIDIBank:=NeuesInstrument.MIDIBank;
Instrument[I].FadeOut:=NeuesInstrument.FadeOut SHL 5;

IF (Instrument[I].MIDIProgramm<>0) OR (Instrument[I].MIDIKanal<>0) OR (NeuesInstrument.MIDIBank<>0) THEN BEGIN
DoImportMPFX:=TRUE;
END;

Instrument[I].GlobalLautstaerke:=NeuesInstrument.GbV;
IF Instrument[I].GlobalLautstaerke>128 THEN Instrument[I].GlobalLautstaerke:=128;
FOR J:=0 TO 119 DO BEGIN
Note:=NeuesInstrument.NoteSampleTabelle[J*2];
Ins:=NeuesInstrument.NoteSampleTabelle[J*2+1];
Instrument[I].NoteMapper.SampleMap[J]:=0;
Instrument[I].NoteMapper.NoteMap[J]:=0;
IF Ins<MaximumAnzahlDerDateiSamples THEN BEGIN
Instrument[I].NoteMapper.SampleMap[J]:=Ins;
END;
IF Note<128 THEN BEGIN
Instrument[I].NoteMapper.NoteMap[J]:=Note+1;
END ELSE IF Note>=$FE THEN BEGIN
Instrument[I].NoteMapper.NoteMap[J]:=Note;
END;
END;

Instrument[I].VolEnv.Aktiv:=(NeuesInstrument.VolEnv.Flags AND 1)<>0;
Instrument[I].VolEnv.Schleife:=(NeuesInstrument.VolEnv.Flags AND 2)<>0;
Instrument[I].VolEnv.SustainSchleife:=(NeuesInstrument.VolEnv.F lags AND 4)<>0;
Instrument[I].VolEnv.Carry:=(NeuesInstrument.VolEnv.Flags AND <>0;

Instrument[I].PanEnv.Aktiv:=(NeuesInstrument.PanEnv.Flags AND 1)<>0;
Instrument[I].PanEnv.Schleife:=(NeuesInstrument.PanEnv.Flags AND 2)<>0;
Instrument[I].PanEnv.SustainSchleife:=(NeuesInstrument.PanEnv.F lags AND 4)<>0;
Instrument[I].PanEnv.Carry:=(NeuesInstrument.PanEnv.Flags AND <>0;

Instrument[I].PitchEnv.Aktiv:=(NeuesInstrument.PitchEnv.Flags AND 1)<>0;
Instrument[I].PitchEnv.Schleife:=(NeuesInstrument.PitchEnv.Flag s AND 2)<>0;
Instrument[I].PitchEnv.SustainSchleife:=(NeuesInstrument.PitchE nv.Flags AND 4)<>0;
Instrument[I].PitchEnv.Carry:=(NeuesInstrument.PitchEnv.Flags AND <>0;
Instrument[I].PitchEnvAlsFilterEnv:=(NeuesInstrument.PitchEnv.F lags AND 12<>0;

Instrument[I].VolEnv.AnzahlDerKnoten:=NeuesInstrument.VolEnv.An zahlDerKnoten;
IF Instrument[I].VolEnv.AnzahlDerKnoten>25 THEN Instrument[I].VolEnv.AnzahlDerKnoten:=25;

Instrument[I].PanEnv.AnzahlDerKnoten:=NeuesInstrument.PanEnv.An zahlDerKnoten;
IF Instrument[I].PanEnv.AnzahlDerKnoten>25 THEN Instrument[I].PanEnv.AnzahlDerKnoten:=25;

Instrument[I].PitchEnv.AnzahlDerKnoten:=NeuesInstrument.PitchEn v.AnzahlDerKnoten;
IF Instrument[I].PitchEnv.AnzahlDerKnoten>25 THEN Instrument[I].PitchEnv.AnzahlDerKnoten:=25;

Instrument[I].VolEnv.SchleifeStart:=NeuesInstrument.VolEnv.Schl eifeStart;
Instrument[I].VolEnv.SchleifeEnde:=NeuesInstrument.VolEnv.Schle ifeEnde;
Instrument[I].VolEnv.SustainSchleifeStart:=NeuesInstrument.VolE nv.SustainSchleifeStart;
Instrument[I].VolEnv.SustainSchleifeEnde:=NeuesInstrument.VolEn v.SustainSchleifeEnde;

Instrument[I].PanEnv.SchleifeStart:=NeuesInstrument.PanEnv.Schl eifeStart;
Instrument[I].PanEnv.SchleifeEnde:=NeuesInstrument.PanEnv.Schle ifeEnde;
Instrument[I].PanEnv.SustainSchleifeStart:=NeuesInstrument.PanE nv.SustainSchleifeStart;
Instrument[I].PanEnv.SustainSchleifeEnde:=NeuesInstrument.PanEn v.SustainSchleifeEnde;

Instrument[I].PitchEnv.SchleifeStart:=NeuesInstrument.PitchEnv. SchleifeStart;
Instrument[I].PitchEnv.SchleifeEnde:=NeuesInstrument.PitchEnv.S chleifeEnde;
Instrument[I].PitchEnv.SustainSchleifeStart:=NeuesInstrument.Pi tchEnv.SustainSchleifeStart;
Instrument[I].PitchEnv.SustainSchleifeEnde:=NeuesInstrument.Pit chEnv.SustainSchleifeEnde;

FOR ev:=0 TO 25-1 DO BEGIN
Instrument[I].VolEnv.Knoten[ev]:=SwapWordLittleEndian(NeuesInstrument.VolEnv.Knot en[ev].KnotenPunkt);
Instrument[I].VolEnv.Env[ev]:=NeuesInstrument.VolEnv.Knoten[ev].Env;
Instrument[I].PanEnv.Knoten[ev]:=SwapWordLittleEndian(NeuesInstrument.PanEnv.Knot en[ev].KnotenPunkt);
Instrument[I].PanEnv.Env[ev]:=NeuesInstrument.PanEnv.Knoten[ev].Env+32;
Instrument[I].PitchEnv.Knoten[ev]:=SwapWordLittleEndian(NeuesInstrument.PitchEnv.Kn oten[ev].KnotenPunkt);
Instrument[I].PitchEnv.Env[ev]:=NeuesInstrument.PitchEnv.Knoten[ev].Env+32;
END;

Instrument[I].NNA:=NeuesInstrument.NNA;
Instrument[I].DCT:=NeuesInstrument.DCT;
Instrument[I].DNA:=NeuesInstrument.DCA;
Instrument[I].PanEnv.PitchCenter:=NeuesInstrument.PPC;
Instrument[I].PanEnv.PitchSeparation:=NeuesInstrument.PPS;
Instrument[I].IFC:=NeuesInstrument.IFC;
Instrument[I].IFR:=NeuesInstrument.IFR;
Instrument[I].VolEnv.Swing:=NeuesInstrument.rv;
Instrument[I].PanEnv.Swing:=NeuesInstrument.rp;
Instrument[I].Pan:=(NeuesInstrument.dfp AND $7F) SHL 2;
IF Instrument[I].Pan>256 THEN Instrument[I].Pan:=128;
Instrument[I].PanningAktiv:=NeuesInstrument.dfp<$80;
END;
IF (Instrument[I].VolEnv.SchleifeStart>=25) OR (Instrument[I].VolEnv.SchleifeEnde>=25) THEN Instrument[I].VolEnv.Schleife:=FALSE;
IF (Instrument[I].VolEnv.SustainSchleifeStart>=25) OR (Instrument[I].VolEnv.SustainSchleifeEnde>=25) THEN Instrument[I].VolEnv.SustainSchleife:=FALSE;
IF (Instrument[I].PanEnv.SchleifeStart>=25) OR (Instrument[I].PanEnv.SchleifeEnde>=25) THEN Instrument[I].PanEnv.Schleife:=FALSE;
IF (Instrument[I].PanEnv.SustainSchleifeStart>=25) OR (Instrument[I].PanEnv.SustainSchleifeEnde>=25) THEN Instrument[I].PanEnv.SustainSchleife:=FALSE;
IF (Instrument[I].PitchEnv.SchleifeStart>=25) OR (Instrument[I].PitchEnv.SchleifeEnde>=25) THEN Instrument[I].PitchEnv.Schleife:=FALSE;
IF (Instrument[I].PitchEnv.SustainSchleifeStart>=25) OR (Instrument[I].PitchEnv.SustainSchleifeEnde>=25) THEN Instrument[I].PitchEnv.SustainSchleife:=FALSE;
END;

FOR I:=1 TO Header.AnzahlDerSamples DO BEGIN
Daten.Seek(SOfs[I-1]);
IF Daten.Read(EinSample,SIZEOF(TITSampleHeader))<>SIZ EOF(TITSampleHeader) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF EinSample.Signatur<>'IMPS' THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
IF (Header.Flags AND $4)=0 THEN BEGIN
IF NOT ASSIGNED(Instrument[I]) THEN Instrument[I]:=TEngineInstrument.Create(I);
Instrument[I].SampleClear;
END;
IF NOT ASSIGNED(Sample[I]) THEN Sample[I]:=TEngineSample.Create(I);
SwapLittleEndianData32(EinSample.Laenge);
SwapLittleEndianData32(EinSample.SchleifeStart);
SwapLittleEndianData32(EinSample.SchleifeEnde);
SwapLittleEndianData32(EinSample.SustainSchleifeSt art);
SwapLittleEndianData32(EinSample.SustainSchleifeEn de);
SwapLittleEndianData32(EinSample.C5Speed);
SwapLittleEndianData32(EinSample.SampleDatenPositi on);
Sample[I].Clear;
Sample[I].Name:=TRIMRIGHT(EinSample.Name);
Sample[I].DateiName:=TRIMRIGHT(EinSample.DateiName);
Sample[I].Laenge:=0;
Sample[I].SchleifeStart:=EinSample.SchleifeStart;
Sample[I].SchleifeEnde:=EinSample.SchleifeEnde;
IF Sample[I].SchleifeEnde>EinSample.Laenge THEN Sample[I].SchleifeEnde:=EinSample.Laenge;
Sample[I].SustainSchleifeStart:=EinSample.SustainSchleifeSt art;
Sample[I].SustainSchleifeEnde:=EinSample.SustainSchleifeEnd e;
Sample[I].C4Speed:=EinSample.C5Speed;
IF Sample[I].C4Speed=0 THEN Sample[I].C4Speed:=8363;
IF EinSample.C5Speed<256 THEN Sample[I].C4Speed:=256;
Sample[I].Lautstaerke:=EinSample.Lautstaerke SHL 2;
IF Sample[I].Lautstaerke>256 THEN Sample[I].Lautstaerke:=256;
Sample[I].GlobalLautstaerke:=EinSample.GvL;
IF Sample[I].GlobalLautstaerke>64 THEN Sample[I].GlobalLautstaerke:=64;
Sample[I].Loop:=(EinSample.Flags AND $10)<>0;
Sample[I].SustainLoop:=(EinSample.Flags AND $20)<>0;
Sample[I].PingPongLoop:=(EinSample.Flags AND $40)<>0;
Sample[I].PingPongSustain:=(EinSample.Flags AND $80)<>0;
Sample[I].Pan:=(EinSample.Panning AND $7F) SHL 2;
IF Sample[I].Pan>256 THEN Sample[I].Pan:=256;
Sample[I].Panning:=(EinSample.Panning AND $80)<>0;
Sample[I].VibratoRate:=EinSample.VibratoRate;
Sample[I].VibratoDepth:=EinSample.VibratoDepth;
Sample[I].VibratoSpeed:=EinSample.VibratoSpeed;
Sample[I].VibratoWaveForm:=VibratoIT2XM[EinSample.VibratoWaveForm AND 7];
IF (EinSample.SampleDatenPosition<>0) AND (EinSample.SampleDatenPosition<LONGWORD(Daten.Size )) AND (EinSample.Laenge<>0) THEN BEGIN
Daten.Seek(EinSample.SampleDatenPosition);
Sample[I].Laenge:=EinSample.Laenge;
Sample[I].Vergroessern(0);
IF (EinSample.Flags AND 4)<>0 THEN BEGIN
Sample[I].Kaenale:=2;
END ELSE BEGIN
Sample[I].Kaenale:=1;
END;
IF (EinSample.Flags AND 2)<>0 THEN BEGIN
Sample[I].Bits:=16;
END ELSE BEGIN
Sample[I].Bits:=8;
END;
IF (EinSample.Flags AND 4)<>0 THEN BEGIN
IF (EinSample.Flags AND 2)<>0 THEN BEGIN
IF ((EinSample.Flags AND <>0) AND (Header.TrackerVersion>=$214) THEN BEGIN // Gepackt
Sample[I].LeseITSample16BitPacked(Daten,Sample[I].Laenge*4,(Header.KompatibelMitVersion>=$215) AND ((EinSample.KonvertierFlag AND 4)<>0),TRUE);
END ELSE BEGIN // Nicht gepackt
Sample[I].LesePCMSample16Bit(Daten,Sample[I].Laenge*4,(EinSample.KonvertierFlag AND 1)<>0,TRUE);
END;
END ELSE BEGIN // 8 Bit
IF ((EinSample.Flags AND <>0) AND (Header.TrackerVersion>=$214) THEN BEGIN // Gepackt
Sample[I].LeseITSample8BitPacked(Daten,Sample[I].Laenge*2,(Header.KompatibelMitVersion>=$215) AND ((EinSample.KonvertierFlag AND 4)<>0),TRUE);
END ELSE IF EinSample.KonvertierFlag=$FF THEN BEGIN // ADPCM4
Sample[I].LeseSample8BitADPCM4(Daten,Sample[I].Laenge,(EinSample.KonvertierFlag AND 1)<>0,FALSE);
END ELSE BEGIN // Nicht gepackt
Sample[I].LesePCMSample8Bit(Daten,Sample[I].Laenge*2,(EinSample.KonvertierFlag AND 1)<>0,TRUE);
END;
END;
END ELSE BEGIN // Mono
IF (EinSample.Flags AND 2)<>0 THEN BEGIN
IF ((EinSample.Flags AND <>0) AND (Header.TrackerVersion>=$214) THEN BEGIN // Gepackt
Sample[I].LeseITSample16BitPacked(Daten,Sample[I].Laenge*2,(Header.KompatibelMitVersion>=$215) AND ((EinSample.KonvertierFlag AND 4)<>0),FALSE);
END ELSE BEGIN // Nicht gepackt
Sample[I].LesePCMSample16Bit(Daten,Sample[I].Laenge*2,(EinSample.KonvertierFlag AND 1)<>0,FALSE);
END;
END ELSE BEGIN // 8 Bit
IF ((EinSample.Flags AND <>0) AND (Header.TrackerVersion>=$214) THEN BEGIN // Gepackt
Sample[I].LeseITSample8BitPacked(Daten,Sample[I].Laenge,(Header.KompatibelMitVersion>=$215) AND ((EinSample.KonvertierFlag AND 4)<>0),FALSE);
END ELSE IF EinSample.KonvertierFlag=$FF THEN BEGIN // ADPCM4
Sample[I].LeseSample8BitADPCM4(Daten,Sample[I].Laenge,(EinSample.KonvertierFlag AND 1)<>0,FALSE);
END ELSE BEGIN // Nicht gepackt
Sample[I].LesePCMSample8Bit(Daten,Sample[I].Laenge,(EinSample.KonvertierFlag AND 1)<>0,FALSE);
END;
END;
END;
END;
Sample[I].FrequenzZuTranspose;
END;

FOR I:=0 TO AnzahlDerPatterns-1 DO BEGIN
IF I<MaximumAnzahlDerDateiPatterns THEN BEGIN
IF NOT LesePattern(I) THEN BEGIN
RESULT:=FALSE;
EXIT;
END;
END;
END;

Daten.Seek(LP);
TRY
ReadExtendedData(Daten,FALSE);
EXCEPT
END;

IF (ExtendedDataOffset>0) AND (ExtendedDataOffset<LONGWORD(Daten.Size)) AND ((Header.Flags AND $8000)<>0) THEN BEGIN
Daten.Seek(ExtendedDataOffset);
END;
Daten.Seek(Daten.Size);

//DoImportMPFX:=TRUE;
MindestPeriodeWert:=8;
MaximumPeriodeWert:=$F000;
TrackType:=ettIT;
EffectNotation:=EFFECTNOTATION_S3MIT;
RESULT:=TRUE;
END;
[/pascal]

[pascal]
{$IFDEF FPC}
{$IFDEF FPC_LITTLE_ENDIAN}
{$DEFINE LITTLE_ENDIAN}
{$ELSE}
{$IFDEF FPC_BIG_ENDIAN}
{$DEFINE BIG_ENDIAN}
{$ENDIF}
{$ENDIF}
{$ELSE}
{$DEFINE LITTLE_ENDIAN}
{$ENDIF}
FUNCTION SwapWordLittleEndian(Value:WORD):WORD; {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
BEGIN
{$IFDEF BIG_ENDIAN}
RESULT:=((Value AND $FF00) SHR OR ((Value AND $FF) SHL ;
{$ELSE}
RESULT:=Value;
{$ENDIF}
END;

FUNCTION SwapDWordLittleEndian(Value:LONGWORD):LONGWORD; {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
BEGIN
{$IFDEF BIG_ENDIAN}
RESULT:=((Value AND $FF000000) SHR 24) OR ((Value AND $00FF0000) SHR OR
((Value AND $0000FF00) SHL OR ((Value AND $000000FF) SHL 24);
{$ELSE}
RESULT:=Value;
{$ENDIF}
END;

FUNCTION SwapWordBigEndian(Value:WORD):WORD; {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
BEGIN
{$IFDEF LITTLE_ENDIAN}
RESULT:=((Value AND $FF00) SHR OR ((Value AND $FF) SHL ;
{$ELSE}
RESULT:=Value;
{$ENDIF}
END;

FUNCTION SwapDWordBigEndian(Value:LONGWORD):LONGWORD; {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
BEGIN
{$IFDEF LITTLE_ENDIAN}
RESULT:=((Value AND $FF000000) SHR 24) OR ((Value AND $00FF0000) SHR OR
((Value AND $0000FF00) SHL OR ((Value AND $000000FF) SHL 24);
{$ELSE}
RESULT:=Value;
{$ENDIF}
END;

PROCEDURE SwapLittleEndianData16(VAR Data); {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
{$IFDEF BIG_ENDIAN}
VAR Value:WORD ABSOLUTE Data;
BEGIN
Value:=((Value AND $FF00) SHR OR ((Value AND $FF) SHL ;
{$ELSE}
BEGIN
{$ENDIF}
END;

PROCEDURE SwapLittleEndianData32(VAR Data); {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
{$IFDEF BIG_ENDIAN}
VAR Value:LONGWORD ABSOLUTE Data;
BEGIN
Value:=((Value AND $FF000000) SHR 24) OR ((Value AND $00FF0000) SHR OR
((Value AND $0000FF00) SHL OR ((Value AND $000000FF) SHL 24);
{$ELSE}
BEGIN
{$ENDIF}
END;

PROCEDURE SwapBigEndianData16(VAR Data); {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
{$IFDEF LITTLE_ENDIAN}
VAR Value:WORD ABSOLUTE Data;
BEGIN
Value:=((Value AND $FF00) SHR OR ((Value AND $FF) SHL ;
{$ELSE}
BEGIN
RESULT:=Value;
{$ENDIF}
END;

PROCEDURE SwapBigEndianData32(VAR Data); {$IFDEF FPC}{INLINE;}{$ELSE}REGISTER;{$ENDIF}
{$IFDEF LITTLE_ENDIAN}
VAR Value:LONGWORD ABSOLUTE Data;
BEGIN
Value:=((Value AND $FF000000) SHR 24) OR ((Value AND $00FF0000) SHR OR
((Value AND $0000FF00) SHL OR ((Value AND $000000FF) SHL 24);
{$ELSE}
BEGIN
{$ENDIF}
END;
[/pascal]