Log In  

Cart #37156 | 2017-02-04 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Hello there, I've been working on this piece of software called midi2pico
It does what it implies, converts midis into music for pico-8

I've recently just added proper drum support, so in celebration of that I want to release this little demo.

Come checkout midi2pico at github: https://github.com/gamax92/midi2pico

It's a very configurable midi conversion program, with the ability to mute channels, change volumes, and to shift pitches to fit into pico-8's audio range. midi2pico attempts to arrange midi data in a logical way, storing the beginning of a song at sfx 0 and the end of the song near the end of available sfx.

MIDI Format 0, pitch bends, sfx deduplication, silence removal, and now drums are supported. A midi instrument and drum to pico-8 translation table is supported, though not very populated and most instruments use a default conversion. Look for 'Instrument to PICO-8 Map' and 'Drums to PICO-8 Map' inside midi2pico.lua

A separate utility is also included for debugging midi files called midi2note. midi2note shows the end result after midi2opus, opus2score, and score2note conversions that midi2pico also uses.

Installation is easy, all you need is lua 5.2 and the MIDI library, which is available in luarocks as 'luarocks install midi' or download the MIDI library directly here and place it along side midi2pico.lua

lua 5.1 is also supported, but you will need a bit32 backport which is also available in luarocks as 'luarocks install bit32'

P#37155 2017-02-04 17:46 ( Edited 2018-05-17 20:47)

I'm getting an error

Using Lua 5.1.4 on Windows.
Installed midi with luarocks

C:\Users\Gryphon\AppData\Roaming\pico-8\carts\music>lua midi2pico.lua invent13.mid songdata.p8
lua: .\argparse.lua:3: attempt to call field 'pack' (a nil value)
stack traceback:
        .\argparse.lua:3: in function 'parse'
        midi2pico.lua:4: in main chunk
        [C]: ?

I'm very excited about having more midi-conversion options.

P#37182 2017-02-05 15:16 ( Edited 2017-02-05 20:16)

Lua 5.1 does not have table.pack or a bit library, which is required by midi2pico

You may install a backport of bit32 via luarocks: luarocks install bit32
and then add

function table.pack(...) return {n=select("#", ...), ...} end

to the very top of the file

I'll add 5.1 compatibility soon

EDIT: Lua 5.1 and LuaJIT compatibility has been added

P#37188 2017-02-05 17:41 ( Edited 2017-02-05 23:03)

hooray for MIDI converter club! :)

drum support! nice! (mine doesn't do drums at all :X)

P#37191 2017-02-05 17:54 ( Edited 2017-02-05 23:26)

Cart #37206 | 2017-02-06 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Also just got my old streaming code fixed up, so now midi2pico has an option to generate a cart that streams sfx data from gfx area.

It's mostly for debugging, but it does technically allow a ~364% increase in music storage at the expense of your gfx and maps, possibly more if you use it right.

And a vumeter for fun.

P#37201 2017-02-05 20:40 ( Edited 2017-02-06 06:03)

Cart #37270 | 2017-02-07 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Just got MIDI CC11 (Expression) supported, which fixes missing volume effects in some midi files. So, have another demo, one of which uses this said Expression command.

Some files like to use CC7 (Volume) as an overall volume, relying on CC11 for dynamic volume control. And some use vice versa, yay midi!

More instrument to pico-8 mappings have been added too which improves the piano and organ sounds.

And a note+volume visualizer for fun

EDIT: Fixed the volume of the beginning 4 notes, sorry.

P#37226 2017-02-06 15:53 ( Edited 2017-02-07 23:24)

I've just added in some time correction options, so midis that were previously rejected by midi2pico for having odd timing may now be supported.

I'd notice in my ~1000 midi's marked as bad, a lot of them had common errors, timing that was close but off by a small bit, or only a few notes did not match the timing, so two options have been added to support these cases, --ignorediv and --fixdivone

There is also a new midi timing --analysis option that can go through and provide some suggestions for possible --div=n values. It will go through all the notes in a file and show which divisions would work best for most notes and also analysis the time spacing between notes.

Do note that some midi files are just really badly timed and cannot be salvaged by midi2pico without the help of some external midi editing tool.

I'll also be working on making MusicHAX an option that doesn't require p8convert, instead of spitting out binary files to be converted into pngs it'll spit out a p8 file

EDIT: Completed making MusicHAX work with p8 files, so now p8convert is not required to use this option.

P#37263 2017-02-07 14:08 ( Edited 2017-02-07 20:03)

I like the visualizer :)

I'm gonna have to look at your tempo stuff to see how it works 'cause that has always been a weak point for mine...

P#37271 2017-02-07 20:13 ( Edited 2017-02-08 01:16)

Tempo support is still rather limited but it supports a good number of cases:

Allows multiple tempo changes before any notes play
Allows multiple tempo changes before any time has passed from zero
Or takes the first tempo event it can get (there are possible problems with this one)

The first two were needed because some midis like to change configuration a bunch of times before actually doing anything.

It's kinda hard to make midi tempo work in pico-8 since in a midi it can change wherever it wants to but pico-8 can only change speed on every 32 note boundary. There's also no way to force the sfx to end early, looping parameters don't affect that.

Songs that don't change in the middle of them will work fine for now. A thing I was thinking of doing was seeing which tempo applies for most of the song and using the longest active one. Or just having an option for delayed/early tempo changes up to the closest sfx boundary

P#37290 2017-02-08 13:14 ( Edited 2017-02-08 18:25)

Just tried this out with the theme tune of the game I am trying to remake in PICO-8..... with outstanding results!

Many many thanks! :)

NOTE: not sure if this will help anyone ever, but I had to edit line 707 of the conversion program to read:

local time, track, channel, control, value=unpack(event, 2)

that is: i removed the 'table.' before unpack.... which i think may be something to do with my lua version (5.1.5)? Not sure though really, just stopped me getting an error regarding unpack() as a nil value.

P#37749 2017-02-23 10:16 ( Edited 2017-02-23 15:16)

Ahh thank you for mentioning that, forgot to fix that when adding in Lua 5.1 support

Fixed in latest version.

P#37838 2017-02-26 00:02 ( Edited 2017-02-26 05:14)

Hey gamax92,
Thanks a lot for sharing this code here.
I gave it a try and it took me arround 9h in 3 sessions to get to the point where it says Info: Finished!
At this moment I'm rly enjoying the success ^^ But I didn't listen to the result yet :D

Btw. My biggest problem was that was kinda new to the lua universe and had to learn a lot about lua and luarocks.
How to install rocks compile lua and that you should omit the hashtags "#" when using the Microsoft Command Line and that lua should be "lua53" when using lua 5.3 and much more of such things...
But finially I was using the cmd like this:

cd C:\lua
lua53 midi2pico.lua somesong.mid songdata.p8 --notrunc

Maybe that helps somebody else to get it faster running.
and now I'm going to listen the converted tune. :D


P#45169 2017-10-13 05:24 ( Edited 2017-10-13 09:26)

ah yes, btw, I've been using it for a while! the only way for me to put music in there :)
a little hard to setup but then it works very well most of the time!
(a little buggy in sewers of doh but I like that (I'm weird))

though it seems I always have to "--analysis" first then use the result in "--div="

now if the resulting p8 could include

music(0) function _update() end

that would be even more ace!

P#45171 2017-10-13 07:15 ( Edited 2017-10-13 11:15)

I also thought that :D

Here is my first ported tune (LemmingsLEMMIN1P(PC).mid)
I had to preedit the mid with mudplugtracker to kick some channels, arrange the patterns new and auto clean the whole file to remove some unused stuff.


Cart #45173 | 2017-10-13 | Code ▽ | Embed ▽ | No License

P#45174 2017-10-13 08:19 ( Edited 2017-10-13 12:21)

I could have sworn I had a stub option available, I'll add one and also clean up the readme a bit

P#45388 2017-10-21 17:30 ( Edited 2017-10-21 21:30)

Nice script! It worked in combination with p8tool but I have to make sure to use convert with the --clean option or p8tool will complain that there are too many values to unpack.

I'm not sure whether the non-clean format is official or legacy, all I can see is that resaving from inside PICO-8 will also clean the data. So I don't know if it's a bug on p8tool side or not.

P#52833 2018-05-17 16:47 ( Edited 2018-05-17 20:47)

How do I get the following to work?
>luarocks install bit32
gives me an error when trying to install the bit32.dll into the Lua install folder in Program Files (x86):
Error: Build error: Failed installing bit32.dll in C:\Program Files (x86)\Lua5.1\rocks/bit32/5.3.0-1/lib

P#68647 2019-10-08 15:43

I know, this is from 2017 and is way dead, but is there anybody willing to help? I don't understand how to use this.

P#122891 2022-12-23 13:47

@Mank, in case you don't get this tool figured out, there is also an interactive web-based midi converter here: https://bikibird.itch.io/denote

I don't know how it compares in features, but it's very simple to use.

P#122900 2022-12-23 17:31

[Please log in to post a comment]