Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Exploring QB64-PE default soundfont patches
#1
I was curious as to what all the default MIDI soundfont patches sounded like, and I also wanted to put together a way of grabbing those sounds somehow in code to use, so this function is the result.  It just grabs 1 midi note.  I don't think I'm calculating the ticks and duration right, but at least I can hear the sound patches available.  There's some real neat ones.  I'm probably not making a valid MIDI data file here, but at least it loads/plays.

- Dav

NOTE:  Get the lastest version, now called MidiNotes, HERE

Code: (Select All)
'Exploring QB64-PE default soundfont patches.
'Makes MIDI a note and play's it from memory.
'Dav, SEP/2024

'Cycles throuh all default sound patchs 127-0

$Unstable:Midi
$MidiSoundFont: Default

'cycle through all sounds, press any key to quit.

For patch = 127 To 0 Step -1
    Print "Patch#"; patch
    note$ = MidiNote$(60, patch, 60, 1)
    midisound& = _SndOpen(note$, "memory")
    _SndPlay midisound&
    _Delay 1
    _SndStop midisound&
    _SndClose midisound&
    If InKey$ <> "" Then End
Next

Function MidiNote$ (tempo&, patch, note, duration&)

    TicksPerQuarterNote = 96

    'Make MIDI Header Chunk (MThd)
    MThd$ = Chr$(77) + Chr$(84) + Chr$(104) + Chr$(100) ' "MThd"
    'Make Header size
    MThd$ = MThd$ + Chr$(0) + Chr$(0) + Chr$(0) + Chr$(6)
    'Make format type (1 = single track)
    MThd$ = MThd$ + Chr$(0) + Chr$(1)
    'Make number of tracks (1)
    MThd$ = MThd$ + Chr$(0) + Chr$(1)
    'Make division = 96 (ticks per quarter note)
    MThd$ = MThd$ + Chr$(0) + Chr$(96)

    'calculate microseconds per beat from tempo& in BPM
    MicroSecsPerBeat& = 60000000 \ tempo& '(converts BPM to microseconds per beat)

    'Get msb/mb/lsb from MicroSecsPerBeat& for saving tempo
    '(midi requires 3 bytes for this info)
    msb = (MicroSecsPerBeat& \ 65536) And 255 'most Significant Byte
    middle = (MicroSecsPerBeat& \ 256) And 255 'middle Byte
    lsb = MicroSecsPerBeat& And 255 'least Significant Byte

    'Make the tempo data + the 3 bytes
    TrackData$ = TrackData$ + Chr$(0) + Chr$(255) + Chr$(81) + Chr$(3) + Chr$(msb) + Chr$(middle) + Chr$(lsb)

    'Set Program number (patch) to use
    TrackData$ = TrackData$ + Chr$(0) + Chr$(192) + Chr$(patch)

    'Set Note On: play note value (with velocity 127)
    TrackData$ = TrackData$ + Chr$(0) + Chr$(144) + Chr$(note) + Chr$(127)

    'convert duration& in beats to ticks& (how long to play the note)
    ticks& = duration& * TicksPerQuarterNote

    'Set Note Off: Stop playing note after specified duration& in ticks&
    TrackData$ = TrackData$ + Chr$(ticks&) + Chr$(128) + Chr$(note) + Chr$(64)

    'Make track end event
    TrackData$ = TrackData$ + Chr$(0) + Chr$(255) + Chr$(47) + Chr$(0)

    'Make the MTrk header
    MTrk$ = Chr$(77) + Chr$(84) + Chr$(114) + Chr$(107) ' MTrk

    'Make the track data length (4 bytes)
    TrackLen& = Len(TrackData$)
    TrackLength$ = Chr$((TrackLen& \ 16777216) And 255) + Chr$((TrackLen& \ 65536) And 255) + Chr$((TrackLen& \ 256) And 255) + Chr$(TrackLen& And 255)

    'Put it all together
    MidiNote$ = MThd$ + MTrk$ + TrackLength$ + TrackData$

End Function

Find my programs here in Dav's QB64 Corner
Reply


Messages In This Thread
Exploring QB64-PE default soundfont patches - by Dav - 09-10-2024, 02:59 AM



Users browsing this thread: 10 Guest(s)