Rendering Ambisonic Soundfields in MetaSounds
This guide demonstrates how to use the Ambisonic Renderer in MetaSounds to render Ambisonic soundfields and dynamically control the listener and source rotations in order to make the rendering react to their relative orientations.
The parameter update technique demonstrated in this guide can be used to control other parameters as well, like the headlocked mode, the output format (binaural vs. stereo), or parameters of the Spatializer node.
Prerequisites
This guide assumes that you are familiar with the basics of MetaSounds and Unreal Engine. Make sure you have installed atmoky TrueSpatial following the installation instructions.
In order to hear the spatialization effect, you will need a pair of headphones. You will also need a First Order Ambisonics audio file in ambiX format (ACN/SN3D) to use as the soundfield.
Adding a MetaSound Source
As a first step, we will create a MetaSound source that will be used to playback the Ambisonic soundfield using a Wave Player and route the audio into the Ambisonic Renderer.
In the Content Browser of your Unreal Engine project, right-click and select
Sounds → MetaSound Source to create a new MetaSound Source asset. Name it
AmbisonicSource and double-click to open it.
The first thing we need to do is make the source play stereo audio. For this, click the MetaSound button and set the Output Format to Stereo. The canvas should now show two Output nodes: left and right.
Next, we will add a Wave Player node to the canvas. Right-click on the canvas
and search for Wave Player and select the Wave Player (4.0, Quad) version.
This node will be used to output the four channels of the Ambisonic soundfield.
In its Wave Asset parameter, select your Ambisonic soundfield file. To make
the player start playing automatically, connect the On Play input node to the
Play input of the Wave Player. To make the patch happy, also connect the
On Finished outlet to the On Finished output of the MetaSound patch.
Your patch should look like this:
Next, we want to route the output of the Wave Player into the Ambisonic
Renderer. Right-click on the canvas and search for Ambisonic Renderer and
select it. Connect the four output channels of the Wave Player to the inputs of
the Ambisonic Renderer.
Finally, connect the two output vertices of the Ambisonic Renderer to the left and right output nodes of the MetaSound Source.
The updated patch should look like this:
At this stage, you can preview the sound by clicking the Play button in the
MetaSound Source asset. Per default, the sound will be played back binaurally,
so make sure to use headphones. You can also change the rendering format to
stereo by expanding the Ambisonic Renderer node and setting the Output Format
to Stereo.
Adding MetaSound Source to the Scene
The quickest way to add out Ambisonic Source to the scene is to drag and drop the MetaSound Source asset from the Content Browser into the scene. For a static source that would be just fine, however, as we want to control the rotation of the source and listener dynamically, we will wrap the MetaSound Source in a Blueprint Actor.
Right-click in the Content Browser and select Blueprint Class, select Actor
and name it AmbisonicSourceActor. Open the Blueprint by double-clicking on it.
From the Content Drawer, drag and drop the AmbisonicSource MetaSound Source
asset into the Blueprint’s Components list in the upper left corner. For
visualization we want to add a Cube component to the Blueprint. Click the
Add Component button and search for Cube and select it.
The component tree should look like this:
Close the Blueprint and drag and drop the AmbisonicSourceActor Blueprint into
the scene. You can now move the Cube around to position the source in the scene.
Hit Play to hear the Ambisonic soundfield being rendered in the scene.
You will notice that the sound is static and does not change when you rotate the Cube or the listener. In the next section, we will add controls to dynamically update the source and listener rotations.
Updating Source and Listener Rotations
Adding Rotation Parameters
To make the soundfield react to the relative orientation of the source and listener, we will first set up our MetaSound source to receive the necessary parameters.
Open the AmbisonicSource MetaSound Source asset and add 6 new input parameters
by clicking the + button next to the Inputs list in the upper left corner.
Name them:
SourceYawSourcePitchSourceRollListenerYawListenerPitchListenerRoll
These parameters will be used to control the yaw, pitch, and roll of the source and listener, respectively. Per default, the parameters will be Floats which is fine for our use case.
We will first connect the Source rotations to the Ambisonic Renderer. To do
this, drag the SourceYaw, SourcePitch, and SourceRoll parameters from the
Inputs list to the canvas. We need to combine them into a Rotation object
before we can feed them into the Ambisonic Renderer. Right-click on the canvas
and search for atmoky Rotation and select it. Connect the three parameters to
the Rotation node and connect the output of the Rotation node to the
Source Rotation input of the Ambisonic Renderer.
If you want to preview the rotation effect, change the range of the parameters to -180 to 180 degrees. You can now adjust the values while the sound is playing. The soundfield rendering should now change as you rotate the source.
Perform the same steps for the Listener rotations. Drag the ListenerYaw,
ListenerPitch, and ListenerRoll parameters to the canvas, combine them into
a Rotation object, and connect the output to the Listener Rotation input of
the Ambisonic Renderer.
The updated patch should look like this:
Updating the Source Rotation
To control the rotation of the source soundfield by rotating the Source Actor in the scene, we need to add some Blueprint logic to update the rotation parameters of the MetaSound Source.
In the next steps, you might want to deselect the “Context Sensitive” option in the Blueprint Editor’s search bar to see all available nodes.
Open the AmbisonicSourceActor Blueprint. To retrieve the current rotation of
the Actor, right-click and search for Get Actor Rotation and select it. The
output will hold all three rotation values: yaw, pitch, and roll. In order to
access the individual values, drag the Return Value outlet to the canvas and
search for Break Rotator. This will split the rotation into its individual
components.
Next we need to update the MetaSound Source parameters. Drag the
AmbisonicSource component from the Components list to the canvas. That’s the
target of our parameter update. Right-click on the canvas and search for
Set Float Parameter and select it. Make sure to select the one with the
Target is Audio Component tooltip. Connect the AmbisonicSource with the
Target input, set the In Name to SourceYaw and connect the Yaw output of
the Break Rotator node to the In Value input.
Repeat the same steps for the SourcePitch and SourceRoll parameters.
In order to actually trigger the parameter update, we need to connect the
Event Tick node to the Set Float Parameter nodes. We can do this with help
of a Sequence node. Add a Sequence node to the canvas and connect the
Event Tick to the Execute input of the Sequence. Connect the
Set Float Parameter nodes to output pins of the Sequence.
The updated Blueprint should look like this:
This will update the parameters every frame. You can now go back to the scene
and rotate the AmbisonicSourceActor to see/hear the soundfield react to the
rotation.
Updating the Listener Rotation
As we haven’t connected the Listener rotation parameters to the Blueprint yet,
the soundfield will not react to the rotation of the listener. To do this, we
need to add the same logic as we did for the Source rotation, but we will use
the Get Player Pawn node to retrieve the rotation of the player character.
After completing the previous steps for the Listener rotation, the Blueprint should look like this:
You can now rotate the player character in the scene to see/hear the soundfield react to the rotation.
In case you don’t get Listener rotation updates, you might want to use the
Get Player Camera Manager node instead of the Get Player Pawn node to
retrieve the camera rotation.