gbsplay icon indicating copy to clipboard operation
gbsplay copied to clipboard

muting channels in midi output

Open pclalv opened this issue 2 years ago • 8 comments

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.

pclalv avatar Aug 25 '22 04:08 pclalv

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 avatar Aug 25 '22 18:08 mmitch

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 avatar Aug 25 '22 18:08 mmitch

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.

mmitch avatar Aug 25 '22 19:08 mmitch

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?

pclalv avatar Aug 26 '22 21:08 pclalv

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

  • Type 0 has only one track that contains the data of all 16 MIDI channels.
  • Type 1 has an extra track for every MIDI channel.

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 avatar Aug 27 '22 07:08 mmitch

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 avatar Aug 27 '22 07:08 mmitch

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 avatar Aug 27 '22 19:08 mmitch

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

mmitch avatar Aug 29 '22 17:08 mmitch

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 :)

pclalv avatar Sep 27 '22 19:09 pclalv

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

  • I totally broke MIDI output 4 weeks ago and nobody noticed :) It's already fixed in master.
  • Until now I interpreted "out of sync" as "the tracks start at different times and everything is off by a fixed amount". Now I have noticed that while the tracks start in sync (like I've seen before), they gradually get more and more out of sync the longer they run.
    This does not have anything to do with trimmed pauses at the start of a track on which I had focused. Instead it looks like some kind of rounding error(?) in the timestamp delta generation that adds over time. When writing all tracks at once it is unnoticeable because all tracks are off by the same amount.

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

mmitch avatar Sep 27 '22 21:09 mmitch

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.

pclalv avatar Sep 28 '22 14:09 pclalv

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!

mmitch avatar Sep 28 '22 19:09 mmitch

cheers, and thank you for maintaining gbsplay :)

pclalv avatar Sep 28 '22 23:09 pclalv