mmitch / gbsplay

gameboy sound player
https://mmitch.github.io/gbsplay/
Other
98 stars 19 forks source link

muting channels in midi output #88

Closed pclalv closed 1 year ago

pclalv commented 1 year ago

I thought that I might be able to invoke, for example, gbsplay -234 -omidi /path/to/some.gbs 1 1 to generate a midi file containing only the note data for channel 1, but this seems to not be the case. is this possible by some other means, or not?

my apologies and please excuse me if this question has been asked and answered. I searched for mute midi in this repo and found no relevant issues.

mmitch commented 1 year ago

Currently this is not possible, but it seems to be more like an "nobody ever thought about this" than "it's basically impossible". I'll look into it.

mmitch commented 1 year ago

btw: You should be able to remove the unwanted channels with nearly every MIDI editor as the different GBS channels map to different MIDI channels.

mmitch commented 1 year ago

I have added channel mute support for both the midi and altmidi plugouts in the midi-channel-mute branch. Please have a look if this works for you.

pclalv commented 1 year ago

thank you for quick response!

yes, that branch does do the job of generating MIDI files with select channels muted.

however, there's something that confuses me. I'll try to explain as best I can, but please excuse my unfamiliarity with how MIDI works at a deep level.

consider a 4 track MIDI file generated by gbsplay.

if you load that MIDI file into Ableton, Ableton loads it into one Ableton MIDI track.

on the other hand, if I load that same MIDI file into Garage Band, Garage Band separates each MIDI track into 4 Garage Band MIDI tracks.

so, the reason that I asked about this feature is that I was hoping that it would be easier for me to import these single-channel MIDI files into Ableton without having to try to convert MIDI formats (I've struggled to do this in the past) with Garage Band or some other tool as an intermediary.

this feature does the channel separation perfectly - however, when I load the multiple MIDI files into Ableton, they're out of sync with one another. this feels surprising to me, and I suspect that others might feel the same.

I hate to sound entitled, but I would like it if gbsplay could generate channel-muted MIDI files that could still easily be synced with one another. is this possible? does this even make sense as a feature? or is it actually easy to sync up these separate MIDI files, and it only appears difficult to me because of my ignorance and inexperience with MIDI?

mmitch commented 1 year ago

There are two (actually three, but the third is rarely used) types of Standard MIDI Files (SMF):

gbsplay creates Type 0 MIDI files because they are easier to write: just append a note event to the file the moment it happens. For Type 1 we'd have to collect the data of every channel separately in memory and can only start writing track after track when all data has been collected. This would mean handling dynamically growing memory buffers in C, which I personally would like to avoid.

So Garage Band seems to have an importer for Type 0 files that automatically seperates the combined MIDi channels. You could try to tell Ableton to upgrade their importer ;-)

I still think using a converter from Type 0 to Type 1 should be a possibility. The MIDI files created by gbsplay are very simple, so any basic converter should work. There might even be online converters nowadays. I personally can't recommend any tools as my active time sequencing MIDI files was more than 20 years ago. I used Cakewalk on Windows 95 and have not gotten proficient in any other tool since then.

mmitch commented 1 year ago

Regardless of the MIDI file Types, I think I know the reason for the offset you are experiencing in the single channel output: We start writing the MIDI file with the first event that is happening. This effectively removes any silence before the first event. With a single channel export, this will make all channels become misaligned, as every channel has a different amount of silence removed.

This should be easily fixable, I'll look into it.

(This might introduce some initial silence in regular MIDI output, too, which would be an incompatible change, but other output formats also keep silence at the beginning. I'd argue it's a more authentic rendering of the GBS file than before.)

mmitch commented 1 year ago

It seems that my suspicion was wrong: I have looked for some GBS files that have one channel starting much later than other channels and I tried to find some faulty offsets but there are none. Silence at the start of a channel does not get removed. I have added some debug output that shows the notes being written at exactly the same timestamp regardless of muted channels. (If the channel in question starts very late, I need to ramp up the -T parameter of gbsplay or the output is empty, but that's "works as designed" :wink:)

Perhaps the Ableton import is messing things up.

What happens if you import the channel-separeted MIDI files into Garage Band? Are the channels out of sync or in sync?

mmitch commented 1 year ago

With which GBS file do you have the Ableton import problems? Perhaps I should test with that file, too.

pclalv commented 1 year ago

I tried outputting midi with both the midi and altmidi output plugins, and in both cases the three channel-separate MIDI tracks are totally out of sync.

yeah, I think you're right about looking for a workaround or tool to convert MIDI. I appreciate your help with this, and thank you for maintaining this tool!

I've been testing with the music from Robopon Sun Version, with the first track in the GBS file. if you haven't heard it before, I hope you enjoy it :)

mmitch commented 1 year ago

Thanks for your reply. I've done some tests with Robopun Sun and found two things:

I will investigate further, I've opened a separate bug for this: #93

pclalv commented 1 year ago

I'm surprised to read that you broke MIDI output. I built gbsplay (make clean && make) from 1dcf2a3 yesterday, and both midi and altmidi seemed to work just fine. maybe my build wasn't as clean as I thought it was. oh well.

yes, it seems that we had different interpretations of 'out of sync'. the description you just gave correctly describes what I've been seeing/hearing.

anyway, given that gbsplay does support muting channels in midi output, and that you've opened a new issue for the 'out of sync' thing, I suppose this issue can be closed.

mmitch commented 1 year ago

I had broken the endianess of the track length field, I hat both midi2ly.py and Rosegarden complain about missing track endings. Perhaps your MIDI importer does not care about the length field - theoretically it should be possible to play or import a MIDI track of unknown length.

btw: This issue has already been closed in August ;-) But I really thank you for your reply to keep this going!

pclalv commented 1 year ago

cheers, and thank you for maintaining gbsplay :)