Nemisindo Engine is an asset for Unity featuring a fully procedural sound effect models (all sounds
generated on the fly,
no stored samples) capable of generating engine sounds. This model is implemented as a
Native Audio Plugin and can
generate sound
effects in real time, completely procedurally. The plugin offers an interactive UI with 14 parameters and 16
model presets.
The model exposes an API to change the parameters of the sound effect at runtime, hence the parameters can
be
linked to any in-game events, which can lead to organic and dynamic sound scenes.
The model is written in C++ wrapped in a custom UI.
The plugin is loaded as audio effects in the mixer channel and the audio signal is passed to the
audio source object mapped to that mixer channel.
The plugin audio parameters can be controlled in real-time using the model's functions interfacing with the
unity C# scripting API.
Supported Target Platforms: Windows (x64 & x32), MacOS, Android
Supported Unity versions: 2018.4.36f1 or later.
Included models: Engine
Import from Unity Asset Store: After purchasing the plugin from the asset store, click on add to my
assets. To use the plugin in a project,
click on open in unity from the popup on the asset store webpage. Once you've located Nemisindo Engine in
your package manager,
you can add it to your project by downloading and importing it from the package manager.
Import as custom package: If importing the package as a file from your machine, click on
[Assets] -> [Import Package] -> [Custom Package...] and select the file.
Make sure everything is selected, then click "Import". Once you've imported it into unity you can also view
the plugin
listed in the package manager. Refer to this
article for
more information on how to add new packages to your package manager.
The resultant asset folder "Nemisindo Engine - Procedural Sound Effects" contains three folders: "Plugins",
"Demo", and "Scripts".
The "Plugins" folder contains a set of .dll files for Windows, a set of .bundle files
for
MacOS, a
set of .so files for Android.
The "Scripts" folder contains C# scripts for UI, Serialisation and Control.
The "Demo" folder contains different scenes for testing each plugin.
Important file list:
.bundle (macOS) or .dll (Windows) or .so (Android) file: This is the
actual Native Audio Plugin. Note: Unity requires the audio plugin to be named starting with
audioplugin_ so do not rename the plugin file name.
/scripts/Editor/Engine_UI.cs: This is the C# script for the UI. Do not change existing
code or it
might break the UI. However towards the end of this file there is a presets section and you can save
your own presets in
here. You can find instructions for that towards the end of this document.
/scripts/Editor/audioplugin_Engine_UnityScript.cs: This is the serialisation script. The
main purpose of this script is
to enable data serialisation between the UI and the DSP core of the plugin via audio parameters. Kindly
do not make
any changes to the script.
/Scripts/Engine_Controller.cs: This is the controller script. This is created for
conveniently
interacting with the plugin and changing its parameters using the unity scripting interface. Each plugin
has a set of
functions that can be used to control the sliders, triggers, and dropdown boxes in the plugin. Note: The
controller
scripts can be added as a component to any object. It can be found under the nemisindo submenu under
when you click
on add component or from the menu bar at [Component] -> [Nemisindo].
/Nemisindo_Audio_Init.cs: This is the audio initialisation script. Add this script to at
least one
audio source attached to every audio mixer to enable sound from the Native Audio Plugin. This can be
accessed from
the nemisindo submenu under the component menu [Component] -> [Nemisindo].
To add a plugin to a mixer channel:
Make sure the "Nemisindo Engine - Procedural Sound Effects" folder is in your "Assets" folder.
Inside the [Audio Mixer] tab, create a new mixer if one does not already exist. Refer
here for more information about the Unity
Audio Mixer.
If the Nemisindo Engine effect is not already in the mixer, right click near on [Attenuation]
in the mixer channel strip and click on [Add Effect Before] then select [Nemisindo Engine] to add it to
the current mixer. Alternatively you can click on the [Add...] button at the bottom of the channel strip
and select the required plugin.
The Engine plugin contains 14 parameters to shape the plugin's sound. Once a model is added to the mixer
channel,
click on [Nemisindo Engine] on the mixer strip, to view the plugin UI in the [Inspector] window.
Every plugin has a set of audio parameters, a plugin instance slider, and a preset
selection
drop down menu.
This plugin has continuous output, i.e. it does not require triggering to sound (like a gunshot or footsteps
would).
The parameters of the Engine model as viewed in the [Inspector] window:
To hear sounds from the model:
Create an audio source and route
its output to the
mixer channel in which the plugin is loaded into.
Add a new Component to that audio source and from the list of Components select Nemisindo and load the
Audio Init script
from the list. This enables audio from the Native Audio Plugin to pass through the respective audio
source. Note: Every
mixer channel with a Native Audio Plugin requires a new audio source and an Audio Init
Component
for seamless integration.
Now run the game by clicking on the play button. Inspect [Nemsindo Engine] effect in the mixer, allow
[Edit in Playmode]
and adjust the RPM slider to hear the engine. You can then dynamically adjust plugin parameters and
select
presets during runtime.
Attaching the model to in-game events through Unity's scripting API:
Open /Demos/Nemisindo Demo Scene
In this demo, the setSpeed() and setFuelMix() model functions are linked
with the
OnMouseDrag() for the cube game object. This linkage is shown in
Scripts/Engine_Controller.cs.
This means that the Engine model's sound characteristics will be changed by dragging the cube around the
screen while
the game is running.
More information on the functions exposed in the Engine model's API can be found later in the API
section
of this documentation.
As mentioned in the previous section, the Engine model provides an API to change the sound parameters at
runtime through Unity's
scripting API.
This makes linking parameters to in-game events very easy.
In your C# script, make sure you have
using System.Runtime.InteropServices
at the top of the file to enable communication with the plugin. To access the setSpeed() model
function, use the
following code snippet inside the Engine_controller class in
Scripts/Engine_Controller.cs.
where setSpeed() alters the RPM parameter of the Engine model.
A list of functions exposed by the Engine model for use in scripting can be found in
Scripts/Engine_Controller.cs.
The are described in more detail in the API section of this documentation.
If you want to import multiple functions, add another similar block right after the previous import with the
required function
name. You can import multiple plugins and call their respective functions if needed. The following snippet
demonstrates importing
setSpeed() and setExhaustShape()
In the following example the setSpeed() and setFuelMix() Engine functions
are altered
as a function of the mouse position. Note that at the top of the Engine_controller class,
setSpeed()
and setFuelMix() are imported:
using UnityEditor;
using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.SceneManagement;
public class Engine_controller : MonoBehaviour
{
#if UNITY_IOS
[DllImport("__Internal")]
#else
[DllImport("audioplugin_Engine")] static extern float setSpeed(float channel, float value);
#endif
#if UNITY_IOS
[DllImport("__Internal")]
#else
[DllImport("audioplugin_Engine")] static extern float setFuelMix(float channel, float value);
#endif
// GetMouseAsWorldPoint() defined here
void OnMouseDrag()
{
transform.position = GetMouseAsWorldPoint() + mOffset;
setSpeed(0, Math.Abs(transform.position.x/5));
setFuelMix(0, Math.Abs(transform.position.y/5));
}
}
Model parameters can be get and set through either their index or directly through their name.
Access parameter through its index:
The Engine model has 14 parameters, and each parameter can be accessed through its respective index (0 - 13).
Every Nemisindo model is provided with setFloatValue(int channel, int index, float value) and
getFloatValue(int channel, int index) functions.
setFloatValue(int channel, int index, float value);
getFloatValue(float channel, int index);
Channel: the current plugin instance, which can be explicitly mentioned by the
user.
There can be 32 different instances of any plugin running at once in your project.
Index: the index of the plugin parameter, the index numbers are outlined in
/scripts/Editor/audioplugin_Engine_UnityScript.cs.
Value: the value the designated parameter will be set to.
Example 1:
To set the "Speed" parameter (1st index) of the 0th channel (the first instance of the Engine model that you
add) to 0.8:
setFloatValue(0, 1, 0.8);
Example 2:
To get the "Speed" of the same channel (i.e. instance):
getFloatValue(0, 1);
Access parameter through its name:
Instead of using the parameter index to set the parameter values, you can import relevantly named functions to
access the
parameter values instead. The Engine model has 14 such functions as it has 14 parameters:
Speed: Speed of the vehicle, input value should be scaled between 0 and 1
MixCylinder: Mixes between the exhaust sound and the cylinder sound
setExhaustVolume(float channel, float value); //ratio between the cylinder and the exhaust sound
Exhaust Shape: Shape of the exhaust outlet
setExhaustShape(float channel, float value); //changes the shape of the exhaust
Cylinder Phase: Controls the phase of the cylinder sound, causing mild phase distortion, which affects
the quality of the signal
setCylinderPhase(float channel, float value); //changes the Phase of the cylinder sound
Cylinder Shaft Length: Controls the length of the cylinder shaft. Longer shaft lengths add high band
noise to the signal
setShaftLength(float channel, float value); //Controls the length of the cylinder shaft
Cylinder Shape/Size: Controls the volume of the cylider
setCylinderShape(float channel, float value); //changes the volume of the cylinder sound
Engine Block Isolation: Controls how well the engine block is isolated to prevent vibrations, higher
values mean more intense vibrations
setBlockIsolation(float channel, float value); //changes the intensity of engine block isolation
Fuel Mix: Different fuels have effect on the sound of the engine. This fuel mix slider changes between
different fuel types
setFuelMix(float channel, float value); //changes between different fuel mixes making the engine agressinve or calm
Aggression: Controls the aggressiveness of the engine sound
setAggression(float channel, float value); //changes the agression intensity of the Engine sound
Exhaust Filter: Adds a resonant filter to the exhaust sound
setExhaustFilter(float channel, float value); //changes the resonant peak of the exhaust filter
Engine Character A: This is a Sawtooth wave, source A of the engine
setCharacterA(float channel, float value); //changes the volume of the input sawtooth
Engine Character B: This is a Triangle wave, source B of the engine
setCharacterB(float channel, float value); //changes the volume of the input Triangle
Engine Character C: This is a Sine wave, source C of the engine
setCharacterC(float channel, float value); //changes the volume of the input Sine
Note: All of the functions mentioned in this section are imported in the way described in the previous
"Scripting" section.
The Engine model contains 16 presets accessible form the preset drop down box in the plugin UI.
You can also add your own preset to the UI in the following way:
In the plugin’s UI script /scripts/Editor/Engine_UI.cs, at the bottom you can see how the
default presets have been
added. Add the name of your new preset inside the curly brackets of the following snippet:
Engine_parameter_options = new string[] { }
Then inside the following snippet add your own preset values:
if(Engine_prevPreset != Engine_Presets) { }
Best practice is to copy code from another preset and paste it towards the end of the list
of presets and change the required parameter values. The following example shows adding a preset with the
name "The New Preset".
The Engine model can be processed and spatialised just like any other sound, using Unity's built in effects.
You can apply post processing effects to the Engine model by loading effects after the [Nemisindo Engine]
model in
the mixer channel.
The smaller upper image above shows multiple effects loaded in after the [Nemisindo Engine] model. The
larger image
shows all the effects' parameters viewed in the [Inspector] window.