Easy and efficient audio synthesis in C++

Related tags

Audio Tonic
Overview

Tonic

Fast and easy audio synthesis in C++.

Prefer coding to patching? Love clean syntax? Care about performance? That's how we feel too, and why we made Tonic.

//Tonic is a collection of signal generators and processors
TriangleWave tone1 = TriangleWave();
SineWave tone2 = SineWave();
SineWave vibrato = SineWave().freq(10);
SineWave tremolo = SineWave().freq(1);

//that you can combine using intuitive operators
Generator combinedSignal = (tone1 + tone2) * tremolo;
        
//and plug in to one another
float baseFreq = 200;
tone1.freq(baseFreq + vibrato * 10);
tone2.freq(baseFreq * 2 + vibrato * 20);

Here look. With Tonic you can create an awesome synthesizer with just a couple lines of code.

ControlXYSpeed speed = ControlXYSpeed().x(addParameter("x")).y(addParameter("y"));    
outputGen = RectWave().freq(100).pwm( 0.1 + (SineWave().freq(0.1) + 1) * 0.1) * SineWave().freq(1) >> LPF12().cutoff(100 + 600 * speed);

This code creates a rectangle wave oscillator, modulates the timbre of that oscillator by a sine wave, adds some slow tremelo, and sends it through a filter. On top of all that, it maps mouse speed to the cutoff frequency.

You can browse more synth examples here

Example Projects

Tonic comes with several example projects, found in the "examples" directory. We plan to add more demo projects for Windows and Linux in the future.

  • Several example synth patches in Demo Synths
  • Standalone example using RTAudio for building a non-interactive synth patch that runs from the command line
  • iOS example for making synths on your iPhone/iPad.

See ofxTonic for examples in openFrameworks.

Development

If you are interested in contributing to Tonic, please visit our Wiki and read the guidelines.

Comments
  • adding Cmake functionality

    adding Cmake functionality

    added CMakelists based on https://github.com/arunoda/cmake-boilerplate.

    mkdir _build
    cd _build
    cmake ..
    make
    

    will compile the lib and the standalone example, no iOS yet

    opened by andik 45
  • Windows port: Visual Studio projects for TonicLib and StandaloneTonicDemo

    Windows port: Visual Studio projects for TonicLib and StandaloneTonicDemo

    Release build works; there's an odd stack-overwriting crash in the Debug build which is worth looking into further, since it seems to be triggered by the debug runtime's memory guards.

    opened by Dewb 32
  • Smart pointers, sample tables, ring buffer for input processing

    Smart pointers, sample tables, ring buffer for input processing

    This is the same pull request as before, with fixes for all the demos and more illustration of the new features.

    Smart Pointers

    • Templated reference counting smart pointer TonicSmartPointer that is used instead of duplicate code in several places
    • BufferFiller and all its subclasses are now true Generator subclasses wrapped in smart pointers, and can also be used as Generators (see SynthsAsGenerators.cpp for example)
    • Synth no longer needs to be directly heap-allocated now that it's wrapped in a smart pointer. All demos and objects handling Synth instances now store as value rather than pointer.
      • Default constructor for Synth uses a passthrough generator, so uninitialized instances will produce no output

    Sample Tables and Input

    • Using a new class SampleTable to wrap instances of TonicFrames with shared data access, so the same data can be accessed in multiple places.
    • TableLookupOsc uses these to provide the lookup table. Can be provided externally (ArbitraryTableLookupSynth) or by a subclass (SineWave).
    • RingBuffer is a very simple ring buffer with over/underrun detection, based on SampleTable. Can be used to acquire/process input from a mic, etc (see the input demo - it will glitch out in the simulator fairly quickly, but that's a known simulator bug).

    Misc

    • TonicDictionary is an easier way to work with std::map for storing/retrieving objects keyed by strings.
    • Mutexes removed from Generator level for performance reasons, no hot-swapping supported right now. Currently living in BufferFiller
      • Another approach is in this branch. Uses smart pointer for SynthContext, which owns the mutex and passes down to Generators. This approach needs review. @Dewb would you mind providing some feedback here? We can chat about it offline, too.
    opened by ndonald2 13
  • Why does RampedValue_::updateValue set finished to false?

    Why does RampedValue_::updateValue set finished to false?

    I was expecting RampedValue::setValue to result in a smooth ramp back to the target, rather than a hold at the value being set. Is there a precedient in some other system (Pd maybe?) for setValue on a ramp de-activating the ramp? Seems more intuitive to me if both setTarget and setValue operate more or less the same. In any case, RampedValue isn't idiot-proof, and I'd love it if we could make it more so.

    question Generator 
    opened by morganpackard 13
  • Merge development to master

    Merge development to master

    The current state of the development branch is pretty stable, IMO. I'd like to get it into master soon-ish.

    The primary changes are:

    • Windows demo(s)
    • Universal smart-pointer usage for Synths
      • Smart pointer base class
    • Input processing via RingBuffer
    • Globally-registered sample tables
    • Smart pointer pass-by-value fixes
    • Multiple other fixes, some fairly critical

    @Dewb if there are still any loose ends for Windows that you'd like to get in before this goes to master, can you tie those up (ideally in the next few weeks)? Thanks.

    Linux build configuration is getting closer but still needs some attention. Personally I'd prefer to put that off til a future merge in the interest of continuing to move things forward.

    opened by ndonald2 12
  • Mp control switcher advance trigger

    Mp control switcher advance trigger

    In addition to accepting an "index" parameter, controlswitcher now accepts an "advanceTrigger" parameter, which increments the index.

    opened by morganpackard 9
  • Add hooks for UI notifications of changed Tonic values

    Add hooks for UI notifications of changed Tonic values

    I've started working on this in the MP-ThickLeap3 branch. Here's my plan:

    To Synth, add the following methods ControlUIMessenger addUIMessenger(string name); void addUIMessageResponder(string name, UIMessageResponder* resp);

    UIMessageResponder is an abstract class with one method, which is called (on the UI thread) when a value changes. A lambda function would be better, but I don't think oF is using C++11 yet. Might be worth adding a C++11 preprocessor macro and giving the option to add a lambda instead of an object pointer.

    ControlUIMessenger is a ControlConditioner which can store a UIMessageResponder.

    The end result of all of this is we can have ControlGenerators in our signal chain which contain callbacks which are set by UI code. A couple things to figure out:

    • How does the UI thread actually trigger the callbacks?
      • My first thought is to add a uiTick method to Synth, and have the UI call this on every frame.
    • How can we support ControlUIMessengers that aren't part of the regular signal chain?
      • Maybe we just don't. It's assumed that the messengers need to be part of the generator graph.
    • It would be nice if any ControlGenerator could just have a exposeToUI(string) method. This would take some thought to work out though, since it would mean we wouldn't be able to just call a method on the Synth to register the messenger.
    opened by morganpackard 9
  • ControlInputList

    ControlInputList

    This is what Nick was describing a while back -- an object that can take an arbitrary number of inputs, and an index which is used to control which of the inputs is used.

    Generator 
    opened by morganpackard 9
  • reserved identifier violation

    reserved identifier violation

    opened by elfring 8
  • Favor tick-based, rather than clock-based timing

    Favor tick-based, rather than clock-based timing

    Nick -- I'm guessing you're on this page already, but wanted to be explicit about it just in case. I like the idea of always tying timing of ControlGenerators (the Metro object you mentioned, for example) to tics, rather than using any sort of system-based clock. Advantages of this:

    • better cross-platform-wise
    • enables off-line rendering
    • stops with the debugger

    Looks to me like ControlGenerators which need to have a sense of advancing time can handle that just fine based on the hasChanged method, though I wonder if a more explicit tick method might be a good idea for controlGenerators too. ControlGenerator::tick() could return a ControlGeneratorTickStatus flag like ControlGeneratorTickStatusValueChanged or ControlGeneratorTickStatusNoValueChange.

    opened by morganpackard 8
  • ControlParameters send trigger signals on first tick

    ControlParameters send trigger signals on first tick

    context.forceNewOutput is set to true in the constructor, which results in the code below sending a trigger signal.

     inline void ControlValue_::computeOutput(const SynthesisContext_ & context){
          output_.triggered =  (changed_ || context.forceNewOutput);
          changed_ = context.forceNewOutput; // if new output forced, don't reset changed status until next tick
          output_.value = value_;
    }
    
    bug 
    opened by morganpackard 7
  • 'iostream' file not found error

    'iostream' file not found error

    When I try to compile the code as shown in your video, I get errors:

    /Users/scherbakov.al/Desktop/Tonic-master/examples/Standalone/TonicStandaloneDemo/main.cpp:11:10: 'iostream' file not found /Users/scherbakov.al/Desktop/Tonic-master/src/Tonic/TonicCore.h:15:10: 'string' file not found /Users/scherbakov.al/Desktop/Tonic-master/src/Tonic/ControlConditioner.h:15:10: 'vector' file not found

    (mac os 10.13.6, Xcode v.10.1) What could be the problem? I'm still quite a newbie. Thank you!

    opened by ScherbakovAl 3
  • The future of Tonic and what you think it should be.

    The future of Tonic and what you think it should be.

    I have put a lot of thought about how to revive Tonic and i think all work on future versions should continue in a separate repository. I don't have a figure for how many projects use Tonic as it is, but there are 57 forks. That means to me that many people had to adapt tonic to their needs but it also means that overall what Tonic has to offer is great. Because of that I'd give retaining compatibility with the existing code base the highest priority. My suggestion would be to reject any API breaking changes and new features. We should also try to avoid changes that effect sound synthesis maybe even when the synthesis would be more correct. Security related issue should still be accepted. I'd like to do something like this:

    • Rename Tonic to Tonic1
    • Create a project named Tonic2 which initially is a copy of Tonic1
    • Initially focus on creating benchmarks and tests for Tonic2 and hunt down problems
    • Find out what the users need. Dig through the forks.
    • Define goals based on those findings.
    • Reevaluate existing issues based on those goals and fix where it makes sense.
    • Here be dragons

    You are all invited to continue in your respective roles in the new repository. If you want a different role that's alright with me.

    I think your input would be very helpful. What do you think?

    question 
    opened by kallaballa 12
  • Add inputSource component

    Add inputSource component

    Would be great if there were a way for Tonic to process audio coming in to a system over Mic/Line inputs - as far as I can tell there is currently no way to do this with a component? If not, then adding an InputSource component would prove fruitful for those of us using Tonic for audio processing ..

    opened by seclorum 0
  • fix: first beat triggers with a delay when Tonic starts

    fix: first beat triggers with a delay when Tonic starts

    When Tonic has just started and context.elapsedTime < sPerBeat in ControlMetro, CM will trigger first not right away but with a sPerBeat-context.elapsedTime delay.

    opened by diviaki 0
  • Project file cleanup using latest Xcode.

    Project file cleanup using latest Xcode.

    I'm about to make a number of pull request, but realized the current upstream project file makes merging a pain, so first off I cleaned it out:

    • Team and Dev IDs have been removed (compiles OK)
    • Values where defaults are the same have been removed.
    • Project-level values are used instead of identical target level values.
    • Testability value added (by Xcode)
    • Background Audio property removed (by Xcode)
    • Mixed up deployment target now 7.1 for the whole project.
    opened by diviaki 0
Owner
null
A synthesis flow for hybrid processing-in-RRAM modes

reram-synthesis A synthesis flow for hybrid processing-in-ReRAM modes This project contains three parts: digital-synthesis: a synthesis flow for the d

Feng Wang 7 Nov 12, 2021
A small fast portable speech synthesis system

Flite is an open source small fast run-time text to speech engine. It is the latest addition to the suite of free software synthesis tools including University of Edinburgh's Festival Speech Synthesis System and Carnegie Mellon University's FestVox project, tools, scripts and documentation for building synthetic voices.

CMU Festvox Project 611 Dec 3, 2022
Audacity is an easy-to-use, multi-track audio editor and recorder for Windows, Mac OS X, GNU/Linux and other operating systems

Audacity is an easy-to-use, multi-track audio editor and recorder for Windows, Mac OS X, GNU/Linux and other operating systems. Audacity is open source software licensed under GPL, version 2 or later.

Audacity 8.5k Nov 30, 2022
Sneedacity (formerly Audacity) is an easy-to-use, multi-track audio editor and recorder for Windows, Mac OS X, GNU/Linux and other operating systems.

Sneedacity (formerly Audacity) is an easy-to-use, multi-track audio editor and recorder for Windows, Mac OS X, GNU/Linux and other operating systems. Sneedacity is open source software licensed under GPL, version 2 or later.

Sneed's Feed & Seed 869 Nov 28, 2022
A simple and easy-to-use audio library based on miniaudio

raudio A simple and easy-to-use audio library based on miniaudio raudio forks from raylib.audio module to become an standalone library. Actually, it w

Ray 61 Oct 5, 2022
PortAudio is a portable audio I/O library designed for cross-platform support of audio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.

PortAudio 758 Nov 28, 2022
Tenacity is an easy-to-use, cross-platform multi-track audio editor/recorder for Windows, MacOS, GNU/Linux

Tenacity is an easy-to-use, cross-platform multi-track audio editor/recorder for Windows, MacOS, GNU/Linux and other operating systems and is developed by a group of volunteers as open source software.

null 12 Dec 2, 2022
Oboe is a C++ library that makes it easy to build high-performance audio apps on Android.

Oboe Oboe is a C++ library which makes it easy to build high-performance audio apps on Android. It was created primarily to allow developers to target

Google 3.2k Nov 24, 2022
highly efficient sound library for the Gameboy Advance

The Apex Audio System (AAS) is a sound library for the GBA. It includes a highly efficient mixer, MOD playing routines and support for up to 16 channels. It is designed for developers using a GCC-based development environment. AAS uses RAW, WAV or *tracker 1-16 channel MOD files as input.

Ties Stuij 33 Nov 28, 2022
A command line and keyboard based strategy-game written in c++, where audio-input determines the AI-strategy and lays the seed for the map-generation.

Table of contents Dissonance Premise Installation Requirements Installation Quick-guide Detailed installation guide Usage Logfiles Tests Uninstall Kno

fux 25 Oct 25, 2022
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework for creating high quality desktop and mobile applications, including VST, VST3, AU, AU

JUCE 4.7k Dec 1, 2022
A simple C++ library for reading and writing audio files.

AudioFile A simple header-only C++ library for reading and writing audio files. Current supported formats: WAV AIFF Author AudioFile is written and ma

Adam Stark 673 Dec 3, 2022
A C library for reading and writing sound files containing sampled audio data.

libsndfile libsndfile is a C library for reading and writing files containing sampled audio data. Authors The libsndfile project was originally develo

null 1.1k Dec 1, 2022
C library for cross-platform real-time audio input and output

libsoundio C library providing cross-platform audio input and output. The API is suitable for real-time software such as digital audio workstations as

Andrew Kelley 1.6k Dec 2, 2022
C++ Audio and Music DSP Library

_____ _____ ___ __ _ _____ __ __ __ ____ ____ / \\_ \\ \/ / |/ \| | | | \_ \/ \ | Y Y \/ /_ \> <| | Y Y \ | |_|

Mick Grierson 1.4k Nov 26, 2022
Single file audio playback and capture library written in C.

A single file library for audio playback and capture. Example - Documentation - Supported Platforms - Backends - Major Features - Building - Unofficia

David Reid 2.5k Nov 25, 2022
simple audio mixer for native and web

?? auph ?? Trivial audio mixer API for native and web targets. Online Demo ⚠️ Work in progress! API is constantly changing. The native playback at the

Elias Ku 13 Jul 1, 2022
An OBS plugin that allows capture of independant application audio streams on Windows, in a similar fashion to OBS's game capture and Discord's application streaming.

win-capture-audio An OBS plugin based on OBS's win-capture/game-capture that hooks WASAPI's audio output functions (rather than the various graphics A

Joe Kaushal 2.9k Nov 28, 2022