-
Notifications
You must be signed in to change notification settings - Fork 641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use channel 10 for percussion #187
base: master
Are you sure you want to change the base?
Conversation
This enables the generation of “percussion” as an “instrument” in the soundfont builder. It also adds that instrument to our General Midi database, with ID 0 (one-based) resp. -1 (zero-based). This does not really reflect the use in GM, but avoids a large number of case distinctions and appears mostly beneficial. This instrument is pre-selected for channel 10 (one-based), to conform with GM usage.
This argument is never used, and I have no idea what that variable `instrument` would be referring to in this place, since it is not a declared variable of nearby enclosing scopes. This is a drive-by fix, found and fixed on the way towards percussion.
This looks good (I've hacked something similar in here). But also GM allows for multiple drum kits with different programs I think, so maybe you shouldn't force program a single program -1. The drum kits are really a whole separate bank of instruments. |
Ideally you would only include samples for which there are actually sounds in the sound font, else you are including a lot of samples of silence, but it's not easy to know which notes are used and which aren't. |
@hmoffatt I realized that there could be multiple drumkits when I looked at https://github.com/musescore/MIDI.js/commit/4c1e69260c4a27bfc7cf7935396ccaabf2cbb688. And I had the same thought as you: we really should be generating exactly those keys for which there are samples in the soundfont. So I wrote a soundfont parser for Node.js and learned a lot about the soundfont format in the process. I realized that MIDI.js in particular does not make use of the loop points present in the soundfont, so it can't stretch the sustain phase arbitrarily. I also learned how it shares samples for multiple keys, and how it can reuse whole instruments in different presets, which seems particularly relevant for different drumkits. At the moment I'm considering abandoning MIDI.js and writing a wavetable synthesizer that works with the raw samples, as stored in the soundfont, and in the end ideally reproduces what fluidsynth does to turn these samples into notes, honoring as many of the soundfont generator specifications as technically possible. |
Nice work @gagern, I would be interested in an improved version of the soundfont converter that omitted unused notes. (Although you mentioned you wrote the sf2 parsing for Node.js, so maybe this is not easy. I was tempted to rewrite the converter in Python personally, as there is an sf2 parser module for Python also.) Ideally the converter would extract the samples directly and also the loop parameters, so that those could be used by the sample player. I think webaudio supports looping. I think sf2 also supports different samples for different velocities... You might be interested in https://github.com/danigb/soundfont-player which loads the existing javascript soundfont conversions and just plays individual notes without any sort of sequencing layer. |
@hmoffatt: I have a version which does extract all the samples, but the metadata still needs some reformatting. Yes, WebAudio does support looping. It currently does not support exiting the loop at a scheduled point in time for the release phase, which is something sf2 supports but which is not being used in the Fluid soundfont I've been working with so far. WebAudio also supports changing the playback rate, which is vital since samples may be used for different notes than those for which they were recorded. Sf2 also assumes a configurable five-phase volume envelope (attack, hold, decay, sustain, release), and some soundfonts might sound bad unless the player learned to reproduce those as well. I'm thinking about something along the lines of soundfont-player, but using the actual data from the sf2. Adding a sequencing layer on top of that would be fairly simple, so the core functionality would be in being able to play each note as accurately as possible. |
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
The MIDI.js verison here is one which integrates three of my PRs: mudcube/MIDI.js#187 (percussion) mudcube/MIDI.js#189 (MIDI.now) mudcube/MIDI.js#190 (WebMIDI detection) The playtone function automatically triggers loading of the plugin. The corresponding soundfont is loaded only when needed, which means there will be some time between when the function calls start and when sound becomes actually audible. Samples are hosted on http://cindyjs.org/soundfont/ which might break widgets delivered through HTTPS. We need a certificate for cindyjs.org to solve this problem, or allow configuring the soundfont through some API, e.g. some CindyScript function. The example is essentially taken from a Cinderella export, except for the deletion of a duplicate play button.
|
||
# Display instrument names. | ||
INSTRUMENTS.each do |i| | ||
puts " #{i}: " + MIDI::GM_PATCH_NAMES[i] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test
This enables the generation of
percussion
as an “instrument” in the soundfont builder. It also adds that instrument to our General Midi database, with ID 0 (one-based) resp. -1 (zero-based). This does not really reflect the use in GM, but avoids a large number of case distinctions and appears mostly beneficial. This instrument is pre-selected for channel 10 (one-based), to conform with GM usage.The soundfont builder changes fix #91. This also addresses the core of #72, but perhaps we should prevent program changes on channel 10 to completely fix that. Doing so might break some existing applications, though, so another alternative might be suppressing program changes in the MIDI file player only.
Do we need to restrict the soundfont creation to those “notes” which actually have a percussion instrument associated with them? Currently I'm using the same range used for other instruments as well, and I don't see fluidsynth complaining.