• Home
  • About
  • Site Policies
  • Contact

Designing Sound

Art and technique of sound design

  • All Posts
  • Featured
  • News
  • Interviews
  • Reviews
  • Tutorials
  • Resources
    • VR Audio Resources
    • Independent SFX Libraries
    • Events Calendar
  • Series Archives
    • Featured Topics
    • Featured Sound Designers
    • Audio Implementation Greats
    • Exclusive Interviews
    • Behind the Art
    • Webinar/Discussion Group Recordings
    • Sunday Sound Thought
    • The Sound Design Challenge

Making a Music System – Wrap Up

September 28, 2016 by Charlie Huguenard

mancala
Photo by Dawn Endico. Click image to view original.

Hey, cool. We’re making music! But it’s not really interactive yet. In this lesson, we’ll hook up the music system to parameters in the game. We’ll also make editing our step sequencer a little easier with some Unity editor scripting.

Game Parameters

A “game parameter” can really be any quantifiable value in the game, such as the player character’s speed, the camera’s position in the level, a non-player character’s attributes, or the player’s score. We can also combine these to derive parameters that are relevant to the music. If you’re familiar with implementing interactive sound, these parameters are synonymous with RTPCs, States, and Switches in Wwise or Parameters in FMOD.

Similarly, we have a lot of things we can change about the behavior of the music. We can turn on and off parts just like we could when using a collection of audio files. But since this is a note sequencer, we can do a few more things, such as change the tempo (without a change in pitch or articulation), shift the key, change the attack and release of the samplers, and transform the sequences in many ways. Let’s look at a couple simple examples.

Changing Tempo

Because this music system is based on triggering notes on instruments, we can freely change the tempo without any change in the sound of the notes themselves, just like using virtual instruments in a DAW. In this example, we create a script that takes a UI slider value in the range of 0.0-1.0 and scales it to a tempo range, like so:

public void OnSliderUpdate(float sliderValue)
{
  float tempo = _tempoMin + ((_tempoMax - _tempoMin) * sliderValue);
  _metronome.SetTempo(tempo);
}

(view source)

All that’s left to do here is to create a UI slider and tell its update event to call this function. For the sake of brevity, we won’t go over how to set up UI controls in Unity, but here is a great primer if you’d like to learn more about that.

When you play the demo scene, you should hear the tempo changing with the value of the slider in the game window.

Muting Sequences

Another common technique is to map the arrangement of the music to the intensity of the action in the game. That intensity value could be one value or a combination of many values from the gameplay systems. Using audio files, this would involve fading in or out. But since we’re using sequencers, we can simply stop or start playing notes in that sequence, preserving the tails of notes that were already playing. In the StepSequencer code, we check whether the sequence is currently suspended, and if so, we don’t report notes that would play.

public void HandleTicked(double tickTime)
{
  int numSteps = _steps.Count;

  if (numSteps == 0)
  {
    return;
  }

  Step step = _steps[_currentTick];

  if (step.Active)
  {
    if (!Suspend && Ticked != null)
    {
      Ticked(tickTime, step.MidiNoteNumber, step.Duration);
    }
  }

  _currentTick = (_currentTick + 1) % numSteps;
}

(view source)

Doing it this way means we keep the sequences in phase when one or more sequences is suspended.

To tie suspending sequences to our “intensity” parameter, we’ll create a way to map StepSequencer instances to a threshold. And then when our intensity parameter gets updated, we’ll check those mappings to determine which sequences should be suspended.

[Serializable]
public class SequencerIntensityPair
{
  public StepSequencer Sequencer;
  public float Intensity;
}

[SerializeField] private SequencerIntensityPair[] _sequencerIntensityPairs;

public void OnSliderUpdate(float sliderValue)
{
  foreach (var sequencerIntensityPair in _sequencerIntensityPairs)
  {
    sequencerIntensityPair.Sequencer.Suspend = (sliderValue < sequencerIntensityPair.Intensity);
  }
}

(view source)

And as before, we can hook this up to a slider in the UI. In the demo scene, you should hear parts turn on and off as you move the intensity slider around.

Step Sequencer Editor

Because we want to move a little faster when making our sequences, let’s take a look at some editor scripting and make the inspector a little prettier.

Custom Inspectors

Unity is an extremely flexible game engine and tool set, and at the heart of that flexibility is a modifiable editor. When you select a GameObject in the scene or project hierarchy, the inspector pane shows that object’s attached MonoBehavior scripts and their properties. If the default inspector layout isn’t suitable for your purposes, you can make your own using the Editor class and the CustomEditor attribute. For further reading, Unity has some great tutorials on editor scripting here.

Pretty Sequence Steps

By default, editing steps in our StepSequencer is a little clunky.

uglyeditor
Not so pretty, but we can fix that!

A nice improvement would be to have all the controls for the steps up front, instead of buried in a tree editor.

prettyeditor
Ah, that’s a little better.

To do that, first we need to hide the default editor for the steps in the StepSequencer.

// hide this field in the inspector. We'll be making a custom inspector for these
[SerializeField, HideInInspector] private List<Step> _steps;

(view source)

Then we can make our own editor for steps by overriding OnInspectorGUI.

List<StepSequencer.Step> steps = sequencer.GetSteps();

// Set the number of steps in the sequence
int numSteps = EditorGUILayout.IntSlider("# steps", steps.Count, 1, 32);

// Add or remove steps based on the above slider's value
while (numSteps > steps.Count)
{
  steps.Add(new StepSequencer.Step());
}
while (numSteps < steps.Count)
{
  steps.RemoveAt(steps.Count - 1);
}

// Draw the steps
for (int i = 0; i < steps.Count; ++i)
{
  StepSequencer.Step step = steps[i];

  // Draw all the step fields on one line
  EditorGUILayout.BeginHorizontal();
  EditorGUIUtility.labelWidth = 60;
  EditorGUILayout.LabelField("Step " + (i + 1), GUILayout.Width(60));
  step.Active = EditorGUILayout.Toggle("Active", step.Active, GUILayout.Width(80));
  step.MidiNoteNumber = EditorGUILayout.IntField("Note", step.MidiNoteNumber);
  step.Duration = EditorGUILayout.FloatField("Duration", (float)step.Duration);
  EditorGUIUtility.labelWidth = 0;
  EditorGUILayout.EndHorizontal();
}

(view source)

And there we have it. A much easier-to-edit sequencer.


Thanks for following along! We hope this series has been helpful. If you have any questions or comments, please post them below.

Filed Under: featured, tutorials Tagged With: adaptive music, game audio, interactive music, procedural audio, procedural sound, tutorial, tutorials

Comments

  1. Samantha says

    October 11, 2016 at 6:52 pm

    Thanks for the detailed post

  2. bsasproaudio says

    April 25, 2017 at 12:10 pm

    Awesome work, really easy to follow as Samantha says, really appreciate it!

  3. tyler says

    November 1, 2017 at 1:02 am

    EPIC tutorial series! – immensely grateful for the detailed walk-through / insights (espesh’ the “look-ahead” audio sync!) *humble bows*

Social Media

  • Twitter
  • YouTube

Posts By Month

#sounddesign on Twitter

#sounddesign

tunepocketTunePocket Music@tunepocket·
26 May 2020

Download royalty free gunshot sound effects, incl. one shot gun sounds, gun cocking sounds, gunshot with silencer, machine guns, and more #gunshot #sfx #sounddesign #videoediting #gamedev #royaltyfree https://t.co/bTTDQkveKF

Reply on Twitter 1265206307927162880Retweet on Twitter 1265206307927162880Like on Twitter 1265206307927162880Twitter 1265206307927162880
Reel2MReel2Media@Reel2M·
26 May 2020

At Reel2Media we are harnessing the power of smart speaker technology, to deliver cutting edge skills that solve problems and add value. To find out more, click here https://t.co/VAAw7vTW1V #sounddesign #smartspeaker #alexaskill #amazonalexa

Reply on Twitter 1265206269255847936Retweet on Twitter 1265206269255847936Like on Twitter 1265206269255847936Twitter 1265206269255847936
SoniKSoundLibSoniK Sound Library@SoniKSoundLib·
26 May 2020

Listen to #soundcloud preview of our next release! #np https://t.co/S3bxxrnqrh #audiopost #soundlibrary #soundediting #sounddesign #ambisonics #spatial #surround #ambience #roomtones

Reply on Twitter 1265204382779559936Retweet on Twitter 12652043827795599361Like on Twitter 12652043827795599361Twitter 1265204382779559936
asoundeffectA Sound Effect@asoundeffect·
26 May 2020

Want to know what the independent sound effects community has been up to? Hear the very latest SFX libraries here: https://t.co/OUBM2SqMoP #sounddesign #soundeffects #soundlibraries #indieSFX #gameaudio #filmsound #filmmaking #gamedev #indiedev #indiefilm

Reply on Twitter 1265199255838511105Retweet on Twitter 1265199255838511105Like on Twitter 1265199255838511105Twitter 1265199255838511105
OblikLinesOblik Lines@OblikLines·
26 May 2020

Working on new tracks with many instances of Misty Valley ! ⁠
Misty Valley is free for all NI Reaktor users⁠
You can get it here: https://t.co/bb53Gtkw5e

#reaktor6 #reaktor #nativeinstruments #synths #vst #sounddesign #virtualinstrument #musicproducer #obliklines #mistyvalley

Reply on Twitter 1265198647307907073Retweet on Twitter 1265198647307907073Like on Twitter 1265198647307907073Twitter 1265198647307907073
Load More...

Copyright Info

All content on Designing Sound is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

Copyright © 2023 · Magazine Pro Theme on Genesis Framework · WordPress · Log in