Skip to content
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

Do not send portamento messages (MIDI CC 5, 65 & 84) to FluidSynth #2705

Merged
merged 1 commit into from Jul 31, 2023

Conversation

johnnovak
Copy link
Member

@johnnovak johnnovak commented Jul 30, 2023

Overview

Roland SC-55 style Portamento cannot be emulated on FluidSynth, and out-of-tune sounding portamento is a much bigger problem than the lack of subtle portamento effects in a handful of synth-oriented game soundtracks.

This fixes the weirdly out of tune synth parts in the Level 8 music of Descent (see #2701).

Detailed explanation

The Roland SC-55 and its clones (Yamaha MU80 or Roland's own later modules that emulate the SC-55) handle portamento (pitch glides between consecutive notes on the same channel) in a very specific and unique way, just like most synthesisers.

The SC-55 accepts only 7-bit Portamento Time values via MIDI CC5, where the min value of 0 sets the fastest portamento time (effectively turns it off), and the max value of 127 the slowest (up to 8 minutes!). There is an exponential mapping between the CC values and the duration of the portamento (pitch slides/glides); this custom curve is apparently approximated by multiple linear segments. Moreover, the distance between the source and destination notes also affect the portamento time, making portamento dynamic and highly dependent on the notes being played.

FluidSynth, on the other hand, implements a very different portamento model. Portament Time values are set via 14-bit CC messages (via MIDI CC5 (coarse) and CC37 (fine)), and there is a linear mapping between CC values and the portamento time as per the following formula:

  (CC5 * 127 ms) + (CC37 ms)

Because of these fundamental differences, emulating Roland SC-55 style portamento on FluidSynth is practically not possible. Music written for the SC-55 that use portamento sounds weirdly out of tune on FluidSynth (e.g. the Level 8 music of Descent), and "mapping" SC-55 portamento behaviour to the FluidSynth range is not possible due to dynamic nature of the SC-55 portamento handling. All in all, it's for the best to ignore portamento altogether. This is not a great loss as it's used rarely and usually only to add some subtle flair to the start of the notes in synth-oriented soundtracks.

This table and diagram illustrate the exponential mapping between the CC values and the Portamento Time. Note the below figures apply only for the two specific MIDI notes I used for my reverse engineering exercise; as the Portamento Time is dynamic, you'll get different exponential curves based on the distance between the two notes:

CC 5 value  Portamento time
----------  ---------------
     0          0.000 s
     1          0.006 s
     2          0.023 s
     4          0.050 s
     8          0.110 s
    16          0.250 s
    32          0.500 s
    64          2.060 s
    80          4.200 s
    96          8.400 s
   112         19.500 s
   116         26.700 s
   120         40.000 s
   124         80.000 s
   127        480.000 s

image

Sound examples

These are MP3 files—download them then change the extension from ZIP to MP3.

Roland Virtual Sound Canvas

This is the isolated synth part in question of the Level 8 music of Descent. This is how portamento sounds on the Roland Virtual Sound Canvas:
scva-portamento-8.zip

Now with the portamento disabled. The difference is certainly subtle and it's a feel thing; note how there is less attack and "vigour" at the start of the notes. You can't really hear a pitch glide when portamento is on because it's fast, but it makes the notes "hit harder" and sound more dynamic and "dangerous" than with portamento off.
scva-no-portamento.zip

Now increasing portamento substantially to 48 to mimic the FluidSynth "bendy notes" behaviour:
scva-portamento-48.zip

And a simpler example where it's more obvious to hear the difference between portamento off and portamento 8. Pay attention to the start of the notes:
scva-portamento-example-no-porta.zip
scva-portamento-example-8.zip

Another example, portamento 80 on a saw wave with notes spaced several octaves apart (that's a looooong 4.2s portamento!)
saw-portamento-80.zip

FluidSynth

Isolated synth part as played by FluidSynth using the GeneralUser GS SoundFont when we let the portamento CC messages through. Yeah, quite horrible due to the very different portamento behaviour between the SC-55 and FluidSynth (not FluidSynth's "fault" though; these are two different synths and FS never aimed to be SC-55 compatible):
fs-porta-coarse-8.zip

With the portamento CC messages completely filtered out, this sounds very similar to the "no portamento" SCVA recording — this is the final solution:
fs-no-porta.zip

An attempt to mimic the SC-55 portamento behaviour by setting portamento coarse to 0 and fine to 60, which should achieve a 60ms portamento. This was done by ear as it's impossible to come up with a single figure as the portamento times are different for every note-pair on the SC-55. Still, it doesn't sound anything like the the SC-55; even manually it's impossible to come up with a single number that replicates the feel of the SC-55 behaviour on this single synth line. Coming up with a general algorithm that would decide the correct number on the fly for every musical score is practically impossible... and we're already verging into accurate SC-55 emulation territory 😅 Which is not possible on FluidSynth, as we well know—we just have to be content with a ~70-80% approximation of the real thing, at best.

fs-porta-fine-60.zip

@johnnovak johnnovak self-assigned this Jul 30, 2023
@johnnovak johnnovak added audio Audio related issues or enhancements bug Something isn't working labels Jul 30, 2023
@johnnovak johnnovak marked this pull request as ready for review July 30, 2023 07:30
@johnnovak johnnovak force-pushed the jn/fluidsynth-ignore-portamento branch from c8a1143 to 41a8587 Compare July 30, 2023 07:51
@johnnovak johnnovak changed the title Do not send Portamento (MIDI CC5) messages to FluidSynth Do not send portamento messages (MIDI CC 5, 65 & 84) to FluidSynth Jul 30, 2023
@johnnovak johnnovak force-pushed the jn/fluidsynth-ignore-portamento branch from 41a8587 to 09f86d1 Compare July 30, 2023 08:13
@johnnovak
Copy link
Member Author

johnnovak commented Jul 30, 2023

@joncampbell123 @dwhinham this might be relevant to your interests 😄

@johnnovak johnnovak force-pushed the jn/fluidsynth-ignore-portamento branch from 09f86d1 to 4d35f25 Compare July 30, 2023 08:50
Roland SC-55 style Portamento cannot be emulated on FluidSynth, and
out-of-tune sounding portamento is a much bigger problem than the lack
of subtle portamento effects in a handful of synth-oriented game
soundtracks.

This fixes the weirdly out-of-tune synth parts in the Level 8 music of
Descent.

See the code comments for further details.
@johnnovak johnnovak force-pushed the jn/fluidsynth-ignore-portamento branch from 4d35f25 to f2c1eea Compare July 31, 2023 06:41
@johnnovak johnnovak requested a review from kklobe July 31, 2023 06:41
@kklobe kklobe self-requested a review July 31, 2023 23:13
Copy link
Collaborator

@kklobe kklobe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gave a good listen to all the samples and fully agree with this change.

@johnnovak
Copy link
Member Author

gave a good listen to all the samples and fully agree with this change.

Thanks for the review, man!

@johnnovak johnnovak merged commit 1930f7f into main Jul 31, 2023
52 checks passed
@kcgen kcgen deleted the jn/fluidsynth-ignore-portamento branch August 1, 2023 23:04
@johnnovak johnnovak mentioned this pull request Aug 2, 2023
3 tasks
@johnnovak johnnovak added the midi MIDI related features and issues label Dec 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audio Audio related issues or enhancements bug Something isn't working midi MIDI related features and issues
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants