Introducing pluguzu, a plugin to run Tidal natively in a DAW

Hello folks,

I'd like to share with you pluguzu, a CLAP/VST plugin featuring a text editor to write Tidal patterns from the comfort of your DAW. It's still the early days, but I think it's already quite usable and I'd love to get your feedback!

I think it would be neat to have a portable binary build, so that you could setup Tidal by just copying the plugin binary, and there are other items in the roadmap that might tickle your fancy:)

Cheers o/
-Tristan

17 Likes

Tristan really nice project!!!
just to be sure of what I read on your CodeBerg, the VST or clap isn't available right away, one must compile it, right? Is it Linux only? I think those repositories can be installed also on windows, but wanted you to point me out in the right direction...

Thanks for sharing your work!

Thanks! Yes that's right, the plugin must be built from source. Here is an issue about adding support for the other platform: #6 - Mac build - TristanCacqueray/pluguzu - Codeberg.org

Pretty amazing idea! Looking forward to what's to come :))

2 Likes

Can’t describe how into this I am. My entire system right now is centered around piping midi into Bitwig, so having a dedicated plugin that hosts TidalCycles sounds incredible. Super excited to see how this project develops!

Thank you for the kind words, makes me excited to develop this project!

Here is a quick update: it looks like the plugin framework I picked (DPF) doesn’t have a consistent transport implementation across platforms, see: #4 - Timer going backwards - TristanCacqueray/pluguzu - Codeberg.org and issue #7. I suspect this happens because DPF supports many plugin formats and perhaps it is not much used to implement a sequencer type of plugin (see upstream issue getTimePosition() returns the same value between two runs · Issue #503 · DISTRHO/DPF · GitHub ). It’s a bit unfortunate because the plugin works well on my setup (REAPER / Linux x86). Thus I’m investigating switching to another framework called nih-plug and I just pushed a prototype in the rust-nih branch. So far it seems to work well and the transport provides a convenient pos_beats helper to get the current bar fraction which appears to be more reliable. I hope to have a working implementation shortly and it would be good to validate if that fixes the issue #7 related to Bitwig.

Also, with regards to distribution, I reported the static link issue to GHC #26390: Can't build native-static foreign library on Linux x86_64 · Issues · Glasgow Haskell Compiler / GHC · GitLab and I can now build a portable binary which should enable installing pluguzu without requiring a build from source with the Haskell/Rust toolchains.

Cheers o/

2 Likes

I merged the rewrite to nih-plug and egui through https://codeberg.org/TristanCacqueray/pluguzu/pulls/9

As an extra feature, I added support for source events location highlight in the editor thanks to the deltaMini helper from tidal! I think it looks fabulous, please give it a try!

I am presently working on integrating the original dirt sampler so that pluguzu can play sounds out of the box. For example, here is the binding I created: dirt.rs.

This is very exiting because pluguzu is now fully usable standalone. It can still be hosted inside a DAW, but the app alone is quite fun too, so I think I'll update the project description to something like "standalone live coding text editor".

If you can give it a try, I would love to get your feedback. The branch still need a bit of work before being merged, like to show sample loading errors, and to build the libdirt automatically. But I am looking forward making a release shortly.

I would like to thanks @yaxu , as pluguzu would not have been possible without his creations. I particularly enjoyed the design of dirt, and how easy it was to get it running inside nih-plug. I think I'll eventually make the libdirt binding standalone too so that it can be integrated in other engines.

Cheers o/

6 Likes

All the changes are now merged, and provided a Rust and Haskell toolchain, running make && make install now produce the following standalone binaries:

[+] Installed STANDALONE: ~/.local/bin/pluguzu
[+] Installed CLAP: ~/.clap/pluguzu.clap
[+] Installed VST3: ~/.vst3/pluguzu.vst3

With the audio samples management and the events' highlight, I had to tweak the core logic to ensure a smooth audio callback, and based on a local benchmark, pluguzu seems to work fine up to 200k events per four bars, e.g. with such code:

stack [
  fast "50000" $ n "c3",
  s "tok*4"
]

… beyond that, the rendering may take too long and starve the cpu.

I think the implementation is accurate timing wise, but I'm still on the look out for synchronization issues with the external clock. For example, reading the bar position may have some (sub millisecond) micro jitters, and perhaps more work is needed to ensure perfect accuracy. When that happens, a warning is printed, and I'd love to gather more data when that occurs.

Also the code editor, provided by egui, is usable, but perhaps a different toolkit can be used, or even a terminal emulator to run vim/emacs might be possible...

Finally, I'd love to improve the dirt sampler by backporting the missing features from superdirt/superdough, and it would be nice to support the new mondo notation too. But that would be a story for another day!

Feel free to open an issue if pluguzu doesn't work for you!
Take care:)

2 Likes

Pluguzu now supports the new mondo notation, for which I managed to parse into Tidal patterns through the new tidal-mondo package. This is more flexible than using tidal-parse, as it lets us support custom expression like let bindings. I'm excited by this new development as it brings Tidal and Strudel closer, for example we can now have sound selection pattern like bd:<1 2>, along with the local function chaining feature, e.g. s [bd (sd # delay .5)].

I'm also working on integrating the new dough synthesizer to replace dirt: pluguzu#13. This is also very exciting as it enables playing melody out of the box using the basic oscillators, and I'm looking forward adding sample based pitch modulation to play instruments like a piano.

Cheers!

3 Likes

The changes to support the dough engine are now merged! In order to re-use the strudel soundmaps locally, I proposed to use a configuration files to indicate the local directory that way: pluguzu.json.

Cheers!

2 Likes

Hello, happy new year!

Here is a change to simplify pluguzu by using a fixed cycle count instead of continuous arcs over the whole project. Previously, the events were rendered as needed, and while it allowed the patterns to play infinitely, this was complicated to do efficiently. This also caused annoying delays when seeking quickly, especially with multiple instances running in parallel. So what I'm proposing to do is to process the events statically for a fixed duration and loop over them.

This prompted me to revisit the cycle position implementation to match the host transport, and the new code now properly support bpm modulation by using a tolerance threshold to make the sliding range continuous. This part remain complicated and I wonder if it wouldn't be better to use a midi sync instead when available.

Anyway, I'm looking forward to integrate this modification, and I'd be happy to get feedback before merging the PR:

Take care:)

2 Likes

Hello folks,

I tinkered with implementing a MIDI based triggering system to start the cycle on external note events, like the OP1 "finger sequencer" or the shaperbox "midi trigger mode". At first, I made this feature so that we can control the start of the cycle using a MIDI lane. This was necessary after the recent fixed cycle implementation. But I now realize that there are two main usage for pluguzu:

  • Synchronized to an external transport, e.g. a DAW, where the transport can seek to arbitrary location. In that case, it is necessary to perform the events from a static loop (using a fixed cycle count) to avoid re-rendering the events during playback.
  • Standalone with the internal transport, where the time goes strictly forward. In that case, it is fine to render the events continuously, without fixing the cycle count.

Thus, I re-worked one more time the transport implementation to handle both cases, including the option to trigger the pattern using MIDI events:

This is a bit tedious, but I think its worthy and the result is quite fun to play with. For now, this change adds basic support for the mt pattern modifier to select which events are played when a note-on event is received. Next, I'd like to figure out how to quantize the trigger starting time, to help keep the patterns somewhat synced. Then it should also be possible to have a global midi trigger, that could offset the notes pitch, I guess a bit like what the OPZ is doing...

The feature seems to be working as expected, and it's quite fun to remix patterns using a midi keyboard, but I'll play test it for a while and review it again before merging. After that, I think it will be time to make the first release and publish a video/manual to explain how to use pluguzu.

As usual, I'd be happy to get feedback and discuss future development, like perhaps implementing a different editor while keeping the transport logic...
Anyway, that's it for today, take care!
-Tristan

1 Like