This project is a case-study on “How you can produce some sounds from scratch by writing c# code in Unity3D”. It includes a custom class, called “ProceduralAudioController” which is actually a custom Audio Synthesizer with capabilities such as Tone Selection (and Mix), Amplitude Modulation and Frequency Modulation. The project also features a Circular Spectrogram, as well as a Complex Object that reacts to some of the Synthesizer’s parameters. Continue reading to find out more about the project!
The project’s core-tool is the ProceduralAudioController class. You may think of it as an audio synthesizer that resides within this Unity project. The class makes use of the “OnAudioFilterRead()” function (view documentation here), which enables you to treat audio data as an array of floats. So, by applying some quite simple mathematics at this low level of data flow, you can (theoretically) produce any sound or make any audio filter you like.
The Audio Synthesizer’s functionality can be summarized as follows:
- Tone Generation (Master Volume and Frequency)
- Tone Selection / Mix (Sinus Wave, Square Wave, Saw Wave)
- Amplitude Modulation
- Frequency Modulation
The Project’s overall functionality also includes:
- A Spectrum Visualizer: a system that analyses the produced sound’s frequencies and visualizes them in a circular array of cubes.
- A Complex Object that reacts to some of the audio generation parameters.
The Audio Synthesizer can be used in a number of ways (from the aspect of control – flow):
- Control the Synthesizer manually, by setting the values yourself in the editor
- Let the Synthesizer Control itself, by using the Auto Play feature.
- Control the Synthesizer externally, by using other scripts to control the audio parameters.
- Use the synthesizer’s public parameters to “drive” (control) the parameters of other scripts (inverse control)
- The ProceduralAudioController script is not (currently) optimized for performance. It will most probably work fine, but if you use multiple instances you may experience audio – clicks and / or other bad effects.
- This project will not work with WebGL builds. That is because Unity’s WebGL builds have a limited number of audio features, which do not (currently) include the “OnAudioFilterRead()” function.
When you open the project with the Unity Editor and hit the Play Button, you will be able to hear the Synthesizer’s audio output, as well as see the corresponding Spectrogram in your Game window. If you select the “_ProceduralAudioGameObject”, you will then be able to see the audio parameters (in the inspector), edit them (using the sliders) in real time and thus explore the tool’s functionality. The following section is an analytical presentation of these control parameters.
- Auto Play: Boolean parameter that determines if the user has control over any of the other parameters, or if the system works in a demo mode. (See next section for more details)
Volume / Frequency
- Master Volume: The master Volume 🙂
- Main Frequency: The main frequency of the produced sound
The overall tone of the produced audio signal is actually a mix of three separate audio sources: a Sinus Wave, a Square Wave and a Saw Wave. You may use the following controls to adjust the mix.
- Use Sinus Audio Wave: Boolean parameter that determines whether or not to use a Sinus wave in the mix.
- Sinus Audio Wave Intensity: Float value that determines the intensity of the sinus audio wave.
- Use Square Audio Wave: Boolean parameter that determines whether or not to use a Square wave in the mix.
- Square Audio Wave Intensity: Float value that determines the intensity of the square audio wave.
- Use Saw Audio Wave: Boolean parameter that determines whether or not to use a Saw wave in the mix.
- SawAudio Wave Intensity: Float value that determines the intensity of the saw audio wave.
- Use Amplitude Modulation: Boolean parameter that determines whether or not to apply amplitude modulation on the produced sound.
- Amplitude Modulation Oscillator Frequency: Float parameter that determines the Amplitude Modulation Oscillator’s frequency.
- Use Frequency Modulation: Boolean Parameter that determines whether or not to apply frequency modulation on the produced sound.
- Frequency Modulation Oscillator Frequency: Float parameter that determines the Frequency Modulation Oscillator’s frequency.
- Frequency Modulation Oscillator Intensity: Float parameter that determines the Frequency Modulation Oscillator’s intensity.
These parameters are for external use, only (they are calculated, based on the previous parameters and time-dependent functions). So, actually they do not control the Synthesizer, but can be used to “drive” (control) other scripts’ parameters. In this project, they are used to control the _ComplexObject’s shape over time, in relation to the audio controls.
- Amplitude Modulation Range Out: The Amplitude Modulation Oscillator’s current value (range 0 to 1)
- Frequency Modulation Range Out: The Frequency Modulation Oscillator’s current value (range 0 to 1)
This Project is part of a Group of case – studies (including the Procedural Water Surface and Procedural Landscape), hosted at my github account, in the “Unity3D-Coding-Examples” repository. You may, of course, download, clone or fork the repo to experiment on (or build upon) any of them. I am trying to keep a clear and helpful documentation in the readme file, and keep the code as best commented as possible.
This specific project’s files are located in this folder: https://github.com/konsfik/Unity3D-Coding-Examples/tree/master/3-Procedural-Audio.
The following code is the “ProceduralAudioController” class. It depends on definitions of other classes, as well, so it will not work if you just copy and paste it in your project. It is posted here for preview – purposes only and in order to find the complete set of necessary scripts, you must visit the project on github (follow the links provided above).
As always, feel free to ask any questions / or post a comment!
The commenting in this code is legendary. THANK YOU!!!
Thanks @d3eds! Glad to hear that 🙂