Audiokinetic's Community Q&A is the forum where users can ask and answer questions within the Wwise and Strata communities. If you would like to get an answer from Audiokinetic's Technical support team, make sure you use the Support Tickets page.

Integrating a Secondary Output in Unity3D

0 votes

Hi,

I want to play audio through a secondary output (HTC Vive headphones) while at the same time play audio through the main output (TV speakers) for a single player VR experience. I am using Unity3D 2019.3 and Wwise 2019.2.1. 

I am able to play audio out of the two audio devices in Wwise from following this guide by Ed Kashinsky by creating a separate Audio Device Shareset "System_VR" and a new audio master bus where the output is set to "System_VR". I have tried to follow the Wwise SDK documentation for Integrating Secondary Outputs using the example for headphones on Windows but have found it difficult to translate the C++ code to C# as I am not a programmer by any means. I also asked a programmer friend for some help but he is not very familiar with Wwise. Below is the following AKSoundEngine C# code that he wrote by creating a new script in Unity and trying to translate the Windows headphone C++ example from the Integrating Secondary Outputs webpage:

public class secondaryOutput : MonoBehaviour
{
    public string DeviceIDName;
    public string DeviceShareSet = "System_VR";
    public GameObject outputGameObject;
    public string EventName;
    public KeyCode TriggerKey;
    public ulong DeviceID;

    void Start()
    {
      
        var uDeviceID = AkSoundEngine.GetDeviceIDFromName(DeviceIDName);
        Debug.Log(uDeviceID);
       

        var outputSettings = new AkOutputSettings(DeviceShareSet, uDeviceID);
       

        AkSoundEngine.AddOutput(outputSettings, out DeviceID, new ulong[] { 0 }, 1);
        Debug.Log(outputSettings);

      

        AkSoundEngine.RegisterGameObj(outputGameObject);

 

        AkSoundEngine.PostEvent("TestSound", gameObject);

    }

Any help would be greatly appreciated.

asked Jun 5, 2020 in General Discussion by Nathan C. (140 points)

1 Answer

+1 vote
 
Best answer

Hi Nathan, 

Hmm.. honestly, this looks fine.
I tried to replicate your setup and I was successful with this.

public class SetMultipleOutputs : MonoBehaviour
{
    public AK.Wwise.Event Event01;
    public AK.Wwise.Event Event02;
    public GameObject GO_01;
    public GameObject GO_02;

    private void Start(){
        Event01.Post(GO_01);
        Event02.Post(GO_02);

        // How to get a list of available Audio Devices on Windows
        for (int i = 0; i<AkSoundEngine.GetWindowsDeviceCount(); i++) {
            uint DeviceID;
            print(AkSoundEngine.GetWindowsDeviceName(i, out DeviceID));
        }
// Would probably work well in a dropdown menu, where the user could select device.

        // Name of my secondary output
        string nameOfDevice = "HMD";

        // Get ID of it
        uint IDofDevice = AkSoundEngine.GetDeviceIDFromName(nameOfDevice);

        // Create new Output Setting
        AkOutputSettings newOutput = new AkOutputSettings("Speaker01", IDofDevice);

        // Add the Output
        AkSoundEngine.AddOutput(newOutput);
    }
}

In Wwise, I created a new Audio Device called Speaker01 and a new adjacent Audio bus to the Master Audio bus. Each master busses would then have a different looping sound feeding to it.

Maybe you can compare my setup with yours and see what's not working. 

Let me know if it helps!

answered Oct 27, 2020 by Mads Maretty S. (Audiokinetic) (38,280 points)
selected Dec 15, 2022 by Mads Maretty S. (Audiokinetic)
Hi Mads,

So with your original code I was able to get a secondary output working in Unity3D. Here are the steps that I took:

1. Create a new Unity3D environment and integrate Wwise using the Wwise Unity Integration feature located on the WWise Launcher.

2. Open WWise and go to the Sharesets tab and create a new System audio device shareset and name it appropriately (e.g. Speaker01)

3. Create a new audio bus separate (not a child) from the master bus. Rename it appropriately (e.g. Speakers)

4. In the general settings of the previously created audio bus, change the audio device shareset to System -> 'Speaker01'. You should now have one audio bus routed to 'System' and the other audio bus to 'Speaker01'.

5. Create two new 'Sound SFX' (ideally two different sounds) and change them to loop infinitely (for testing purposes). Route one SFX to the master audio bus and the second to the newly renamed audio bus. From these sounds, select both, right-click and select 'New Event (One Event Per Object) -> Play. This should have created two individual events for each sound.

5.1 To test this, go to Audio -> Audio Preferences and change the hardware device to your desired secondary audio output of the audio bus with 'Speaker01' set as it's audio device shareset. Create a new Soundcaster session, add the two audio events and play both of them at the same time. You should hear separate and simultaneous audio playback on your two audio device outputs.

6. Create a new soundbank, switch to the Soundbank layout (F7) and add your audio events to it. Click 'Generate All' in the Soundbank manager and then switch to Unity3D.

7. If your integration was successful, you should now see the Wwise Picker menu tab (if you don't see it, go to Window -> Wwise Picker). Create three empty game objects and attach the following Wwise components respectively to each individual empty game object: Wwise Soundbank, Audio Event 1, and Audio Event 2. Click 'Refresh Project and 'Generate SoundBanks' in the Wwise Picker just as a precaution.

7.1 To test if the soundbank generation was successful, select Audio Event 1 and click 'Play' in the 'AKAmbient' component. You won't hear anything from Audio Event 2 if you do this.

8. Create a new C# script and open it in your IDE to add the following code under void Start():

// How to get a list of available Audio Devices
        for (int i = 0; i < AkSoundEngine.GetWindowsDeviceCount(); i++)
        {
            uint DeviceID;
            print(AkSoundEngine.GetWindowsDeviceName(i, out DeviceID));
        } // Would probably work well in a dropdown menu, where the user could select device.

        // Name of my secondary output (doesn't need to be full name, just parts of it... like "Headphone")
        string nameOfDevice = "Headphone";
        // Get ID of it
        uint IDofDevice = AkSoundEngine.GetDeviceIDFromName(nameOfDevice);
        // Create new Output Setting
        AkOutputSettings newOutput = new AkOutputSettings("Speaker01", IDofDevice);
        // Add the Output
        AkSoundEngine.AddOutput(newOutput);

9. Replace "Headphone" with the name of your secondary output. This is the actual audio device name as seen in the audio settings of your OS. It doesn't have to be the full name as it will search for a device that has "Headphone' in the name.

10. In the "Create new Output Setting" section, "Speaker01" is the audio device shareset you created previously in Wwise and is used to create the output setting for the secondary output. "Speaker01" is used as the working audio device shareset naming example for this guide. However, if you have named the created audio device shareset to something else, replace "Speaker01" in the code to what you have instead. Save the script and switch back to Unity3D.

11. Create an empty game object and attach the script to it. Click play in the Unity editor and you should now hear two separate audio events playback simultaneously across two different audio devices.


However, this only worked for devices that had a number in front of their name.

For reference, I am using a HTC Vive and Focusrite 18i20. The Vive had a number but the Focusrite did not. Just to add onto this with another problem, Windows only allows me to choose a predefined speaker layout (Stereo, Quadraphonic, 5.1, and 7.1). My project has changed so that I am now using a 4.1 speaker system and a HTC Vive. With that in mind, I decided to change the shareset type to an ASIO shareset to more precisely control my audio mix. However, I ran into a few more problems.

While I can output my audio to discrete channels using the ASIO shareset and WWise channel router, when I switch to Unity3D after generating the bank I receive the same continuous error in the command log:

Wwise: ASIO initialization error for driver (ASIO Avid Driver): 'Bad Device'): [Hardware input or output is not present or available]:

While I do have Pro Tools installed on this computer, I don't think that is causing the issue. I haven't set the ASIO shareset bus as the secondary output as that is currently not supported (just by seeing the error message in the command log through my testing). Even just using a single audio bus using the ASIO shareset generates this problem and I occasionally receive the same error as this fellow:

https://www.audiokinetic.com/qa/6801/probleme-asio-plug-in-unity?show=6801#q6801

Here is my setup for reference:

Windows 10
Unity3D 2019.4.9f1
Wwise 2019.2.6.7381
Focusrite 18i20 (2nd Gen.) outputting to 4.1
HTC Vive(Original)

If you need any further information just let me know.
Hey Nathan. What an awesome amount of info you've provided for everyone else to get inspired. I'll make sure to share it with someone who knows much more about this than I.
...