I’ve created a plugin, PianoRes, that imitates piano resonance when the sustain pedal is down. It’s intended to be plugged in downstream of a sample player (like sfizz) and respond to MIDI sustain pedal messages, adding the resonance when the pedal is down (and fading it out when it is lifted.)
It’s not built for Zynth yet. I’ve been developing on Windows using VS Community and I know it’s capable but I haven’t got to that part yet. Stay tuned (or feel free to help out.)
The project is GitHub - jlearman/PianoRes: Resonance plugin for sampled pianos · GitHub . It’s licensed under GitHub Unlicense (equivalent to CC0), and I hope to get it installed on Zynth. But I also need to get Sfizz to pass the MIDI through. I don’t know if there’s a way to plumb it up on Zynthian otherwise.
It doesn’t seem to be too big a CPU hog, so I’m hoping it’ll run well on Pi5.
Anyway, LMK what you think; any feedback is appreciated.
The default IR file is for Accurate Salamander Grand 6.2beta2, available here: Accurate-Salamander Project . I use the live/flat version. IMHO, it really makes a great piano even more fun to play. The controls are set up so it’s easy to compare with or without the effect, or even to hear just the effect.
It doesn’t save/restore settings yet and there are a few other issues.
The built-in/default IR file is a short one for Accurate Salamander Grand (about 4 seconds.) It works better with the longer (10 second) IR file, which is included in the release. I was worried about the CPU usage, especially for Zynthian, and thus making the short one the default.
OK, please try again! No idea why the LV2 plugin files were all empty on the zynthian. Odd, since it was working! Copied again, rebuilt the zip and uploaded, should be better now.
The default wet level is IMHO a bit higher than “natural” but it helps to actually clearly hear the effect. One nice way of hearing the effect clearly without having to turn it up too much is to compare playing a high undamped note like G6 (ISO) with or without pedal.
Very interested in any feedback. I think the IR needs work. One thing I knew was a shortcut was, all the notes summed were recorded from the same velocity, but I bet in reality there’s some sort of a response curve. And in practice, the low end seems over-emphasized and I suspect that makes sense.
I also wondered about whether phase matters, because I really recorded just two MIDI files, each with half the piano’s notes, so the notes don’t all start at exactly the same time. Well, the attack time matters in principle, but since the response isn’t very immediate anyway I don’t think it matters in practice. After thinking about how convolutions work, the phase isn’t terribly relevant to whether it’ll respond to a given note. I wonder whether the attack time variation matters in terms of constructive/destructive coherence. I suspect I’d get more constructive, if they were all aligned perfectly. Maybe that’s why low G seems prominent (esp when playing C1 or C2). And I wonder if I’m overthinking it.
Ack! Please use it at 44.1KHz rate. I discovered that the JUCE convolver automatically adjusts when loading a file, but not when loading from memory buffer, which is needed for Zynthian since there’s no UI to specify a file.
The problem isn’t the JUCE convolver, it’s my code, or the fact that I used a 44.1Khz file for the default IR. It works it just doesn’t sound right, for the obvious reason. I plan to fix it soon.
I’ve been testing your PianoRes plugin. It sounds really nice! Congratulations!
But …it generates a lot of XRuns with the default zynthian audio settings (2 buffers of 128 samples => latency 5.6 ms) . The recommended config (3 buffers of 256 samples => 16ms latency) is not workable for live playing. Most serious piano players wont accept this latency.
Do you think you could improve the performance to get the plugin running smoothly with the default low-latency configuration? I don’t think it’s too difficult to achieve. Pi5 & Pi4 are perfectly capable of performing real-time stereo convolution with these settings. Other plugins does it with very low CPU load.
Apart from performance, LV2 plugins (and zynthian!) does support loading files via the “Path extension”. There is no limitation about this.
You should be capable to tell JUCE to export the “IR file” parameter & generate TTL for it. JUCE should support the Path extension, that is part of the LV2 core specs from long time ago. If this is not possible with JUCE, the limitation is not in LV2/Zynthian, but in JUCE not supporting the LV2 mechanism to load files, that is pretty straightforward.
The TTL generated by JUCE for the “IR file” paraemter should be something like this:
<plug:_20_irfile>
a lv2:Parameter;
mod:fileTypes "wav,flac";
rdfs:label "IR File";
rdfs:range atom:Path.
Finally, a minor issue, the plugin in the “Others” category. It should be in the “Reverb” category, right?
I would like to include the plugin in the Vangelis release, but it should run without XRuns with the default audio settings in Pi4 & Pi5.
Typically a plugin reports it latency in samples to the host (which must be jalv here) and adjusts the compensated latency to the audio stream. Ideally it tries to squeeze all reported latencies into the needed amount of buffersizes, some DAWs would introduce a buffer per plugin at least.
In this use case the plugin could just report zero latency to the host and use an internal buffer to feed the convolution reverb and output the convoluted signal delayed.
I must say that I have more insights about VST format in windows and less about LV2 in jalv/jack.
I don’t even know if this plugin even reports latency, it’s maybe more a question of performance.
It probably reports latency, but i doubt the host (jalv) do nothing with it. The zynthian core does nothing about latency compensation, not matters what the plugins report to the host.
In the future we could consider latency compensation, but until now we didn’t becasue for most use-cases as “keyboard expander” it has not sense.
Regarding the PianoRes plugin, i think there is a low performance problem and it’s not related with latency compensation at all.
From the Jalv’s code ( Report Jack latency (Patch from Robin Gareus).),it seems that jalv calculates the plugin’s latency and reports to jack. I’m not sure of what jack does with this info. It could add “delays” to the faster paths to compensate the delay of slower paths and ensure the final audio mix is perfectly synced at the sample level, but i couldn’t find a good explanation about this.
Anyway, i doubt any of this is the cause of the XRUNs.
No, it doesn’t cause the xruns, but if a certain latency is needed to calculate the convolution it would be better in a keyboard extender context to not report latency via jalv to jack in order to output the dry signal undelayed and handle the convolution with an internal buffer.
Anyway I cannot find an explicit latency report directive in @jlearman 's code.
So you’re right, it’s a performance issue. But typically convolution should be managable with standard buffer configuration.