Rust Audio

Announcement: loopers, a graphical live looper for jack

Last year, frustrated with the complexity and instability of the existing open-source live loopers (like mobius and sooperlooper), I started developing one myself: loopers. And of course I decided to write it in Rust. After picking the project back up this summer, it’s now pretty much usable (although still missing a few key features), and I’ve decided it’s time to open it up.

For those unfamiliar with live looping, the idea is to allow a single musician to create complex arrangements in a live setting by building up overdubs on top of a continuously looping track. Originally loopers used simple tape delay devices, but soon more sophisticated looping devices were released, supporting multiple loops of different lengths, effects, quantization, and more powerful control schemes.

Loopers implements many of these features, and pairs them with a sophisticated GUI that makes it easy to understand the state of the system. It looks like this:

Currently it runs as a jack application (only supported on Linux at the moment, although probably would not be hard to support MacOS as well), using rust-jack. Hopefully it will be possible to make it into a plugin as well.

The GUI is completely custom, drawn via rust-skia and hosted in an sdl2 window. Communication between the audio thread, the GUI, and the looper backends is done with a bounded crossbeam-channel.

The code is over at https://github.com/mwylde/loopers, which also has more information and documentation. I think there’s some interesting ideas in the code around how to do complex multi-threading and UIs for real-time audio applications in Rust, and I’m sure a lot of stuff that could be improved.

Working on this has made me very excited for the future of Rust audio, but clearly there are still a bunch of gaps. Lacking a real GUI solution is probably the biggest. I tried several of the existing GUI crates (druid, azul, conrod, orbtk) and found that none of them were suitable for real-time audio applications. But at the same time, it would be nice to be able to rely on pre-built widgets for things like text editing and configuration.

11 Likes

Neat! IMO the biggest piece of software that is glaringly missing in the free software world is a live performance/improvisational composition tool like Ableton’s Live view. Have you considered making Loopers into that kind of application with a grid of samples? There is one project, Lupp, which does that but it hasn’t had much active development since its initial release.

I think using JACK will only go so far for interoperating with DAWs to achieve the deep integration Ableton has between its conventional DAW view (Session view) and live performance/looping view (Live view). An idea I’ve had for a while was to make a standalone application that interoperates with Ardour by reading/writing Ardour session files. If you’re interested in pursing that, I’d recommend getting in touch with the Ardour developers for their input.

If you’re interested in making this cross platform, check out rust-portaudio and cpal. Using JACK via PortAudio is kinda clunky. PortAudio abstracts over different audio APIs so it can’t support JACK’s unique features and I don’t think it works well with JACK session managers.

If your ambitions are more modest, ignore all that and just do your thing.

@micahw This is awesome, thanks fror sharing.

Thanks for the kind words!

Neat! IMO the biggest piece of software that is glaringly missing in the free software world is a live performance/improvisational composition tool like Ableton’s Live view. Have you considered making Loopers into that kind of application with a grid of samples?

Currently I’m really focused on making it easy to use for practice / live performance use cases. I’m far from a Live expert, but as a performer (and primarily acoustic musician) I’ve found it hard to build a looping workflow that is natural for the kind of music I play. But I agree that having the ability to store and playback samples would be very interesting!

I think using JACK will only go so far for interoperating with DAWs to achieve the deep integration Ableton has between its conventional DAW view (Session view) and live performance/looping view (Live view).

I like Jack as a user because it kind of explodes the traditional DAW mentality, making it easy to interface with other plugins, instruments, and tools without requiring everything to live within a single application. So for example, as loopers has per-loop outputs users can easily build separate processing chains for each or even send them independently to a DAW and arrange it there. The downside is that it’s a lot of set up to get a good environment, and a lot of complexity. I have a series of scripts that get my default environment up and running, but that’s probably beyond what most musicians will be able to do.

Ultimately I’d like to make it available as a plugin as well, and it’s architected to make that relatively easy once the rust plugin stuff is further along (all of the jack-specific code is in a single crate).

It will be awesome that loopers can act as a Jack Timebase master but I think the rust-jack crate doesn’t support it yet.

Yes, that would be great. I haven’t explored that much, but I’d be interested in contributing support for rust-jack if needed.

Looks neat! If you’re interested in gaining users (and feature requests, bug reports, praise and complaints), you can announce it on several places, as documented here (quarterly release pact for FOSS, mostly Linux software).

I am a first time rust user. I succeeded to install it on my gentoo system and it seam to work. I cloned looprs’s source code from github, and when running ‘cargo install loopers-jack’, it goes well until:

 Compiling sct v0.6.1
error[E0658]: `#[doc(alias)]` is experimental
  --> /home/dom/.cargo/registry/src/github.com-1ecc6299db9ec823/sdl2-0.34.5/src/sdl2/clipboard.rs:32:5
   |
32 |     #[doc(alias = "SDL_SetClipboardText")]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #50146 <https://github.com/rust-lang/rust/issues/50146> for more information

error[E0658]: `#[doc(alias)]` is experimental
  --> /home/dom/.cargo/registry/src/github.com-1ecc6299db9ec823/sdl2-0.34.5/src/sdl2/clipboard.rs:46:5
   |
46 |     #[doc(alias = "SDL_GetClipboardText")]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #50146 <https://github.com/rust-lang/rust/issues/50146> for more information
<snip a lot of them>
error[E0658]: `#[doc(alias)]` is experimental
    --> /home/dom/.cargo/registry/src/github.com-1ecc6299db9ec823/sdl2-0.34.5/src/sdl2/video.rs:1748:1
     |
1748 | #[doc(alias = "SDL_GetVideoDriver")]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: see issue #50146 <https://github.com/rust-lang/rust/issues/50146> for more information

   Compiling gl v0.14.0
error: aborting due to 342 previous errors

For more information about this error, try `rustc --explain E0658`.
error: could not compile `sdl2`.

Should I report this issue as a bug on github, or is it some issue into my system like a partial sdl2 installation (libsdl2-2.0.12 is installed, I installed sdl2-gfx and ran cargo again and still get the same issue.).

I updated rust to 1.52.0 and all is going fine now.

It is very likely that Ardour 7.0 will feature the first iteration of clip launching ala Live/Bitwig/DP. I know this because I’m working on it right now (in C++ of course :slight_smile:

1 Like

I’m curious what you mean by “the complexity and instability of the existing open-source live loopers (like mobius and sooperlooper)”

The complexity comment is mostly about the workflow. Sooperlooper is very powerful, but doesn’t provide much help in figuring out how to effectively use it in a performance. Loopers aims to be closer to a hardware loop system in that respect. I mention instability because sooperlooper has crashed on me a bunch, which is not great in a performance setting.