jpcima / smf-dsp

Advanced MIDI file player
Boost Software License 1.0
47 stars 5 forks source link

[Feature request] Ability to use two MIDI synths at once #32

Open freq-mod opened 2 years ago

freq-mod commented 2 years ago

OPN2, provided by libOPNMIDI, has a very low polyphony. Even with 2 cores, it's just 12 channels. Some MIDIs, most often these written for SC-88Pro synth, require up to 40 channels. While you can raise the amount of cores, at some point, MIDI playback may become heavy for some weaker devices. Also, some MIDI timbres, like drums, would sound somewhat better with PCM-based device.

Since this player supports multiple synths, also sf2 based like Fluidsynth, would it be possible to "mix" two midi snth instances. One synth would play some MIDI channels (specified in config file), other the rest. That would also allow for some kind of Sound Blaster 16 PCM emulation when mixed with libADLMIDI. Is it feasible, or in scope of this program?

jpcima commented 2 years ago

Most definitely, it's possible to implement such a thing.

There exists an alternative solution as well, probably more in line with what ordinary players would do; this is to let a background task compute the audio up to the next N seconds of music, and have the audio thread just deliver precomputed data.

A drawback is, as soon as the player seeks or changes speed, the buffer has to be trashed and reloaded with a bit of audio, which creates a little wait before resuming.

Sorry for delay, trying to catch up with my back log. :)

jpcima commented 2 years ago

On topic of the hybrid synth thing:

Surely it would make more sense that the synths are mapped according to bank/program/precussive mode, instead of channel?

This may also cause challenges regarding the format of configuration.. i'll give it a bit of thought. It might not be a bad idea to move the configuration format to toml.

freq-mod commented 2 years ago

Yeah, I also thought of it. Maybe if, for example, GM bank is played via FM, and GS/XG banks are played via Timidity/Fluidsynth...

jpcima commented 2 years ago

What I have in mind currently.

User can define one or more custom synth setups. These setups are in files of the form s+_<identifier>.ini. The s+ files will be listed by the program and they appear in the F3 menu.

That configuration will allow to define one or more synth. By default the settings of the synth are those of the ini file of that synth (t_adlmidi.ini), but it accepts the options of the s+ file as overrides.

For mapping midi to synths, I considered a lua routine body, that receive channel, bank pgm drum and such. I'n providing an example below. Also this form is flexible enough that it can route to multiple synths to create layers.

Example s+_mine.ini

name = FM+Soundfont

synth1 = adlmidi
synth2 = fluidsynth

;; adjust relative volumes
gain1 = 0.0
gain2 = +6.0

[synth1]
option1 = value1

[synth2]
option1 = value1

[mapping]
code = <<<LUA
    if (channel==10)
        to(synth2)
    else
        to(synth1)
LUA
freq-mod commented 2 years ago

sounds interesting, it can work