QB64 Phoenix Edition
How to play a Midi file - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Utilities (https://qb64phoenix.com/forum/forumdisplay.php?fid=8)
+---- Thread: How to play a Midi file (/showthread.php?tid=2647)



How to play a Midi file - eoredson - 05-02-2024

This a short snippet on how to play a Midi file:

Code: (Select All)
Dim SoundHandle As Long
$Unstable:Midi
$MidiSoundFont:Default
Print "Enter midi file";
Input Midi$
Midi$ = UCase$(Midi$)
If Right$(Midi$, 4) = ".MID" Then
   If _FileExists(Midi$) Then
      Print "Playing.."
      Print "  Enter <space>=pause/+plus 10/-minus 10."
      Print "  Press <escape> to exit."
      '_SndPlayFile Midi$
      SoundHandle = _SndOpen(Midi$)
      If SoundHandle Then
         _SndPlay SoundHandle
         Do
            _Limit 50
            x$ = InKey$
            If Len(x$) Then
               If x$ = Chr$(27) Then Exit Do
               If x$ = "+" Then
                  z! = _SndGetPos(SoundHandle)
                  z! = z! + 10!
                  _SndSetPos SoundHandle, z!
               End If
               If x$ = "-" Then
                  z! = _SndGetPos(SoundHandle)
                  z! = z! - 10!
                  If z! < 0! Then z! = 0!
                  _SndSetPos SoundHandle, z!
               End If
               If x$ = " " Then
                  If _SndPaused(SoundHandle) Then
                     _SndPlay SoundHandle
                  Else
                     _SndPause (SoundHandle)
                  End If
               End If
            End If
         Loop
      End If
   End If
End If
End
note the included $metacommands..

attached is midiplay.zip which contains the midi player and midi.zip with some .mid files.


RE: How to play a Midi file - eoredson - 05-03-2024

Additional notes on Midi player:

The
Code: (Select All)
$MidiSoundFont:Default
is where default can be changed to an .sf2 file or a soundfont file which can be found on several soundfont library websites.

for example: $MidiSoundFont:"soundfont2.sf2"

Erik.


RE: How to play a Midi file - Steffan-68 - 05-03-2024

Instead of  " Input Midi$ "

That would be even nicer

Midi$ = _OpenFileDialog$("MID Datei Öffnen", "", " *.mid", "Musik Datei", 0)


RE: How to play a Midi file - eoredson - 05-03-2024

(05-03-2024, 03:24 PM)Steffan-68 Wrote: Instead of  " Input Midi$ "

That would be even nicer

Midi$ = _OpenFileDialog$("MID Datei Öffnen", "", " *.mid", "Musik Datei", 0)
I don't see any reason why not..

Code: (Select All)
Rem Midiplay.bas is the .mid player function for QB64 PD 2024.
Rem   v1.0a first release 05/02/2024
Rem   v1.1a new release 05/05/2024
Rem   v2.0a new release 05/06/2024

' declare variables.
Dim SoundHandle As Long
Dim SoundVolume As Single

' enable midi support.
$Unstable:Midi
$MidiSoundFont:Default
'$MidiSoundFont:"silly.sf2"

' setup screen.
_Title "Midiplay"
_ScreenMove _Middle

' reset statusbar v2.0a
Screen 0
Width 80, 25
Cls
Locate 25, 1
Color 15, 1
Print Space$(80);
Locate 25, 1
Print "Midiplay "; Date$; " "; Time$;
Locate 24, 1
Color , 0

' init volume
SoundVolume = 1!

' start midi interface.
Color 15
Print "Welcome to Midi player v2.0a."
Color 14
StartLoop:

Rem Call dialog v1.1a
Midi$ = _OpenFileDialog$("Open File", "", "*.mid", "Midi files", 0)

If Midi$ = "" Then Color 7: End
Midi$ = UCase$(Midi$)
If Right$(Midi$, 4) <> ".MID" Then
   Print "File not found."
   GoTo StartLoop
End If
If _FileExists(Midi$) = 0 Then
   Print "File not found."
   GoTo StartLoop
End If
If Right$(Midi$, 4) = ".MID" Then
   If _FileExists(Midi$) Then
      Color 15
      Print "  Enter <space>=pause/+plus 10/-minus 10/?=length."
      Print "  Press <escape> to exit, <enter> to restart."
      Print "  <up> increase volume by .1 seconds."
      Print "  <down> decrease volume by .1 seconds."
      Print "  <right> Move playback plus 10 seconds."
      Print "  <left> Move playback minus 10 seconds."
      Print "  <ctrl-right> Moves position plus 30 seconds."
      Print "  <ctrl-left> Moves position minus 30 seconds."
      Color 14

      Rem Added v1.1a
      If _MessageBox("MidiPlay", "Load: " + Midi$, "yesno", "question") = 0 Then Color 7: End

      Print "Loading.."
      SoundHandle = _SndOpen(Midi$)
      If SoundHandle = 0 Then
         Print "File not found."
         GoTo StartLoop
      End If
      If SoundHandle Then
         Print "Playing.."
         _SndPlay SoundHandle

         ' reset statusbar v2.0a
         Locate 25, 1
         Color 15, 1
         Print Space$(80);
         Locate 25, 1
         S$ = "Midiplay " + Date$ + " " + Time$ + " - " + Midi$
         S$ = Left$(S$, 80)
         Print S$;
         Locate 24, 1
         Color 14, 0
         _Title "Midiplay " + Midi$

         ' reset to full volume in v2.0a
         SoundVolume = 1!
         _SndVol SoundHandle, SoundVolume

         ' soundplay loop
         Do
            _Limit 50
            x$ = InKey$
            If Len(x$) Then
               ' adjust volume control
               If x$ = Chr$(0) + Chr$(72) Then ' up
                  SoundVolume = SoundVolume + .1!
                  If SoundVolume > 1! Then SoundVolume = 1!
                  _SndVol SoundHandle, SoundVolume
                  S$ = Str$(SoundVolume)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 1)
                  End If
                  Print "Volume is"; S$; " of 1."
               End If
               If x$ = Chr$(0) + Chr$(80) Then ' down
                  SoundVolume = SoundVolume - .1!
                  If SoundVolume < 0! Then SoundVolume = 0!
                  _SndVol SoundHandle, SoundVolume
                  S$ = Str$(SoundVolume)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 1)
                  End If
                  Print "Volume is"; S$; " of 1."
               End If

               If x$ = Chr$(27) Then

                  Rem Added v1.1a
                  _MessageBox "MidiPlay", "Press <enter> to quit: ", "info"

                  _SndStop SoundHandle
                  _SndClose SoundHandle
                  Exit Do
               End If
               If x$ = Chr$(13) Then
                  _SndStop SoundHandle
                  _SndClose SoundHandle
                  GoTo StartLoop
               End If
               If x$ = "?" Then
                  S& = _SndLen(SoundHandle)
                  S$ = Str$(S&)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 2)
                  End If
                  Print "Handle"; SoundHandle; "length is"; S$; " seconds."
                  S$ = Str$(SoundVolume)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 1)
                  End If
                  Print "Position is"; _SndGetPos(SoundHandle); "seconds. Volume is"; S$; " of 1."
               End If
               If x$ = "+" Or x$ = Chr$(0) + Chr$(77) Then ' right
                  z! = _SndGetPos(SoundHandle)
                  z! = z! + 10!
                  _SndSetPos SoundHandle, z!
                  S& = _SndGetPos(SoundHandle)
                  S$ = Str$(S&)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 2)
                  End If
                  Print "Position is"; S$; " seconds."
               End If
               If x$ = "-" Or x$ = Chr$(0) + Chr$(75) Then ' left
                  z! = _SndGetPos(SoundHandle)
                  z! = z! - 10!
                  If z! < 0! Then z! = 0!
                  _SndSetPos SoundHandle, z!
                  S& = _SndGetPos(SoundHandle)
                  S$ = Str$(S&)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 2)
                  End If
                  Print "Position is"; S$; " seconds."
               End If
               If x$ = Chr$(0) + Chr$(116) Then ' ctrl-right
                  z! = _SndGetPos(SoundHandle)
                  z! = z! + 30!
                  _SndSetPos SoundHandle, z!
                  S& = _SndGetPos(SoundHandle)
                  S$ = Str$(S&)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 2)
                  End If
                  Print "Position is"; S$; " seconds."
               End If
               If x$ = Chr$(0) + Chr$(115) Then ' ctrl-left
                  z! = _SndGetPos(SoundHandle)
                  z! = z! - 30!
                  If z! < 0! Then z! = 0!
                  _SndSetPos SoundHandle, z!
                  S& = _SndGetPos(SoundHandle)
                  S$ = Str$(S&)
                  If InStr(S$, ".") Then
                     S$ = Left$(S$, InStr(S$, ".") + 2)
                  End If
                  Print "Position is"; S$; " seconds."
               End If
               If x$ = " " Then
                  If _SndPaused(SoundHandle) Then
                     Print "Resume play."
                     _SndPlay SoundHandle
                  Else
                     Print "Pause play."
                     _SndPause (SoundHandle)
                  End If
               End If
            End If
         Loop
      End If
   End If
End If
Color 7
End

Version history:

Code: (Select All)
Midiplay.bas is the .mid player function for QB64 PD 2024.

Version history:
  v1.0a:
    First release 05/02/2024
  v1.1a:
    New release 05/05/2024
      Adds OpenFileDialog box call.
      Adds <up>/<down>
        Moves volume up by .1 seconds.
        Moves volume down by .1 seconds.
      Adds <right>/<left>
        Moves position plus 10 seconds.
        Moves position minus 10 seconds.
      Adds <ctrl-right>/<ctrl-left>
        Moves position plus 30 seconds.
        Moves position minus 30 seconds.
  v2.0a:
    New release 05/06/2024
      Sets volume to 1 when starting new soundfile.
      Adds Status line with program/date/time/soundfile.
      Adds Title bar with program/soundfile.
      Adds realtime seconds soundfile played on statusline.

-end-

Find attached v2.0a of the Midi Player..

Now 294 lines.

Also includes some sample .sf2 files.


RE: How to play a Midi file - eoredson - 05-04-2024

Just to play around a bit here is some code:

Code: (Select All)
$Unstable:Midi
$MidiSoundFont:Default
_SndPlayFile (_OpenFileDialog$("Open File", "", "*.mid", "Midi files", 0)): Color 15: Print "Press key:": While InKey$ = "": Wend: System

unfortunately you can't concatenate the metacommands into one line.

but you can specify a function call as a parameter to a function call..