An analog synth in C# for Unity
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Assets
ProjectSettings
Screenshots
.gitignore
README.md

README.md

Hello there!

I'm Wavy McFormface, and I'm here to help you make awesome procedural sounds and music at runtime 😜

Overview

Wavy McFormface is an analog synth that allows to to create and waveforms in real time.

Wavy offers a wealth of controls to edit and constomize your waveform. And, as if that weren't enough, you can also edit your waveform at runtime using Wavy's API!

Below we'll step through the install process, how to create a waveform, the parts of a waveform, and how to use the editor UI and API to edit/modify your waveform.

Install Wavy

This is pretty simple - all you need is the Wavy McFormface/Assets/Wavy McFormface directory at the root of your project. I realize the directory structure is weird - it's required by Unity. The most important directory in this entire project is the Editor directory. The Editor directory is special; Unity looks inside it for UI widgets and such. One pattern you could use to get Wavy ready to go is:

git clone git@github.com:bsgbryan/wavy-mcformface.git # Clones project to ./wavy-mcformface
cp -R ./wavy-mcformface/Assets/Wavy\ McFormface {YOUR_PROJECT_ROOT}

This will put the Wavy McFormface directory in your project's root directory - which is exactly what we want.

You may need to restart Unity for it to pick up that Wavy was added to the project.

Create your first waveform!

TL;DR

  • Tools -> Wavy McFormface -> New Waveform (or CTRL + ALT + SHIFT + W)
  • Add Wavy Mc Formface component to GameObject in scene
  • Add Audio Source component to same GameObject Wavy was added to
  • Play around 🙌

Details

To create a waveform simply select the Tools -> Wavy McFormface -> New Waveform Menu (or use the CTRL + ALT + SHIFT + W shortcut) and select where you'd like your waveform config to be saved. I'd recommend something like a Waveforms directory in your project root.

Once you click Save navigate to the created file. Note that a .asset file was created. This is important as assets files can be shared across multiple instances of Wavy McFormface scripts.

To start editing your waveform, simply create a new GameObject or find the existing GameObject you want and click Add Component. Then find the "Wavy Mc Formface" component and click it. Be sure to add an Audio Source component to your GameObject as well - without an Audio Source Wavy has no way to produce sound.

Scripts vs Assets

What is the difference between a script and an asset?

Assets

Wavy McFormface assets are called Configies and hold all the configuration data for a waveform. All the edits and update you make via the editor UI or API are maintained in the Configie.

Why? Because assets are not scene specific and changes to them persist during Play Mode. This is important because your scene has to be playing for the OnAudioFilterRead Unity API method to be called. The OnAudioFilterRead method is the hook Wavy uses to generate waveforms. You can read about OnAudioFilterRead here.

Since the scene needs to be in Play Mode for Wavy to generate waveforms we really need to our edits to waveform Configies to persist beyond Play Mode. Assets are the best way to achieve this. Since an asset exists outside a scene it gets updated whether Unity is in Play Mode or not. Using assets for Configies means that you can enter Play Mode and get your waveform sounding exactly the say you want. When you exit Play Mode all your work will persist because it was saved against the Configie - not the GameObject the script is attached to.

Scripts

Scripts are the logic that that uses a Configie to generate a waveform. Scripts get attached to GameObjects and require an Audio Source also be attached to the same GameObject as the script.

A script references a Configie (as is shown in the Configie and Master Volume section below).

Importantly, you can edit a Configie either by editing the asset directly, or by using the script - both editors do the same thing. Most of the time you'll likely use the script editor UI to edit the Configie while in Play Mode.

It's important to note that you can have multiple scripts reference the same Configie. In this case, a change made via the script editor UI will effect all script instances referencing the same Configie.

The Editor UI

There are several sections of the editor UI, each with their own purpose. Below we go through each section in turn.

Overview

Before diving into the details of each section, we'll cover some basics

Property types

Wavy McFormface has five types of properties:

  • AnimationCurve
  • Float
  • Integer
  • Range
  • Time

AnimationCurve, Float, Range, and Integer property types may be edited in real time while in Play Mode. Time properties may not be edited from Play Mode.

AnimationCurve properites are:

  • Envelope attack and decay curves
  • Harmonics
  • Frequency Limit
  • Wibble Wobble pattern curve
  • Noise pattern curve

Float properties are:

  • Master Volume
  • Sine, Square, Sawtooth, and Triangle Wave Volumes
  • Noise level

The single Integer property is:

  • Play Controls current octave

The two Range properties are:

  • Play Controls octave range
  • Noise variance

The Envelope attack/decay times as well as the Wibble Wobble Time fields are all Time values and may not be edited in real time while in Play Mode.

Enable/Disable

Any section with a checkbox (Hamronics, Frequency Limit, Wibble Wobble, and Noise) may be enabled or disabled. You can enable/disable while in Play Mode.

Configie and Master Volume

Configie and Master Volume editor UI section

Configie may not be updated in real time while in Play Mode

Master Volume may be updated in real time while in Play Mode

The top-most section is where you specify which Configie a script is using, and set the Master Volume.

To change which Configie a script uses, simply select a different one from the component chooser.

Wavy McFormface supports all four basic wave types:

  • Sine
  • Sawtooth
  • Square
  • Triangle

The volume level for each wave type can be specified individually. The Master Volume raises or lowers all wave type volumes uniformly, and can be used as a cutoff to make sure the overall volume output nevers get beyond a desired threshold.

IMPORTANT NOTE The editor UI enforces a range of 0.0 - 1.0 for the value of the Master Volume. The API, because of the way Unity works, does not. Do not ever specify a Master Volume level above 1.0 as doing so may cause damage to your audio equipment and/or your ears. This is extremely serious.

Wave Volumes

Wave Volumes editor UI section

These values may be updated in real time while in Play Mode

This section allows you specify volume levels for all four wave types independently - play around with these to create something awesome and unique!

IMPORTANT NOTE The editor UI enforces a range of 0.0 - 1.0 for each of these values. The API, because of the way Unity works, does not. Do not ever specify a wave volume level above 1.0 as doing so may cause damage to your audio equipment and/or your ears. This is extremely serious.

Play Controls

Play Controls editor UI section

This section looks complex, but it's really just three things:

  1. The octave range specifier
  2. The current octave slider
  3. The note grid

We'll go through each item in turn:

octave range

This value may be updated in real time while in Play Mode

The octave range specifies all octaves to render when Harmonics are active.

Wavy can generate a pure tone (a single note in a single octave) or it can generate multiple tones that play at once. Generating multiple tones that play at once typically sounds more natural and pleasent. Wavy gives you the freedom to select the range of octaves to render for Harmonics - giving you tremendous power to shape the sound and texture of your waveform.

If Harmonics are not active this value is not used.

current octave

This value may be updated in real time while in Play Mode

This slider selects the octave to use when generating your waveform. It is bounded by the values selected in the octave range.

note grid

The note grid is a collection of buttons allowing you to play your waveform to see how it sounds.

tap

The tap buttons roughly simulate tapping a key on a keyboard to play your waveform. The formula used to determine how long to play when tapping is as follows: attack + attack. The note is played for twice the attack time - this provides enough time for the note to get to full volume, with a sustain equal to the attack time. When attack + attack time has passed, the note stops playing and the decay takes over. The note volume fades out according to the decay time and AnimationCurve specified.

play

The play buttons simulates pressing and holding a key on a keyboard to play your waveform. The attack time and AnimationCurve are used to get the waveform to full volume. The waveform then continues playing until stop is pressed. When stop is pressed the decay time and AnimationCurve are used to lower the waveform's volume to 0.

IMPORTANT NOTE Only one note can play at a time. Pressing play on multiple notes will simply transition from the first note to the second - even though both buttons will say stop, only the most recent note selected will be playing.

Envelope

Envelope editor UI section

attack/decay AnimationCurves may be updated in real time while in Play Mode

attack/decay time values may not be updated in real time while in Play Mode

time values

The attack and decay time values specify how long their associated actions take to complete. Because of the way the waveform is generated at runtime, these values may not be edited while in Play Mode.

AnimationCurves

The attack and decay AnimationCurves give you absolute control over exactly how a waveform's volume raises and lowers over the time specified. The AnimationCurves may be edited in real time while in Play Mode - however, changes to attack will not be heard until the next play and changes to decay will only be heard until stop is pressed.

Harmonics

Harmonics without details editor UI section

These values may be updated in real time while in Play Mode

The Harmonics AnimationCurves allow you to specify how loud harmonic octaves should be relative to the current octave.

The grey bars behind the AnimationCurves show you where each rendered octave is at - making it easy to visually get an idea how loud each octave is.

Harmonic details

Harmonics showing details editor UI section

The Details section provides info on the volume level for each octave below and above the current octave.

IMPORTANT NOTE The volume range for harmonic octaves is bounded to 0.0 - 1.0. Since harmonic volumes are just AnimationCurves, this can be changed via the API. Do not change the default volume bounds for harmonic octaves. Doing so may damage your audio equipliment and damage your ears.

Frequency Limit

Frequency Limit without details editor UI section

This AnimationCurve may be updated in real time while in Play Mode

The Frequency Limit curve is like an advanced volume control for all rendered frequencies of your waveform.

The grey bars behind the AnimationCurve show you where each rendered octave is at - making it easy to visually get an idea how loud each octave is.

Using the AnimationCurve you can control the volumes of every octave and note rendered in your waveform to a high degree of precision.

Frequency Limit showing details editor UI section

The Frequency Limit details shows the exact volume level of each rendered octave.

The volume range is between 0.0 (completely silent) and 1.0 (full volume).

Wibble Wobble

This one is fun 🤘

Wibble Wobble editor UI section

The official name for this control in synth parlance is Pitch Bending, or portamento (usually using a Pitch Wheel) - but I didn't know that when I was building this plugin so I called it Wibble Wobble (which is more fun anyway).

The Wibble Wibble uses an AnimationCurve to specify how to bend you're waveform's pitch. The bend pattern repeats according the the Time units specified.

Noise

Ok... this one's a doozy 😁

Noise editor UI section

The Noise section has three parts:

  • variance
  • level
  • pattern (the AnimationCurve)

We'll go through each part in reservse order as that will make more sense:

pattern

This AnimationCurve defines the pattern by which a waveform should deviate from it's note over the course of a sample. This pattern will repeat for each call to OnAudioFilterRead (ie: sample). While this pattern does give shape and texture to your waveform, it is not the same as the Wibble Wobble pattern. This pattern is for providing suble texture changes and nuances in your waveform.

level

The level determines to what extent the pattern and variance distort the waveform. A value of 0 means the no distortion occurs. As the value increases, the waveform distortion becomes more intense.

variance

This range defines how far randomized noise points may deviate from the specified pattern. The "noise" provided by this control is a function of random deviations from the specified pattern, amplified by level.

A narrow variance range means the injected noise will only deviate slightly from the specified pattern. A wide variance means that more random noise deviations will be applied to the waveform as they will fall within the specified varaince range.

Additionally, you can control the tone of the variance by sliding the range up and down.

API

All properties available through the editor UI are also available via the API. For examples of API use, please see the Assets/Wavy McFormface/Examples directory (specifically the Scripts directory). These scenes are playable. To run them you will need the Standard Assets package installed.

Lerping

There are two different speeds that Wavy lerps at when animating between property values:

  • Slow: This lerp takes one full second to complete
  • Fast: This lerp takes one full sample pass to complete (1/48th of a second on desktop, 1/24th of a second on mobile)

All AnimationCurve properties lerp at the slow speed. This is to prevent audio artifacts like popping - which are caused by changing values too quickly.

Float properties lerp at the fast speed. This is because changes in these values can be animated faster without causing artifacts.