Hey, man!
I have been searching for an answer for six months and I succeeded) I will try to show my own solution and maybe it will help you. I need to have 2 players (VR and keyboard+mouse) and make 2 listeners with my own audio devices. How did I do it? First, this can only be done using C++, and you must download Visual Studio to create code and rebuild the wwise plugin. And after some manipulations with the code, you can use the prepared AKŠ”omponent in Blueprints. In short, AKComponent will get 2 variables: the audio device name in OS and the audio device name in Wwise, and you will connect it together in Blueprints. And step by step:
- I created 2 variables (this parameters you can fill in Blueprints) in AkComponent.h (Base path is: Plugins\Wwise\Source\AkAudio\Classes\)
/**
* Name of Audio Device in Wwise. If empty, "System" is using
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = "AkComponent")
FString WwiseDeviceName;
/**
* Name of Audio Device in OS. If empty, default device is using
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = "AkComponent")
FString AudioDeviceName;
- Then we go to AkAudioDevice.h to create some tough functions:
// this need to find your audio device in OS by name parameter above
TTuple <AkUInt32, FString> SearchAudioDeviceIdByName(FString deviceName);
// this function add secondary output and connect audio device from OS with device from Wwise
AkOutputDeviceID AddCustomOutput(FString AudioDevice, FString WwiseDevice, UAkComponent* in_pComponent);
// important function remove secondary output when game stopped
AKRESULT RemoveCustomOutput(AkOutputDeviceID deviceId);
- Now go to AkAudioDevice.cpp and create functions above:
TTuple <AkUInt32, FString> FAkAudioDevice::SearchAudioDeviceIdByName(FString deviceName)
{
TTuple <AkUInt32, FString> result;
AkUInt32 immDeviceCount = AK::GetWindowsDeviceCount(AkDeviceState_Active);
for (AkUInt32 i = 0; i < immDeviceCount; ++i) {
AkUInt32 deviceId = AK_INVALID_DEVICE_ID;
AK::GetWindowsDevice(i, deviceId, NULL, AkDeviceState_Active);
auto deviceNameWstr = AK::GetWindowsDeviceName(i, deviceId, AkDeviceState_Active);
if (FString(deviceNameWstr).Contains(deviceName)) {
result.Key = deviceId;
result.Value = FString(deviceNameWstr);
break;
}
}
return result;
}
AkOutputDeviceID FAkAudioDevice::AddCustomOutput(FString AudioDevice, FString WwiseDevice, UAkComponent* in_pComponent)
{
TTuple <AkUInt32, FString> Device;
AkOutputDeviceID deviceId = AK_INVALID_DEVICE_ID;
FString WwiseDeviceName = "System";
AKRESULT res = AK_Fail;
if (AudioDevice.Len() == 0 && WwiseDevice.Len() == 0) {
return deviceId;
}
if (WwiseDevice.Len() > 0) {
WwiseDeviceName = WwiseDevice;
}
Device = SearchAudioDeviceIdByName(*AudioDevice);
if (Device.Key) {
AkOutputSettings outputSettings(*WwiseDeviceName, Device.Key);
auto gameObjID = in_pComponent->GetAkGameObjectID();
res = AK::SoundEngine::AddOutput(outputSettings, &deviceId, &gameObjID, 1);
}
if (res != AK_Success) {
UE_LOG(LogAkAudio, Error, TEXT("Searching of VR Audio Devices is failed: %d"), res);
} else {
FString componentName = in_pComponent->GetName();
UE_LOG(LogAkAudio, Warning, TEXT("AkComponent \"%s\" attached to \"%s\" <-> \"%s\" "), *componentName, *Device.Value, *WwiseDeviceName);
}
return deviceId;
}
AKRESULT FAkAudioDevice::RemoveCustomOutput(AkOutputDeviceID deviceId)
{
return AK::SoundEngine::RemoveOutput(deviceId);
}
- And at the end we go to AkComponent.cpp and look for UAkComponent::PostRegisterGameObject() and UAkComponent::PostUnregisterGameObject(). It perfect place to manipulate with devices. Here we just use functions just created:
void UAkComponent::PostRegisterGameObject()
{
FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
if (AudioDeviceName.Len() > 0 || WwiseDeviceName.Len() > 0) {
OutputID = AkAudioDevice->AddCustomOutput(AudioDeviceName, WwiseDeviceName, this);
}
}
void UAkComponent::PostUnregisterGameObject()
{
FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
if (AkAudioDevice && OutputID != AK_INVALID_DEVICE_ID) {
AkAudioDevice->RemoveCustomOutput(OutputID);
}
}
That's it. If you find some patience and managed with compiler, you get new posibility in Blueprint)
After this hell you have to create AkComponent as a listener and attach any other AkComponent to it as a listener: