Midi format music distortion

General discussion about LÖVE, Lua, game development, puns, and unicorns.
votrin
Prole
Posts: 2
Joined: Sat May 02, 2020 10:39 am

Midi format music distortion

Post by votrin »

Sorry to bother, I am new here and had problems playing music in Love2d.
When I use the 11.3 version of Love2d to play .mid files, there is severe distortion. In order to solve this problem, I changed the instruments many times, but there seems to be no difference between the instruments-all instruments sound the same, or they are the same at all.
The code I use is as follows:

Code: Select all

function love.load()
    musbg = love.audio.newSource("musbg.mid", "stream")
    musbg : play()
end
Wikipedia says Love has supported .mid files since version 0.9.1, and I do n’t understand what went wrong. I checked the forum, but found no solution (except for using other formats of music, but that would make the .love file very large, since I've got a lot of music to play in game, each at a size of 1~10 mb; or maybe it's because I didn't look carefully and skipped the blog containing resolution).
Anyway, could anyone who knows how to solve this problem help me with it?
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Midi format music distortion

Post by zorg »

Hi and welcome to the forums!

The issue is that while löve does indeed support parsing midi formats, it does so through the included libmodplug library, which expects something called Timidity to exists. Without it, it will play all notes as the same default instrument, which seems to be some simple waveform... beeps basically.

Multiple issues exist with this though, including (to my knowledge anyway) you not being able to define where löve should look for Timidity, and setting up Timidity itself is not an easy feat.

If you want small-ish files, you can use tracker modules, also supported; if you're on Windows, you can get OpenMPT for free, which can load in your midi files, add in the instruments you used, then you can simply export them in one of the supported formats both it can export and libmodplug can load (strictly: MOD, S3M, XM, IT)

Alternatively, wait a few eternities until someone writes both a midi parser library and a playback library that could use either soundfonts or just provided audio samples to be used with Löve... :P
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
votrin
Prole
Posts: 2
Joined: Sat May 02, 2020 10:39 am

Re: Midi format music distortion

Post by votrin »

Thanks!
eri0o
Prole
Posts: 7
Joined: Fri Feb 09, 2018 9:51 pm

Re: Midi format music distortion

Post by eri0o »

Hey, has someone ever kept investigation on this?

I am trying to find where in the code is this bail to use beeps in place of timidity to figure a way at least making a little prettier tunes by code.

Also some minor silence in each X seconds.

I see libmodplug code is kept updated here: https://github.com/sezero/libmodplug
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Midi format music distortion

Post by zorg »

I'm assuming that libmodplug itself handles the "no timidity? use beeps" thing; it is probably also responsible for whatever timing issues happen; MIDI and tracker formats are not 1:1 compatible, so strange things can happen after it converts the data.

Might be a neat idea to look at that fork, though i haven't seen a place where they mention what exactly they fixed/modified/added/(potentially )removed since the last commit in konstanty's repo.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Pajo
Prole
Posts: 11
Joined: Tue Dec 22, 2020 4:19 pm
Contact:

Re: Midi format music distortion

Post by Pajo »

Here's how to make Löve play MIDIs, on GNU/Linux and Android. Still not completely solved for Windows, could use some help here!
This solution works only when the game is unpacked. Some additional steps are needed for packed .love files to work. (Described in the next post.)

1) Prepare instruments by converting a soundfont to GUS patches

It seems there is no way to make use of system's native way of playing MIDI files, so you should include the instruments yourself. As oposed to Timidity++, the Timidity included in libmodplug uses instruments in GUS patch format only. As these are hard to find, you can use unsf utility to convert sf2 to them.

You can find some soundfonts here. (The ideal soundfont should be small, should include all instruments your song uses, and should have no copyright issues.)

After executing unsf somefile.sf2, you will end up with somefile.cfg and several subfolders with instruments in PAT format.

2) Create directory structure

In the folder of your love game, create folder instruments - it must be called like that. Move all subfolders with instruments (and any PATs not in subfolder) there.

Move somefile.cfg to the folder above instruments (your love game folder in this case) and rename it to timidity.cfg (also important).

3) Create minimal main.lua to play the song and set environment variable

Code: Select all

local ffi = require('ffi')
ffi.cdef[[
int setenv(const char*, const char*, int); // Unixes
int _putenv_s(const char*, const char*);   // Windows
]]

function love.load()
	local path = love.filesystem.getRealDirectory('timidity.cfg')
	if love.system.getOS() == 'Windows' then
		ffi.C._putenv_s('MMPAT_PATH_TO_CFG', path)
	else
		ffi.C.setenv('MMPAT_PATH_TO_CFG', path, 1)
	end
	love.audio.newSource('ame002.mid', 'static'):play()
end
This should set environment variable MMPAT_PATH_TO_CFG pointing to the folder with timidity.cfg (in this example, your love game folder).

Don't forget to place somesong.mid in the same folder...
... and you should hear the song correctly - if the game is unpacked!

The working proof-of-concept standalone .love file is in the next post.


EDIT: Figured out how to set an environment variable using FFI
EDIT: Updated info for standalone files
EDIT: Updated info for Windows
Last edited by Pajo on Sat Jan 23, 2021 10:26 am, edited 3 times in total.
User avatar
Pajo
Prole
Posts: 11
Joined: Tue Dec 22, 2020 4:19 pm
Contact:

Re: Midi format music distortion

Post by Pajo »

To make patches available to libmodplug, even after compressing everything to a single love file, you can copy all the patches and timidity.cfg to the save folder.

So here's a proof of concept file that plays MIDI.

I've considered other solutions. Timidity++ is able to read zipped files, but libmodplug seems only to care about instruments folder (I may be wrong). I've also tried mounting zips to save folder, but libmodplug didn't see them.

The advantage of MIDI files is that instruments can be shared between songs. On the other hand, with PAT files, the samples can't be shared between instruments, so there is an increase in size, compared to SF2.

EDIT: Should work on Windows now
EDIT: Doesn't work on Windows yet!
Attachments
midi-example-v2.love
(4.33 MiB) Downloaded 309 times
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Midi format music distortion

Post by milon »

Is there a real use case for MIDI these days? Why not use mp3 or ogg etc? (I promise I'm not trying to be a jerk - I just am surprised to see this question in 2021.)
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Midi format music distortion

Post by zorg »

milon wrote: Wed Feb 17, 2021 5:49 pm Is there a real use case for MIDI these days? Why not use mp3 or ogg etc? (I promise I'm not trying to be a jerk - I just am surprised to see this question in 2021.)
Despite what you might equate to "MIDI", like those old html1 sites with background music being played back with shit microsoft "MIDI instruments", most composing software still use MIDI for their notation data (or at least allow exporting that in that format), and most synths (besides the ones that work with voltage levels) and other hardware still use MIDI to communicate with each other and computers... they're even working on a new version of the standard right now.

Because midi is a notation format, not a sound format; You can't store notation data in mp3/ogg/flac/wav/aiff/whatever.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Midi format music distortion

Post by milon »

Cool, thanks for clearing that up for me. :)
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
Post Reply

Who is online

Users browsing this forum: No registered users and 52 guests