Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Any C programmers wanna help convert code to convert between MIDI + CSV?
#50
Hi QB64 friends
I have followed some links posted by MadSciJr
and I have found very interesting and reach of information the published work of Utah in VB6
moreover many links have talked about a unfoundable QMIDI.BAS written in Qbasic.

After different googled researches I got it...
Here it is and I post it in Codebox tool

Code: (Select All)
'538 lines (511 sloc)  20.5 KB

'QMIDI v3.0
'QBasic/QuickBASIC background MIDI player
'by Jesse Dorland (jessedorland@hotmail.com)
'Released to the Public Domain, March 1998
'
'See SAMPLE.BAS for a demo, and be sure to read the documentation before
'using QMIDI, even if you're familiar with previous versions..
'
'Acknowledgements:
'   Mike Huff      - author of the QuickBASIC MIDI code that QMIDI is based
'                    on.
'   Rick Elbers    - author of the QBasic Interrupt routine that was used in
'                    version 1.0.
'   Angelo Mottola - contributed the new Pause/Resume code.
'
'If you decide to use QMIDI, please tell me what you think of it and
'give me some ideas for improvements.  My e-mail address is at the top of
'the code and in the documentation.
'
'-Jesse
'
'DISCLAIMER
'----------
'If your computer suffers crashes, loss of data, or is taken over by
'smurfs as a result of using QMIDI, I won't be responsible for it.
'Reading the documentation should ensure safe operation, but I'm not
'making any guarantees.  You have been warned....

'**** START OF CODE ****

'Returns the amount of memory required to load a MIDI file
DECLARE FUNCTION BytesRequired& (Filename$)
'Detects whether the supplied sound drivers are loaded
DECLARE SUB DriversLoaded (SBMIDI%, SBSIM%)
'Internal functon used by DriversLoaded
DECLARE SUB GetIntVector (IntNum%, Segment%, Offset%)
'Loads and plays a file using SBSIM
DECLARE SUB LoadAndPlayLarge (Filename$)
'Loads and plays a file using SBMIDI
DECLARE SUB LoadAndPlayMIDI (Filename$, MIDISegment%, MIDIOffset%)
'Loads a file using SBSIM
DECLARE SUB LoadLarge (Filename$)
'Loads a file using SBMIDI
DECLARE SUB LoadMIDI (Filename$, MIDISegment%, MIDIOffset%)
'Returns the last error that occurred (if any)
DECLARE FUNCTION MIDIError$ ()
'Pauses a file that is currently playing
DECLARE SUB PauseMIDI ()
'Resumes playing a file after it has been paused
DECLARE SUB ResumeMIDI ()
'Plays a file loaded with LoadLarge
DECLARE SUB PlayLarge ()
'Plays a file loaded with LoadMIDI
DECLARE SUB PlayMIDI (MIDISegment%, MIDIOffset%)
'Stops any MIDI file that is currently playing.
DECLARE SUB StopMIDI ()
'Returns the amount of time a file has been playing
DECLARE FUNCTION TimeMIDI! ()

'The following code is REQUIRED in programs that use QMIDI in order for
'all features to work properly.

Dim Shared MIDI.PLAYTIME As Single
Dim Shared MIDI.ERROR As Integer
Dim Shared MIDI.LOADED As Integer
Dim Shared SBMIDI.INTERRUPT As Integer
Dim Shared SBSIM.INTERRUPT As Integer
MIDI.PLAYTIME = 0
MIDI.ERROR = 0
MIDI.LOADED = 0
SBMIDI.INTERRUPT = &H80
SBSIM.INTERRUPT = &H81

'Insert your own code beginning here.


'The data statements below are REQUIRED in programs that use the
'DriversLoaded routine.  Do not edit any of the data; it will cause
'the routine to return inaccurate information.
SBMIDIData:
Data 156,30,6,80,83,81,82,87,86,85,139,236,80,184,14,16,142,216,142,192,88,131,78,24,1,199,70,12,255,255,128,62
Data 68,1,0,117,59,198,6,68,1,1,251,252,11,219,120,21,129,251,13,0,115,37,131,102,24,254,209,227,255,151,40,0
Data 137,70,12,235,22,247,219,75,129,251,3,0,115,13,131,102,24,254,209,227,255,151,34,0,137,70,12,198,6,68,1,0
Data 93,94,95,90,89,91,88,7,31,157,207,156,250,30,6,80,184,14,16,142,216,142,192,161,145,1,1,6,28,0,114,6
Data 176,32,230,32,235,9,255,6,28,0,156,255,30,18,0,83,81,82,87,86,85,139,236,250,128,62,67,1,0,117,54,140
Data 22,32,0,137,38,30,0,140,216,142,208,188,66,1,198,6,67,1,1,251,252,131,62,133,1,0,116,10,128,62,21,3
Data 0,117,3,232,143,4,250,139,38,30,0,142,22,32,0,198,6,67,1,0,251,93,94,95,90,89,91,88,7,31,157,207
Data 30,6,80,83,81,82,87,86,85,156,184,14,16,142,216,142,192,228,96,10,192,120,18,60,83,117,14,180,2,205,22,36
SBSIMData:
Data 46,143,6,134,1,46,143,6,132,1,46,143,6,130,1,46,131,14,130,1,1,46,131,62,110,1,0,116,6,184,1,0
Data 233,193,0,128,255,5,119,25,10,255,116,27,81,80,51,192,138,207,128,225,127,249,211,208,46,35,6,126,1,88,89,117
Data 6,184,2,0,233,157,0,250,46,140,30,138,1,14,31,140,22,140,1,137,38,142,1,142,22,152,1,139,38,154,1,85
Data 139,236,86,87,6,83,163,144,1,137,22,148,1,137,14,146,1,180,98,205,33,137,30,150,1,180,80,140,203,205,33,199
Data 6,110,1,1,0,251,252,50,192,255,30,118,1,139,94,248,83,134,251,3,219,3,219,50,255,254,14,124,1,117,11,129
Data 6,152,1,0,0,198,6,124,1,20,139,243,91,50,255,30,7,255,156,176,1,114,5,131,38,130,1,254,250,199,6,110
Data 1,0,0,80,180,80,139,30,150,1,205,33,88,91,7,95,94,139,229,93,139,14,146,1,142,22,140,1,139,38,142,1
Data 142,30,138,1,46,255,54,130,1,46,255,54,132,1,46,255,54,134,1,207,85,139,236,131,236,10,137,70,248,137,94,250

'BytesRequired - Returns the amount of memory needed to store a file.
Function BytesRequired& (Filename$)
    'Open the file.
    FF% = FreeFile
    Open Filename$ For Binary As #FF%
    'Store the length of the file.
    FileLen& = LOF(FF%)
    'Close the file.
    Close FF%
    'If the length of the file is 0, assume it does not exist and delete it.
    If FileLen& = 0 Then Kill Filename$
    'Return the length of the file as the number of bytes required.
    BytesRequired& = FileLen&
End Function

DefInt A-Z
Sub DriversLoaded (SBMIDI%, SBSIM%) Static

    'Check the interrupt handlers for int 80h-89h to see if they contain
    'program code from either SBSIM or SBMIDI.  Only those 10 interrupts
    'are checked because chances are slim that either driver will be loaded
    'at int 8Ah or higher, and they will never load themselves below
    '80h.

    For I% = &H80 To &H8A
        'Get the address of the interrupt handler.
        GetIntVector I%, Segment%, Offset%
        'If the address is null, then the interrupt is not in use, and can be
        'skipped.
        If Segment% = 0 And Offset% = 0 Then GoTo Skip:

        'Point to the segment of the interrupt handler.
        Def Seg = Segment%
        Restore SBMIDIData:
        For J% = 0 To 255
            'Read a byte of the SBMIDI program code that has been previously
            'saved.
            Read Byte1%
            'Read a byte of code from the current interrupt handler.
            Byte2% = Peek(Offset% + J%)
            'Do they match?  If so, we may have found SBMIDI!
            If Byte1% = Byte2% Then
                MatchSBMIDI% = 1
                'If not, this interrupt is definitely not occupied by SBMIDI.
            Else
                Select Case J%
                    Case Is = 14, 15, 113, 114, 235, 236
                    Case Else
                        MatchSBMIDI% = 0
                        Exit For
                End Select
            End If
        Next J%
        'If there's a match, set SBMIDI% to the current interrupt.
        If MatchSBMIDI% Then SBMIDI% = I%
        Restore SBSIMData:
        For J% = 0 To 255
            'Read a byte of the SBSIM program code that has been previously
            'saved.
            Read Byte1%
            'Read a byte of code from the current interrupt handler.
            Byte2% = Peek(Offset% + J%)
            'If the values match, SBSIM may be loaded at this interrupt.
            If Byte1% = Byte2% Then
                MatchSBSIM% = 1
                'If not, then it isn't.
            Else
                MatchSBSIM% = 0
                Exit For
            End If
        Next J%
        'If this interrupt handler is a match, set SBSIM% to the current
        'interrupt number.
        If MatchSBSIM% Then SBSIM% = I%

        'If both SBMIDI% and SBSIM% have been detected, there's no need to
        'check the rest of the interrupt handling routines.
        If MatchSBMIDI% And MatchSBSIM% Then Exit For
        Skip:
    Next I%
End Sub

Sub GetIntVector (IntNum%, Segment%, Offset%) Static
    'If the code hasn't been loaded already, do it now.
    If GetIntVCodeLoaded% = 0 Then
        asm$ = asm$ + Chr$(&H55)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)
        asm$ = asm$ + Chr$(&H8A) + Chr$(&H7)
        asm$ = asm$ + Chr$(&HB4) + Chr$(&H35)
        asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)
        asm$ = asm$ + Chr$(&H8C) + Chr$(&HC1)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HDA)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HF)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)
        asm$ = asm$ + Chr$(&H89) + Chr$(&H17)
        asm$ = asm$ + Chr$(&H5D)
        asm$ = asm$ + Chr$(&HCB)
        asm$ = asm$ + Chr$(&H34) + Chr$(&H0)
        asm$ = asm$ + Chr$(&H60)
        asm$ = asm$ + Chr$(&H23) + Chr$(&H0)
        GetIntVCodeLoaded% = 1
    End If
    'Execute the code
    Def Seg = VarSeg(asm$)
    Call Absolute(IntNum%, Segment%, Offset%, SAdd(asm$))
End Sub

DefSng A-Z
Sub LoadAndPlayLarge (Filename$) Static
    'See if an extension was supplied, and if not, add one.
    If InStr(Filename$, ".") = 0 Then Filename$ = Filename$ + ".MID"
    'The sound driver needs an ASCIIZ string (a string that ends with
    'character 0) for a file name.
    If Right$(Filename$, 1) <> Chr$(0) Then Filename$ = Filename$ + Chr$(0)
    'Initialize the MIDI driver and load the file in memory
    If LoadCodeLoaded% = 0 Then
        Lasm$ = ""
        Lasm$ = Lasm$ + Chr$(&H55)
        Lasm$ = Lasm$ + Chr$(&H89) + Chr$(&HE5)
        Lasm$ = Lasm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        Lasm$ = Lasm$ + Chr$(&H8B) + Chr$(&H7)
        Lasm$ = Lasm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)
        Lasm$ = Lasm$ + Chr$(&H8B) + Chr$(&H17)
        Lasm$ = Lasm$ + Chr$(&HBB) + Chr$(&H0) + Chr$(&H5)
        Lasm$ = Lasm$ + Chr$(&HCD) + Chr$(SBSIM.INTERRUPT)
        Lasm$ = Lasm$ + Chr$(&H5D)
        Lasm$ = Lasm$ + Chr$(&HCB)
        LoadCodeLoaded% = 1
    End If
    Def Seg = VarSeg(Lasm$)
    Offset% = SAdd(Lasm$)
    Call Absolute(SAdd(Filename$), VarSeg(Filename$), Offset%)

    'Start the music!!
    If PlayCodeLoaded% = 0 Then
        Pasm$ = ""
        Pasm$ = Pasm$ + Chr$(&HB8) + Chr$(&H1) + Chr$(&H0)
        Pasm$ = Pasm$ + Chr$(&HBA) + Chr$(&H1) + Chr$(&H0)
        Pasm$ = Pasm$ + Chr$(&HBB) + Chr$(&H1) + Chr$(&H5)
        Pasm$ = Pasm$ + Chr$(&HCD) + Chr$(SBSIM.INTERRUPT)
        Pasm$ = Pasm$ + Chr$(&HCB)
        PlayCodeLoaded% = 1
    End If
    Def Seg = VarSeg(Pasm$)
    Offset% = SAdd(Pasm$)
    Call Absolute(Offset%)
    MIDI.LOADED = 1
    MIDI.PLAYTIME = Timer
End Sub

'LoadAndPlayMIDI - Loads a MIDI file into memory and plays it
Sub LoadAndPlayMIDI (Filename$, MIDISegment%, MIDIOffset%)
    'See if an extension was supplied, and if not, add one.
    If InStr(Filename$, ".") = 0 Then Filename$ = Filename$ + ".MID"
    'Open the file
    FF% = FreeFile
    Open Filename$ For Binary As #FF%
    FileLen& = LOF(FF%)
    Close #FF%
    'If the file is empty, delete it and exit now.
    If FileLen& = 0 Then Kill Filename$: MIDI.ERROR = 1: Exit Sub
    'If the file is too large, exit now.
    If FileLen& > 65536 Then MIDI.ERROR = 2: Exit Sub
    'Make the filename an ASCIIZ string.
    Filename$ = Filename$ + Chr$(0)
    'Check if the MIDI loading code has already been loaded;
    'if not, do it now.
    If LoadCodeLoaded% = 0 Then
        asm1$ = asm1$ + Chr$(&H1E)
        asm1$ = asm1$ + Chr$(&H55)
        asm1$ = asm1$ + Chr$(&H89) + Chr$(&HE5)
        asm1$ = asm1$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H3D)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HE)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H17)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H10)
        asm1$ = asm1$ + Chr$(&H8E) + Chr$(&H1F)
        asm1$ = asm1$ + Chr$(&HCD) + Chr$(&H21)
        asm1$ = asm1$ + Chr$(&H89) + Chr$(&HC6)
        asm1$ = asm1$ + Chr$(&HB4) + Chr$(&H3F)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&HF)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H17)
        asm1$ = asm1$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)
        asm1$ = asm1$ + Chr$(&H8E) + Chr$(&H1F)
        asm1$ = asm1$ + Chr$(&H89) + Chr$(&HF3)
        asm1$ = asm1$ + Chr$(&HCD) + Chr$(&H21)
        asm1$ = asm1$ + Chr$(&HB4) + Chr$(&H3E)
        asm1$ = asm1$ + Chr$(&HCD) + Chr$(&H21)
        asm1$ = asm1$ + Chr$(&H5D)
        asm1$ = asm1$ + Chr$(&H1F)
        asm1$ = asm1$ + Chr$(&HCA) + Chr$(&HA) + Chr$(&H0)
        LoadCodeLoaded% = 1
    End If
    'Call the assembly language routine.
    Def Seg = VarSeg(asm1$)
    Call Absolute(VarSeg(Filename$), SAdd(Filename$), MIDISegment%, MIDIOffset%, &HFFFF, SAdd(asm1$))
    'Check to see if the MIDI playing code has previously been loaded.
    'If not, load it now.
    If PlayCodeLoaded% = 0 Then
        'Load the machine codes into a string.
        asm2$ = asm2$ + Chr$(&H55)
        asm2$ = asm2$ + Chr$(&H89) + Chr$(&HE5)
        asm2$ = asm2$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        asm2$ = asm2$ + Chr$(&H8B) + Chr$(&H17)
        asm2$ = asm2$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)
        asm2$ = asm2$ + Chr$(&H8B) + Chr$(&H7)
        asm2$ = asm2$ + Chr$(&HBB) + Chr$(&H4) + Chr$(&H0)
        asm2$ = asm2$ + Chr$(&HCD) + Chr$(SBMIDI.INTERRUPT)
        asm2$ = asm2$ + Chr$(&HBB) + Chr$(&H5) + Chr$(&H0)
        asm2$ = asm2$ + Chr$(&HCD) + Chr$(SBMIDI.INTERRUPT)
        asm2$ = asm2$ + Chr$(&H5D)
        asm2$ = asm2$ + Chr$(&HCA) + Chr$(&H4) + Chr$(&H0)
        'Indicate that the code has been loaded.
        PlayCodeLoaded% = 1
    End If
    'Call the machine language routine to play the music.
    Def Seg = VarSeg(asm2$)
    Call Absolute(MIDISegment%, MIDIOffset%, SAdd(asm2$))
    'Start the MIDI timer.
    MIDI.PLAYTIME = Timer
End Sub

Sub LoadLarge (Filename$) Static
    'See if an extension was supplied, and if not, add one.
    If InStr(Filename$, ".") = 0 Then Filename$ = Filename$ + ".MID"
    'The sound driver needs an ASCIIZ string (a string that ends with
    'character 0) for a file name.
    If Right$(Filename$, 1) <> Chr$(0) Then Filename$ = Filename$ + Chr$(0)
    'Initialize the MIDI driver and load the file in memory
    If CodeLoaded% = 0 Then
        asm$ = ""
        asm$ = asm$ + Chr$(&H55)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H7)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)
        asm$ = asm$ + Chr$(&HBB) + Chr$(&H0) + Chr$(&H5)
        asm$ = asm$ + Chr$(&HCD) + Chr$(SBSIM.INTERRUPT)
        asm$ = asm$ + Chr$(&H5D)
        asm$ = asm$ + Chr$(&HCB)
        CodeLoaded% = 1
    End If
    Def Seg = VarSeg(asm$)
    Offset% = SAdd(asm$)
    Call Absolute(SAdd(Filename$), VarSeg(Filename$), Offset%)
    MIDI.LOADED = 1
End Sub

'LoadMIDI - loads a MIDI file into memory
Sub LoadMIDI (Filename$, MIDISegment%, MIDIOffset%) Static
    'See if an extension was supplied, and if not, add one.
    If InStr(Filename$, ".") = 0 Then Filename$ = Filename$ + ".MID"
    'Open the file
    FF% = FreeFile
    Open Filename$ For Binary As #FF%
    FileLen& = LOF(FF%)
    Close #FF%
    'If the file is empty, delete it and exit now.
    If FileLen& = 0 Then Kill Filename$: MIDI.ERROR = 1: Exit Sub
    'If the file is too large, exit now.
    If FileLen& > 65536 Then MIDI.ERROR = 2: Exit Sub
    'Make the filename an ASCIIZ string.
    Filename$ = Filename$ + Chr$(0)
    'Check if the assembly language code has already been loaded;
    'if not, do it now.
    If CodeLoaded% = 0 Then
        asm$ = asm$ + Chr$(&H1E)
        asm$ = asm$ + Chr$(&H55)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)
        asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H3D)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HE)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H10)
        asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)
        asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HC6)
        asm$ = asm$ + Chr$(&HB4) + Chr$(&H3F)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&HF)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)
        asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HF3)
        asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)
        asm$ = asm$ + Chr$(&HB4) + Chr$(&H3E)
        asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)
        asm$ = asm$ + Chr$(&H5D)
        asm$ = asm$ + Chr$(&H1F)
        asm$ = asm$ + Chr$(&HCA) + Chr$(&HA) + Chr$(&H0)
        CodeLoaded% = 1
    End If
    'Call the assembly language routine.
    Def Seg = VarSeg(asm$)
    Call Absolute(VarSeg(Filename$), SAdd(Filename$), MIDISegment%, MIDIOffset%, &HFFFF, SAdd(asm$))
End Sub

Function MIDIError$
    Select Case MIDI.ERROR
        Case 0: MIDIError$ = "NO ERROR"
        Case 1: MIDIError$ = "FILE CONTAINS NO DATA"
        Case 2: MIDIError$ = "FILE IS TOO LARGE"
        Case 3: MIDIError$ = "NO MIDI FILE PLAYING"
        Case Else: MIDIError$ = "UNKNOWN ERROR"
    End Select
End Function

'PauseMIDI - Pauses a MIDI file that is currently playing
Sub PauseMIDI
    'If no MIDI file is playing, exit now
    If MIDI.PLAYTIME = 0 Then Exit Sub
    'Pause the music.
    If CodeLoaded% = 0 Then
        asm$ = ""
        asm$ = asm$ + Chr$(&HB8) + Chr$(&H1) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HBA) + Chr$(&H1) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HBB) + Chr$(&H3) + Chr$(&H5)
        asm$ = asm$ + Chr$(&HCD) + Chr$(SBSIM.INTERRUPT)
        asm$ = asm$ + Chr$(&HCB)
        CodeLoaded% = 1
    End If
    Def Seg = VarSeg(asm$)
    Offset% = SAdd(asm$)
    Call Absolute(Offset%)
    'Save the number of seconds the MIDI file has been playing.
    PAUSED = TimeMIDI!
    'If it hasn't been playing long enough for TimeMIDI! to return
    'a value greater than 0, change PAUSED to a tiny positive value.
    If PAUSED = 0! Then PAUSED = .00001
    'Indicate that the file has stopped playing.
    MIDI.PLAYTIME = 0
End Sub

Sub PlayLarge Static
    'If no MIDI file is loaded, exit now
    If MIDI.LOADED = 0 Then Exit Sub
    'Start the music!!
    If CodeLoaded% = 0 Then
        asm$ = ""
        asm$ = asm$ + Chr$(&HB8) + Chr$(&H1) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HBA) + Chr$(&H1) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HBB) + Chr$(&H1) + Chr$(&H5)
        asm$ = asm$ + Chr$(&HCD) + Chr$(SBSIM.INTERRUPT)
        asm$ = asm$ + Chr$(&HCB)
        CodeLoaded% = 1
    End If
    Def Seg = VarSeg(asm$)
    Offset% = SAdd(asm$)
    Call Absolute(Offset%)
    MIDI.PLAYTIME = Timer
End Sub

'PlayMIDI - Begins playing a MIDI file in the background.
Sub PlayMIDI (MIDISegment%, MIDIOffset%) Static
    'Check to see if the MIDI playing code has previously been loaded.
    'If not, load it now.
    If CodeLoaded% = 0 Then
        'Load the machine codes into a string.
        asm$ = asm$ + Chr$(&H55)
        asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)
        asm$ = asm$ + Chr$(&H8B) + Chr$(&H7)
        asm$ = asm$ + Chr$(&HBB) + Chr$(&H4) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HCD) + Chr$(&H80)
        asm$ = asm$ + Chr$(&HBB) + Chr$(&H5) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HCD) + Chr$(&H80)
        asm$ = asm$ + Chr$(&H5D)
        asm$ = asm$ + Chr$(&HCA) + Chr$(&H4) + Chr$(&H0)
        'Indicate that the code has been loaded.
        CodeLoaded% = 1
    End If
    'Call the machine language routine to play the music.
    Def Seg = VarSeg(asm$)
    Offset% = SAdd(asm$)
    Call Absolute(MIDISegment%, MIDIOffset%, Offset%)
    'Start the MIDI timer.
    MIDI.PLAYTIME = Timer
End Sub

'ResumeMIDI - Starts playing a MIDI file after it has been paused
Sub ResumeMIDI
    'If no MIDI file is paused, exit now
    If PAUSED = 0! Then Exit Sub
    'Resume playing.
    If CodeLoaded% = 0 Then
        asm$ = ""
        asm$ = asm$ + Chr$(&HB8) + Chr$(&H1) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HBA) + Chr$(&H1) + Chr$(&H0)
        asm$ = asm$ + Chr$(&HBB) + Chr$(&H4) + Chr$(&H5)
        asm$ = asm$ + Chr$(&HCD) + Chr$(SBSIM.INTERRUPT)
        asm$ = asm$ + Chr$(&HCB)
        CodeLoaded% = 1
    End If
    Def Seg = VarSeg(asm$)
    Offset% = SAdd(asm$)
    Call Absolute(Offset%)
    MIDI.PLAYTIME = Timer - PAUSED
    PAUSED = 0!
End Sub

'StopMIDI - Stops playing MIDI file
Sub StopMIDI
    'Stop the music!!
    asm$ = asm$ + Chr$(&HBB) + Chr$(&H4) + Chr$(&H0)
    asm$ = asm$ + Chr$(&HCD) + Chr$(SBMIDI.INTERRUPT)
    asm$ = asm$ + Chr$(&HCB)
    'These next commented lines are for using the converted code.
    Def Seg = VarSeg(asm$)
    Offset% = SAdd(asm$)
    Call Absolute(Offset%)
    'No MIDI file is playing, so reset the timer
    MIDI.PLAYTIME = 0
End Sub

Function TimeMIDI!
    'If a MIDI file is paused, lock the current playing time
    If PAUSED > 0! Then
        TimeMIDI! = PAUSED
        'If a MIDI file is playing, carry out the timing routine
    ElseIf MIDI.PLAYTIME Then
        'Get the current time
        CurrentTime! = Timer
        'If midnight has come since the MIDI file started playing, change
        'CurrentTime! accordingly
        If CurrentTime! - MIDI.PLAYTIME < 0 Then
            CurrentTime! = 86400 + CurrentTime!
        End If
        'Get the final result
        TimeMIDI! = CurrentTime! - MIDI.PLAYTIME
    Else
        MIDI.ERROR = 3
    End If
End Function

you can got it from here or if you prefer from https://github.com/creationix/basic-game.../QMIDI.BAS

If you copy and paste the code into QB64 IDE you get this error tha I don't know how to solve to try to run the code.
Any suggestions?


Attached Files Image(s)
   
Reply


Messages In This Thread
RE: Any C programmers wanna help convert code to convert between MIDI + CSV? - by TempodiBasic - 09-03-2022, 02:20 PM



Users browsing this thread: 46 Guest(s)