Opium

Opium

Opium is a modular software synthesizer developed for 64k intros and was used in Tensile. After writing my first software synthesizer for Wheels Within Wheels, which featured a classical hard-wired synthesizer architecture, I wanted to explore a more modular approach into synthesis.

Opium is based around the concept of operators, each one performing a single task, very similar to modules in a modular synthesizer. Operators are responsible for generating and processing both audio and control signals. Each operator generates a single output signal and takes signals from multiple inputs. Operators are connected together to generate complex audio signals. Opium provides the following operators:

  • Band-limited virtual-analog oscillators (sine, saw, square, triangle)
  • Frequency modulation oscillator
  • Karplus-Strong oscillator
  • Padsynth oscillator based on inverse FFTs
  • Noise source
  • Waveshaping and distortion
  • State-variable and biquad filters
  • Modulation sources including ADSR envelopes and LFOs
  • Auxiliary operators to performa mathematical operations
  • Compressor and limiter for dynamics processing
  • Effects processors including delays, reverb and glitch effects

To minimize the size of the synthesizer engine, I have opted to use plain C code. Audio is processed in buffers of 32 samples to allow using SIMD and to generally reduce the function call overhead. The engine uses a stack-based approach, where each operator pops the input signals from the stack and pushes the output back to the stack. The operator graph is reduced into a serial list of operations. This allowed to keep the code for the runtime engine very small and simple.

During music composition, Opium is run as a VST plugin inside a digital audio workstation. The plugin is developed on top of the JUCE framework and features a graphical interface for editing the synthesizer patch. MIDI data is used to trigger the instruments. To export a song for use in a 64k intro, the plugin allows to record incoming MIDI data and generates a C header file containing all the note and patch data in a form that allows for good compression.