Vertical Re-Mixing in Unreal Engine with Metasounds + Quartz (Part 1/2)

Si prefieres leer una versión en Español, da click en este botón =>

Unreal Engine Version: 5.0.3

This blog post shows how to implement a simple looping music cue using Unreal Engine's Metasounds. This music cue has four “layers” that play interactively and in sync, one on top of the other, to create a vertical re-mixing system. Finally, I show how to trigger changes or states on this metasound using a Quartz clock.

I implemented the same systems twice for this test project, one using Blueprints visual scripting and another using native C++. Here is the list of essential tools and keywords used for this project:

I programmed all the functionality inside the MusicPlayerActor C++ parent class, BP_MusicPlayerActor blueprint class, and the ThirdPersonMap level blueprint.

Important:

Please consider that this guide does not intend to teach creative sound design. Instead, it exclusively focuses on game audio's implementation and programming aspects.


Download the project here:



 

Part 1 - Metasound:

The Music Cue:

This project uses a 4-part (layers) music composition with these characteristics:

  • Tempo: 76.0 bpm

  • Meter: 4/4

  • Length: *8 bars

* The image below shows that the “Pad” and “Bass” stems are longer than 8 bars. These files contain a "tail” or the natural decay of its instruments. The tail of these tracks allows us to create seamless transitions between every music loop, and it is essential to export them like this.

Metasound Source:

To create Metasounds, go to the Unreal Editor and enable Metasound by going to Edit > Plugins, and enabling “Metasound”.

After re-starting the editor, Metasound Source will be available when right-clicking on the content drawer inside the “Sounds” category

For this project I created a MetaSound Source called “S_MusicCue_MS”

These are the Members of this Metasound Source:

  • Triggers (Orange):

    • EndCue: Stops the looping behavior. The Metasound will stop its timeline when the audio volume reaches 0dB

    • PlayBass: Plays the bass audio track in sync

    • PlayGlitch: Plays the glitch audio track in sync

    • PlayPad: Plays the pad audio track in sync

    • OnNearlyFinishedDrums: Prepares the next loop before the current loop ends

  • Wave Assets (Blue):

    • Bass, Drums, Glitch, Pad: These are the Wave Assets or Audio Files.

  • Audio Signal Flow (Pink):

    • Bass, DrumsAudio(L, R), GlitchAudio(L, R), PadAudio(L, R): Audio flow and connections between nodes.

  • Floats (Green):

    • DrumsPlaybackLocation: Keeps track of the relative position of the “Drums” Wave Asset

    • EnvelopeBass, Envelope Glitch, Envelope Pad: Interpolates an attack curve to the gain inputs on the master mixer

  • Time (Cyan):

    • LoopPosition: Keeps track of the relative position of the “Drums” Wave Asset in seconds

Layer 1: Drums

This section plays the “Drums” layer. It is triggered by OnPlay, or OnNearlyFinishedDrums every time the loop ends. If EndCue its triggered, OnNearlyFinishedDrums won’t be called so the system won’t loop again. The position of this Wave Asset is tracked so the other layers can be played in sync with it.

Layer 2: Glitch

This section plays the “Glitch” layer. It is triggered by PlayGlitch, or OnNearlyFinishedDrums only if PlayGlitch was triggered first. The Wave Player node receives the updated position of the music cue so its always in sync.

Layer 3: Bass

This section plays the “Bass” layer. It is triggered by PlayBass, or OnNearlyFinishedDrums only if PlayBass was triggered first. The Wave Player node receives the updated position of the music cue so its always in sync. This Wave Asset contains a tail which extends two extra bars after the loop ends, so it is important to have two Wave Player nodes so the previous sound overlaps with the next one, seamlessly.

Layer 4: Pad

This section plays the “Pad” layer. It is triggered by PlayPad, or OnNearlyFinishedDrums only if PlayPad was triggered first. The Wave Player node receives the updated position of the music cue so its always in sync. This Wave Asset contains a tail which extends two extra bars after the loop ends, so it is important to have two Wave Player nodes so the previous sound overlaps with the next one, seamlessly.

The Master Mixer Section

The Stereo Mixer combines all the layers and routes them into the left and right outputs. An ADSR envelope is used to create an audio fade-in for the “Glitch”, “Pad”, and the “Bass” layers. Finally, when the EndCue is engaged OnFinished is triggered when the amplitude reaches 0db.


About Part 2

On my next post I will share how to implement this Metasound into the game using both Blueprints and native C++. I'll show how to setup a Quartz Clock and how to trigger each layer synced with a musical tempo.

 

THE END

〰️〰️〰️

THE END 〰️〰️〰️

Previous
Previous

Vertical Re-Mixing in Unreal Engine with Metasounds + Quartz (Part 2/2)

Next
Next

Spatialization #1 in Unreal Engine and Wwise (Blueprints and C++)