Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Extended KotD #21: _MIDISOUNDBANK
#1
_MIDISOUNDBANK is a QB64-PE v3.14.0 feature. However, before we dive straight into it, let's take a look at a bit of history.

What is MIDI?

MIDI (Musical Instrument Digital Interface) is a communication protocol that enables the control and synchronization of electronic musical instruments, software, and other devices. Unlike audio data, MIDI messages are lightweight, making them ideal for real-time performance and control. MIDI was standardized in 1983 by the MIDI Manufacturers Association (MMA), and its continued use today highlights its enduring versatility.

What is a MIDI File?

A MIDI file is a digital file format that stores MIDI data. Unlike audio files, which contain actual sound recordings, a MIDI file contains instructions for generating sound. These instructions include information such as note pitch, duration, velocity, and timing, as well as control changes and other parameters. MIDI files are highly compact because they do not store actual audio, making them ideal for efficient storage and manipulation of musical compositions. MIDI files can be played back by any MIDI-compatible device, which interprets the data and generates the corresponding sounds.

What is a MIDI soundbank?

A MIDI soundbank is a collection of audio samples and settings that a synthesizer uses to generate sounds when playing a MIDI file. It defines how the notes and instructions in the MIDI file will sound, allowing for different instrument tones and qualities.

QB64 and MIDI

The last SDL version of QB64 (v0.954) was the version that had native MIDI playback support. MIDI and several other audio formats were dropped in the OpenGL version of QB64. QB64-PE v3.2.0 reintroduced support for MIDI playback, although it was initially hidden behind $UNSTABLE:MIDI. QB64-PE v3.14.0 moved MIDI playback support out of $UNSTABLE:MIDI and made it a first-class feature. $UNSTABLE:MIDI and $MIDISOUNDFONT were deprecated, and the new _MIDISOUNDBANK statement was added.

_MIDISOUNDBANK Syntax

Code: (Select All)
_MIDISOUNDBANK: fileName$[, capabilities$]

fileName$ is the file name of the soundbank or a buffer containing the soundbank data.
capabilities$ (optional) can be two flags if specified.
  • "memory" - indicating that the fileName$ is a buffer and not a file name and one of the following.
  • "ad": Global Timbre Library format for Audio Interface Library.
  • "op2": DMX OPL-2 format.
  • "opl": Global Timbre Library format for Audio Interface Library.
  • "sf2": Creative's SoundFont 2.0 format.
  • "sf3": MuseScore's Ogg compressed Creative SoundFont 2.0 format.
  • "sfo": Bernhard Schelling's Ogg compressed Creative SoundFont 2.0 format.
  • "tmb": Apogee Sound System timbre format.
  • "wopl": Vitaly Novichkov's OPL3BankEditor format.

Example: Using an embedded soundbank
Code: (Select All)
$EMBED:'./tiny.sf2','mysf2'

_MIDISOUNDBANK _EMBEDDED$("mysf2"), "memory, sf2"

handle = _SNDOPEN("canyon.xmi")
_SNDPLAY handle

QB64-PE MIDI Player Engine

The QB64-PE MIDI player engine heavily borrows from the foobar2000 MIDI Player plugin (https://www.foobar2000.org/components/view/foo_midi). Unlike the foobar2000 plugin, however, the QB64-PE implementation is cross-platform, except for VSTi support (more on this later). The player internally uses various backends to play MIDI files. All backends need a soundbank. However, the Opal+yfmidi backend has a tiny soundbank embedded by default that is used to play MIDI files if no other soundbank is loaded.

Synth Type Setup Difficulty Platform Quality
Opal+yfmidi Frequency modulation None Can I play, Daddy? All Retro
Primesynth/TinySoundFontSample-based Less Don't hurt me. All Awesome
VSTi Implementation defined More Bring 'em on! Windows Hell yeah!

Playing a MIDI file without any soundbank loaded will default the MIDI engine to use the Opal+yfmidi backend and the default embedded soundbank. Note that the FM Synthesis used is similar to that of a real Yamaha OPL3. However, unlike hardware OPL3 that supports only 18 channels, the Opal+yfmidi backend supports 108 (18 x 6) channels. This allows it to produce exceptional quality retro-sounding music. External AD, OPL2, OPL, TMB, and WOPL FM bank formats are also supported by this backend.

Example: Playing a MIDI files using FM synthesis
Code: (Select All)
handle = _SNDOPEN("groove.xmi")

_SNDPLAY handle

The Primesynth/TinySoundFont backends support sample-based synthesis using SoundFonts (SF2). As such, they can reproduce music using real-life instrument sounds at very high quality. The TinySoundFont backend supports compressed SoundFonts like SF3 & SFO. Note that compression is lossy (OGG), and hence some degradation in quality can be perceived. QB64-PE does not contain any SoundFonts, so the user must specify a SoundFont using _MIDISOUNDBANK to use this backend.

Example: Playing a MIDI file using a SoundFont
Code: (Select All)
_MIDISOUNDBANK "4mgmgsmt.sf2"

handle = _SNDOPEN("onestop.mid")
_SNDPLAY handle

The VSTi backend is Windows-only because it uses a VSTi DLL. QB64-PE itself does not include any code from Steinberg Media Technologies. Therefore, it uses a VST Host module to communicate with the VSTi DLL. Yours truly has taken the effort to adapt the foobar2000 MIDI VST Host for QB64-PE, and the same is available at https://github.com/a740g/vsthost. One should compile the project using Visual Studio 2022 to get the vsthost32.exe and vsthost64.exe files. My sole motivation to add VSTi support to QB64-PE was to get MIDI playing using the Yamaha S-YXG50 VSTi found at https://veg.by/en/projects/syxg50/. A VSTi can be specified using _MIDISOUNDBANK. However, QB64-PE expects the VST Host to be in the same directory as the VSTi DLL. Otherwise, the VSTi will not be loaded, and playback will fail.

Example: Playing a MIDI file using a VSTi
Code: (Select All)
$IF WINDOWS THEN
_MIDISOUNDBANK "syxg50.dll" ' load VSTi on Windows
$ELSE
_MIDISOUNDBANK "4mgmgsmt.sf2" ' fallback to a SoundFont on other platforms
$ENDIF

handle = _SNDOPEN("onestop.mid")
_SNDPLAY handle

The example player (MIDIPlayer64) below contains code that shows how to load various soundbanks, use the various backends, and several other features. Feel free to experiment and use the code in your own projects.

[Image: Screenshot-2024-08-25-194929.png] [Image: Screenshot-2024-08-25-195032.png]

Things to try
  • Play monkey.mid and Wolfenstein 3D*.mid from the midis directory using FM Synthesis.
  • Play THE_RAIN.mid, ECHOES.mid, striving.mid, and DOOM MIDIs in the midis directory using soundbanks/gzdoom.sf2.
  • Play COLDWAVE.mid, MHBB.mid, and TK_EATS.mid in the midis directory using soundbanks/wingroove.sf2.
  • On Windows, play bi2_polkovnik.mid, Cop Out by Sam Sketty YME '96.mid, Fool's World (XG).mid, The Major Seven (XG).mid, and Technocrat XG Sam Cardon.mid using soundbanks/syxg50.dll.

Cheers!

Questions?


Attached Files
.zip   MIDIPlayer64.zip (Size: 10.89 MB / Downloads: 32)
Reply


Messages In This Thread
Extended KotD #21: _MIDISOUNDBANK - by a740g - 08-25-2024, 04:07 PM
RE: Extended KotD #20: _MIDISOUNDBANK - by Dav - 08-25-2024, 04:22 PM
RE: Extended KotD #21: _MIDISOUNDBANK - by a740g - 08-25-2024, 08:40 PM
RE: Extended KotD #21: _MIDISOUNDBANK - by Pete - 08-28-2024, 08:09 PM
RE: Extended KotD #21: _MIDISOUNDBANK - by a740g - 08-29-2024, 03:30 AM
RE: Extended KotD #21: _MIDISOUNDBANK - by a740g - 08-30-2024, 03:31 PM



Users browsing this thread: 1 Guest(s)