XM Infomation Code

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

XM Infomation Code

Post by BackupUser »

Restored from previous forum. Originally posted by Inner.

Missing pattern decoding/decompression not sure which would be the appropreate word there, mainly due to to the fact that I don't know how to decompress stuff does my head in, if I am not using someone else DLL for example ACE.. anyway I am ramblerling, I don't know what use this is too anyone but never the less you never know.

Code: Select all

;-----------------------------------------------------------------------------
;
; XM - File Reader
;
; ToDo:
; Pattern Decoding 
;
; Based on:
;       The XM module format description for XM files version $0104.
;       By Mr.H of Triton in 1994.
;
; Code : T.J.Roughton / (A.K.A) Innner
;
;-----------------------------------------------------------------------------
Dim notetable.s(256)
OpenConsole()
    filename.s=OpenFileRequester("","","",0)
    For octv=0 To 7
        Restore notes
        For nt=0 To 11
             Read nts.s
             notetable(nti)=nts+" - "+Str(octv)
             nti+1
        Next
    Next
    fsize=FileSize(filename)
    *memptr=AllocateMemory(0,fsize,0)
    If(*memptr0)
        PrintN("*** Memory Aloocated")
        If(ReadFile(0,filename))
            PrintN("*** File loaded "+filename)
            ReadData(*memptr,fsize)
            CloseFile(0)
        EndIf
        DeleteFile("XM.log")
        OpenFile(0,"XM.log")
        WriteStringN("--------------------------- Header ---------------------------")
        idtext.s=PeekS(*memptr,17)
        modname.s=PeekS(*memptr+17,20)
        trackername.s=PeekS(*memptr+38,20)
        version_hi=PeekB(*memptr+5 
        version_lo=PeekB(*memptr+59)
        header_size=PeekL(*memptr+60)        ; 60      4  (dword) Header size
        songlen=PeekW(*memptr+64)            ; +4      2   (word) Song length (in patten order table)                                         
        restartpos=PeekW(*memptr+66)         ; +6      2   (word) Restart position
        numchan=PeekW(*memptr+6             ; +8      2   (word) Number of channels (2,4,6,8,10,...,32)
        numpatt=PeekW(*memptr+70)            ;+10      2   (word) Number of patterns (max 256)
        numinst=PeekW(*memptr+72)            ;+12      2   (word) Number of instruments (max 128)
        fraqtab=PeekW(*memptr+74)            ;+14      2   (word) Flags: bit 0: 0 = Amiga frequency table (see below);
                                             ;                                  1 = Linear frequency table
        deftempo=PeekW(*memptr+76)           ;+16      2   (word) Default tempo
        defbpm=PeekW(*memptr+7              ;+18      2   (word) Default BPM
        patordertab=PeekB(*memptr+80)        ;+20    256   (byte) Pattern order table
        WriteStringN("ID Text                     : "+idtext)
        WriteStringN("Module Name                 : "+modname)
        WriteStringN("Tracker Name                : "+trackername)
        WriteStringN("Version                     : "+Str(version_lo)+"."+Str(version_hi))
        WriteStringN("Header Size                 : "+Str(header_size))
        WriteStringN("Song Length                 : "+Str(songlen))
        WriteStringN("Restart Pos                 : "+Str(restartpos))
        WriteStringN("Num Channels                : "+Str(numchan))
        WriteStringN("Num Patterns                : "+Str(numpatt))
        WriteStringN("Num Instruments             : "+Str(numinst))
        WriteStringN("Freq Table                  : "+Str(fraqtab))
        WriteStringN("Default Tempo               : "+Str(deftempo))
        WriteStringN("Default BPM                 : "+Str(defbpm))
        WriteStringN("Pattern Order               : "+Str(patordertab))
        ;-----------------------------------------------------------------------------
        ;Patterns: (Skip Info It's not needed)
        ;-----------------------------------------------------------------------------
        WriteStringN("--------------------------- Patterns ---------------------------")
        npati=256
        For pati=0 To numpatt-1
            header_patsize=PeekL(*memptr+npati+80)
            pack_type=PeekB(*memptr+fkoff+256+84)      ; +4      1   (byte) Packing type (always 0)
            num_rows=PeekW(*memptr+fkoff+256+85)       ; +5      2   (word) Number of rows in pattern (1..256)
            pack_patdatsize=PeekW(*memptr+npati+87)

            WriteStringN("Pattern Header Size         : "+Str(header_patsize))
            WriteStringN("Pattern Pack Type           : "+Str(pack_type))
            WriteStringN("Num Rows                    : "+Str(num_rows))
            WriteStringN("Packed Pattern Data Size    : "+Str(pack_patdatsize))

            npati+header_patsize+pack_patdatsize
        Next
        npati+80
        For getinsti=0 To numinst-1    
            WriteStringN("--------------------------- Instruments ---------------------------")
            WriteStringN("Instrument No. : "+Str(getinsti)+" @ "+Str(npati))
            WriteStringN("-------------------------------------------------------------------")
            instsize=PeekL(*memptr+npati)          ; ?     4  (dword) Instrument size
            instname.s=PeekS(*memptr+npati+4,22)   ; +4     22 (char) Instrument name
            insttype=PeekB(*memptr+npati+26)       ;+26      1 (byte) Instrument type (always 0)
            instninst=PeekW(*memptr+npati+27)      ;+27      2 (word) Number of samples in instrument
            WriteStringN("Instrument size             : "+Str(instsize))
            WriteStringN("Instrument name             : "+instname)
            WriteStringN("Instrument type             : "+Str(insttype))
            WriteStringN("No. of samples              : "+Str(instninst))
            If(instninst>0)
                *smpaddr=*memptr+npati
                header_smpsize=PeekL(*smpaddr+29)   ; +29      4  (dword) Sample header size
                WriteString("Sample number for all notes : ")
                For i=0 To 96
                    smpno_notes=PeekB(*smpaddr+33+i); +33     96   (byte) Sample number for all notes
                    WriteString(Str(smpno_notes))
                Next
                WriteStringN("")
                WriteString("Points for volume envelope  : ")
                For i=0 To 48
                    smp_pointsfvol=PeekB(*smpaddr+129+i);+129     48   (byte) Points for volume envelope
                    WriteString(Str(smp_pointsfvol))
                Next
                WriteStringN("")
                WriteString("Points for panning envelope : ")
                For i=0 To 48
                    smp_pointsfpan=PeekB(*smpaddr+177+i);+177     48   (byte) Points for panning envelope
                    WriteString(Str(smp_pointsfpan))
                Next
                WriteStringN("")
                smpno_volpoints=PeekB(*smpaddr+225) ;+225      1   (byte) Number of volume points
                smpno_panpoints=PeekB(*smpaddr+226) ;+226      1   (byte) Number of panning points
                smp_volsuspoint=PeekB(*smpaddr+227) ;+227      1   (byte) Volume sustain point
                smp_vollopspoint=PeekB(*smpaddr+228);+228      1   (byte) Volume loop start point
                smp_vollopepoint=PeekB(*smpaddr+229);+229      1   (byte) Volume loop end point
                smp_pansuspoint=PeekB(*smpaddr+230) ;+230      1   (byte) Panning sustain point
                smp_panlopspoint=PeekB(*smpaddr+231);+231      1   (byte) Panning loop start point
                smp_panlopepoint=PeekB(*smpaddr+232);+232      1   (byte) Panning loop end point
                smp_voltype=PeekB(*smpaddr+233)     ;+233      1   (byte) Volume type: bit 0: On; 1: Sustain; 2: Loop
                smp_pantype=PeekB(*smpaddr+234)     ;+234      1   (byte) Panning type: bit 0: On; 1: Sustain; 2: Loop
                smpvirb_type=PeekB(*smpaddr+235)    ;+235      1   (byte) Vibrato type
                smpvirb_sweep=PeekB(*smpaddr+236)   ;+236      1   (byte) Vibrato sweep
                smpvirb_depth=PeekB(*smpaddr+237)   ;+237      1   (byte) Vibrato depth
                smpvirb_rate=PeekB(*smpaddr+238)    ;+238      1   (byte) Vibrato rate
                smp_volfadeout=PeekW(*smpaddr+239)  ;+239      2   (word) Volume fadeout
                ;smp=PeekW()                        ;+241      2   (word) Reserved
                WriteStringN("Sample Header Size          : "+Str(header_smpsize))
                WriteStringN("Sample number for all notes : "+Str(smpno_notes))
                WriteStringN("Number of volume points     : "+Str(smpno_volpoints))
                WriteStringN("Number of panning points    : "+Str(smpno_panpoints))
                WriteStringN("Volume sustain point        : "+Str(smp_volsuspoint))
                WriteStringN("Volume loop start point     : "+Str(smp_vollopspoint))
                WriteStringN("Volume loop end point       : "+Str(smp_vollopepoint))
                WriteStringN("Panning sustain point       : "+Str(smp_pansuspoint))
                WriteStringN("Panning loop start point    : "+Str(smp_panlopspoint))
                WriteStringN("Panning loop end point      : "+Str(smp_panlopepoint))
                WriteStringN("Number of volume points     : "+Str(smpno_volpoints))
                WriteStringN("Number of panning points    : "+Str(smpno_panpoints))
                WriteStringN("Volume type                 : "+Str(smp_voltype))
                WriteStringN("Panning type                : "+Str(smp_pantype))
                WriteStringN("Vibrato Type                : "+Str(smpvirb_type))
                WriteStringN("Vibrato Sweep               : "+Str(smpvirb_sweep))
                WriteStringN("Vibrato Depth               : "+Str(smpvirb_depth))
                WriteStringN("Vibrato Rate                : "+Str(smpvirb_rate))
                WriteStringN("Volume FadeOut              : "+Str(smp_volfadeout))
                ;-----------------------------------------------------------------------------
                ;Sample headers
                ;-----------------------------------------------------------------------------
                WriteStringN("--------------------------- Samples ---------------------------")

                *smpaddr=*memptr+npati+instsize
                For csmpi=0 To instninst-1
                    smp_smplen=PeekL(*smpaddr+smpic)          ;   ?      4  (dword) Sample length
                    smp_smploops=PeekL(*smpaddr+4+smpic)      ;  +4      4  (dword) Sample loop start
                    smp_smploope=PeekL(*smpaddr+8+smpic)      ;  +8      4  (dword) Sample loop length
                    smp_smpvol=PeekB(*smpaddr+12+smpic)       ; +12      1   (byte) Volume
                    smp_smpfinetune=PeekB(*smpaddr+13+smpic)  ; +13      1   (byte) Finetune (signed byte -16..+15)
                    smp_smptype=PeekB(*smpaddr+14+smpic)      ; +14      1   (byte) Type: Bit 0-1: 0 = No loop, 1 = Forward loop,
                                                              ;                                    2 = Ping-pong loop;
                                                              ;                                    4 : 16-bit sampledata
                    smp_smpan=PeekB(*smpaddr+15+smpic)        ; +15      1   (byte) Panning (0-255)
                    smp_smprelnote=PeekB(*smpaddr+16+smpic)   ; +16      1   (byte) Relative note number (signed byte)
                    ;smp=PeekB(*smpaddr+17)                   ; +17      1   (byte) Reserved
                    smp_name.s=PeekS(*smpaddr+18+smpic,22)    ; +18     22   (char) Sample name
                    smpic+40
                    WriteStringN("Sample Length               : "+Str(smp_smplen))
                    WriteStringN("Sample loop start           : "+Str(smp_smploops))
                    WriteStringN("Sample loop length          : "+Str(smp_smploope))
                    WriteStringN("Volume                      : "+Str(smp_smpvol))
                    WriteStringN("Finetune                    : "+Str(smp_smpfinetune))
                    WriteStringN("Type                        : "+Str(smp_smptype))
                    WriteStringN("Panning                     : "+Str(smp_smpan))
                    WriteStringN("Relative note number        : "+Str(smp_smprelnote))
                    WriteStringN("Sample name                 : "+smp_name)
                    sampdatsize+smp_smplen                                        
                Next
                npati+instsize+smpic+sampdatsize
                smpic=0 : sampdatsize=0
            Else
                npati+instsize
            EndIf
        Next
        CloseFile(0)
        ;WriteStringN("                            : "+Str())
        FreeMemory(0)
    EndIf
    Input()
CloseConsole()
DataSection
    notes:
    Data.s "C ","C#","D ","D#","E ","F ","F#","G ","G#","A ","A#","B "
EndDataSection