• 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 – Part 2

September 7, 2016 by Charlie Huguenard

post office
click for source

Playing samples straight through will get us there, but it sounds so much nicer if we have options to shape the sounds. A good first step is volume envelopes. In this lesson, we’ll make an attack-sustain-release (ASR) envelope and modify our sampler to use it to modulate the volume.

Lesson 2 – Envelopes

What’s an Envelope?

If you’re familiar with using synths, samplers, and effects in a DAW, chances are you already know how an envelope works. It’s a way to describe how some parameter changes over time. Common uses include changing volume, filter cutoff, and pitch, but it could really be any knob or slider you can think of.

ASR Envelope

To get started, let’s define our parameters. We’ll want to define an attack time, which is how long it takes for the level of the envelope to go from zero to full volume. We’ll also define a sustain time, which is how long it should stay at full volume. And finally, we’ll define a release time, which is how long it takes to go from full volume back down to zero. So, our envelope graph will look something like this:

envelope
A typical envelope with attack, sustain, and release.

Since we want this to be sample-accurate, we’ll convert the attack time and release time into an increment per sample. Or in other words, we’ll find out how much the level should change for each audio sample. The formulas look like this:

attackIncrement = 1.0 / (attackTimeInSeconds * samplesPerSecond)
releaseIncrement = 1.0 / (releaseTimeInSeconds * samplesPerSecond)

And for the sustain time, we’ll want to know how many samples we’ll be holding at max volume. That formula looks like this:

sustainSamples = sustainTimeInSeconds * samplesPerSecond

In all three cases, we’re multiplying the time in seconds by the sample rate to get a duration in samples. So, seconds * samples/seconds = samples. For the attack and release, we want the change in level per sample, so we invert the duration.

In order to get the level for each sequential sample, our GetLevel() function will:

  • Start at 0.0
  • Increment the level using the attack increment until the level reaches 1.0
  • Stay at 1.0 until the sustain sample count reaches 0
  • Decrement the level using the release increment until the level reached 0.0

(view the full code)

Hooking it Up

Now that we have our envelope code, we’ll need to hook it up to our sampler. First off, we’ll add an envelope to our SamplerVoice class:

private readonly ASREnvelope_Lesson2 _envelope = new ASREnvelope_Lesson2();

Then we’ll modify our Play function to take some additional parameters:

public void Play(AudioClip audioClip, double attackTime, double sustainTime, double releaseTime)
{
  sustainTime = (sustainTime > attackTime) ? (sustainTime - attackTime) : 0.0;
  _envelope.Reset(attackTime, sustainTime, releaseTime, AudioSettings.outputSampleRate);

  _audioSource.clip = audioClip;
  _audioSource.Play();
}

Note the safety check to make sure we don’t get a negative sustain time.

And finally, we’ll use the OnAudioFilterRead callback to apply the volume change to the playing audio. OnAudioFilterRead gets called every time a new buffer of samples gets passed on from the AudioSource, and includes the sound from the sample we’re playing. In order to apply the volume, we’ll iterate through each sample in the buffer and multiply it by the level from our envelope:

private void OnAudioFilterRead(float[] buffer, int numChannels)
{
  for (int sIdx = 0; sIdx < buffer.Length; sIdx += numChannels)
  {
    double volume = _envelope.GetLevel();

    for (int cIdx = 0; cIdx < numChannels; ++cIdx)
    {
      buffer[sIdx + cIdx] *= (float)volume;
    }
  }
}

Note that if we get a multi-channel sound, we only want to get the volume from the envelope once for all channels.

(view full code)

Our Sampler code doesn’t have to change much to support the new volume envelope on the SamplerVoice. We’ll just add three fields for the attack, sustain, and release time:

[SerializeField, Range(0f, 2f)] private double _attackTime;
[SerializeField, Range(0f, 2f)] private double _sustainTime;
[SerializeField, Range(0f, 2f)] private double _releaseTime;

And then we’ll pass those values on to the SamplerVoice when we play a sound:

_samplerVoices[_nextVoiceIndex].Play(_audioClip, _attackTime, _sustainTime, _releaseTime);

(view full code)
Try it out in the editor, and you should hear your envelope parameters changing the shape of the sound!

Filed Under: featured, tutorials Tagged With: Audio Programming, dsp, game audio, interactive music, procedural audio, procedural sound, tutorial

Social Media

  • Twitter
  • YouTube

Posts By Month

#sounddesign on Twitter

#sounddesign

tunepocketTunePocket Music@tunepocket·
26 May

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

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

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

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

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 © 2021 · Magazine Pro Theme on Genesis Framework · WordPress · Log in