Close

Making Fluxly, Part 2: The Software

A project log for Real World Fluxly, Physics Looper

A hardware implementation of Fluxly, a software musical physics looper in which you create new instruments by spinning colorful fluxum.

fluxlyFluxly 09/08/2018 at 19:280 Comments

Fluxly is written in C++ and uses the openFrameworks toolkit for creative coding. openFrameworks is aimed at making coding easier for artists and designers and provides convenient libraries or addons that provide an embarassment of riches for someone willing to take it on. Fluxly uses the built-in OpenGL capabilities of openFrameworks, and the OfxBox2d port of Box2D and danomatika's libPd addon.

All of the hard work of the sound synthesis is done in the embedded Pure Data patch, the Yak Shaver Engine called Yakshaver.pd, which you can download and open using the freely available Pure Data.

There are a few parts to the patch: an input stage, the Yak Shaver engine, and an output stage, which handles panning and reverb. There are also the "scopes" that are arrays that hold the data of the sample so they can be rendered in the app. A block diagram looks like this ("Ofx" below refers to the openFrameworks app that the patch is talking to):

The main interface to the app has the four "subunits" at the top, an interface for testing the on/off and tempo controls, and a section at the bottom for loading the default values. Clicking on the messages to the right will load different samples into the 8 yak shaver channels: 

The Yak Shaver engine makes extensive use of send and receive blocks (the "s" an "r" blocks) as well as throw~ and catch~ blocks, which are the audio signal equivalent. The "r" or receive blocks here will catch messages sent from within the patch or from the openFrameworks app.

Each of the Yak Channels (there's 8 of them) loads a WAV file into a buffer and plays it back as long as the on/off toggle is on. The tempo (marked "multiple" here) controls how fast the file is played back. The openFrameworks app sends a message to this inlet every time the angular velocity of one of the Fluxum circles changes. If the app sends a message to the "filename" inlet a new file is read into the buffer.

Each of the voices is panned in the final output depending on the X coordinate of the Fluxum looper. This subunit of the output stage handles the panning of each channel:

Each of the panned outputs of the 8 channels are added together and run through the Pure Data "Freeverb" processor. The inputs are sent as a message from the app depending on the rotation of the white Fluxum in each scene. The output is toggled on or off when the sample selector is chosen.

Recording is handled by the input stage, which uses Pure Data's analog to digital converter to read in microphone audio and save it to a buffer. When the stop button is pushed a message is sent and the buffer is trimmed to size and saved to the app's documents directory. Right now the limit is about 10 seconds (400000 samples at 44.1kHz, as seen in the "resize" command upper right), but that could easily be changed if there's interest in longer samples.

The audio output is also sent to the "scopes" subunit, a group of arrays that are sent back periodically to the main app and used to draw the waveform on the screen.

One of the benefits of using openFrameworks is that it provides a simplified framework for writing your app. Anyone familiar with the "sketching" approach of Processing or Arduino wil recognize an openFrameworks app: it consists of a setup() function called once, an update() function called repeatedly, and a draw() function called at a certain framerate. The draw() function should be as lean as possible, focused just on things that need to be done to draw a frame of the screen play. The update() function is where any number crunching should be done. There are also convenient callbacks for handling user interface events like touches.

Fluxly uses two openFrameworks addons: ofxPd as a wrapper around Pure Data and the Yak Shaver patch, and ofxBox2d which provides the physics model. Here's an illustration of how they interact:

Discussions