From 1f4ddf2a555086793b63d18d5e754a465555fa86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Sch=C3=A4fer?=
 <pschaefer@ITA.AKUSTIK.RWTH-AACHEN.DE>
Date: Wed, 1 Mar 2023 08:46:14 +0100
Subject: [PATCH] VAReceierActor / VAServerLauncher: ReproductionInputType -
 now sends the reproduction input signal type (e.g. binaural / ambisonics) to
 the launcher

---
 Source/VAPlugin/Private/VAReceiverActor.cpp  |  2 +-
 Source/VAPlugin/Private/VAServerLauncher.cpp | 58 +++++++++++++++++++-
 Source/VAPlugin/Private/VAServerLauncher.h   |  8 ++-
 Source/VAPlugin/Public/VAEnums.h             | 13 +++++
 Source/VAPlugin/Public/VAReceiverActor.h     |  4 ++
 5 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/Source/VAPlugin/Private/VAReceiverActor.cpp b/Source/VAPlugin/Private/VAReceiverActor.cpp
index 07b9a86..b061504 100644
--- a/Source/VAPlugin/Private/VAReceiverActor.cpp
+++ b/Source/VAPlugin/Private/VAReceiverActor.cpp
@@ -57,7 +57,7 @@ void AVAReceiverActor::BeginPlay()
 	if (bAutomaticRemoteVAStart)
 	{
 		FVAPlugin::VAServerLauncher.StartVAServerLauncher(); //if possible
-		bStartedVAServer = FVAPlugin::VAServerLauncher.RemoteStartVAServer(GetIPAddress(), RemoteVAStarterPort, WhichVAServerVersionToStart, VARendererIniFile);
+		bStartedVAServer = FVAPlugin::VAServerLauncher.RemoteStartVAServer(GetIPAddress(), RemoteVAStarterPort, WhichVAServerVersionToStart, VARendererIniFile, ReproductionInputType);
 		if(bStartedVAServer){
 			FVAPlugin::SetUseVA(true);
 		}
diff --git a/Source/VAPlugin/Private/VAServerLauncher.cpp b/Source/VAPlugin/Private/VAServerLauncher.cpp
index 37b1ebd..b57dd25 100644
--- a/Source/VAPlugin/Private/VAServerLauncher.cpp
+++ b/Source/VAPlugin/Private/VAServerLauncher.cpp
@@ -13,7 +13,7 @@
 #include "VAPlugin.h"
 
 
-bool FVAServerLauncher::RemoteStartVAServer(const FString& Host, const int Port, const FString& VersionName, const FString& VARendererIniFile)
+bool FVAServerLauncher::RemoteStartVAServer(const FString& Host, const int Port, const FString& VersionName, const FString& VARendererIniFile, const EReproductionInput ReproductionInputType)
 {
 	if (!UVirtualRealityUtilities::IsMaster())
 	{
@@ -59,7 +59,16 @@ bool FVAServerLauncher::RemoteStartVAServer(const FString& Host, const int Port,
 		if (!SendFileToVAServer(VARendererIniFile))
 		{
 			FVAUtils::OpenMessageBox("[FVAServerLauncher::RemoteStartVAServer()]: VARenderer.ini file '" + VARendererIniFile +
-				"' could not be copied to VAServer. Does the file exist? See error log for additional info. VAServer will be launched with default settings.", true);
+				"' could not be copied to VAServerLauncher. Does the file exist? See error log for additional info. VAServerLauncher will run with default settings.", true);
+		}
+	}
+
+	if (ReproductionInputType != EReproductionInput::Default)
+	{
+		if (!SendReproductionInputSignalType(ReproductionInputType))
+		{
+			FVAUtils::OpenMessageBox("[FVAServerLauncher::RemoteStartVAServer()]: ReproductionInputType '" + EnumToString(ReproductionInputType) +
+				"' could not be sent to VAServerLauncher. See error log for additional info. VAServerLauncher will run with default settings.", true);
 		}
 	}
 
@@ -282,6 +291,33 @@ bool FVAServerLauncher::IsVAServerLauncherConnected()
 	return VAServerLauncherSocket!=nullptr;
 }
 
+bool FVAServerLauncher::SendReproductionInputSignalType(const EReproductionInput ReproductionInputType)
+{
+	const FString ProjectName = GetDefault<UGeneralProjectSettings>()->ProjectName;
+	FString CommandMsg = "reproduction_input_type:" + EnumToString(ReproductionInputType);
+	TArray<uint8> CommandMsgBinary = ConvertString(CommandMsg);
+
+	int32 BytesSend;
+	VAServerLauncherSocket->Send(CommandMsgBinary.GetData(), CommandMsgBinary.Num(), BytesSend);
+
+	const int32 BufferSize = 16;
+	int32 BytesRead = 0;
+	uint8 Response[16];
+	if (VAServerLauncherSocket->Recv(Response, BufferSize, BytesRead))
+	{
+		FString ResponseString = ByteArrayToString(Response, BytesRead);
+		if (ResponseString == "ack")
+		{
+			FVAUtils::LogStuff("[FVAServerLauncher::SendReproductionInputSignalType()]: ReproductionInputType was successfully received by VAServerLauncher!", false);
+			return true;
+		}
+		FVAUtils::LogStuff("[FVAServerLauncher::SendReproductionInputSignalType()]: ReproductionInputType not accepted by VAServerLauncher! Answer: " + ResponseString, false);
+		return false;
+	}
+	FVAUtils::LogStuff("[FVAServerLauncher::SendReproductionInputSignalType()]: VAServerLauncher did not answer!", true);
+	return false;
+}
+
 TArray<uint8> FVAServerLauncher::ConvertString(const FString& String)
 {
 	TArray<uint8> RequestData;
@@ -313,3 +349,21 @@ FString FVAServerLauncher::ByteArrayToString(const uint8* In, int32 Count)
 	}
 	return Result;
 }
+
+FString FVAServerLauncher::EnumToString(EReproductionInput Enum)
+{
+	switch (Enum)
+	{
+	case EReproductionInput::Default:
+		return TEXT("default");
+	case EReproductionInput::Binaural:
+		return TEXT("binaural");
+	case EReproductionInput::Ambisonics:
+		return TEXT("ambisonics");
+	case EReproductionInput::Custom:
+		return TEXT("custom");
+	default:
+		return TEXT("invalid");
+	}
+
+}
diff --git a/Source/VAPlugin/Private/VAServerLauncher.h b/Source/VAPlugin/Private/VAServerLauncher.h
index acc4b1f..b9dffc0 100644
--- a/Source/VAPlugin/Private/VAServerLauncher.h
+++ b/Source/VAPlugin/Private/VAServerLauncher.h
@@ -2,12 +2,14 @@
 
 #include "Sockets.h"
 
+#include "VAEnums.h"
+
 class FVAServerLauncher
 {
 public:
 	// Remote Start VAServer
 	bool RemoteStartVAServer(const FString& Host, int Port,
-	                                const FString& VersionName, const FString& VARendererIni = "");
+	                                const FString& VersionName, const FString& VARendererIni = "", const EReproductionInput ReproductionInputType = EReproductionInput::Default);
 
 	bool StartVAServerLauncher();
 
@@ -22,9 +24,13 @@ public:
 
 private:
 
+	bool SendReproductionInputSignalType(const EReproductionInput ReproductionInputType);
+
 	TArray<uint8> ConvertString(const FString& String);
 	FString ByteArrayToString(const uint8* In, int32 Count);
 
+	static FString EnumToString(EReproductionInput Enum);
+
 
 	//Socket connection to the VAServer Launcher, has to be held open until the program ends
 	FSocket* VAServerLauncherSocket=nullptr;
diff --git a/Source/VAPlugin/Public/VAEnums.h b/Source/VAPlugin/Public/VAEnums.h
index 56f69ca..8866e0e 100644
--- a/Source/VAPlugin/Public/VAEnums.h
+++ b/Source/VAPlugin/Public/VAEnums.h
@@ -34,6 +34,19 @@ namespace EConnectionSetting
 	};
 }
 
+UENUM()
+enum class EReproductionInput : uint8
+{
+	// [NOT RECOMMENDED] Use default reproduction modules
+	Default = 0,
+	// Use reproduction modules for binaural signals
+	Binaural = 1,
+	// Use reproduction modules for ambisonics signals
+	Ambisonics = 2,
+	// Use reproduction modules for custom purposes (e.g. mixed signal types)
+	Custom = 3
+};
+
 
 UENUM(BlueprintType)
 namespace EDirectivitySetting
diff --git a/Source/VAPlugin/Public/VAReceiverActor.h b/Source/VAPlugin/Public/VAReceiverActor.h
index 9a475a2..2e0f387 100644
--- a/Source/VAPlugin/Public/VAReceiverActor.h
+++ b/Source/VAPlugin/Public/VAReceiverActor.h
@@ -89,6 +89,10 @@ protected:
 	UPROPERTY(EditAnywhere, meta = (DisplayName = "VARenderer.ini file", Category = "VAServer Launcher"))
 	FString VARendererIniFile = TEXT("");
 
+	//Used to select the group of reproduction modules specified in VAServer Launcher config.
+	UPROPERTY(EditAnywhere, meta = (DisplayName = "Reproduction input signal type", Category = "VAServer Launcher"))
+	EReproductionInput ReproductionInputType = EReproductionInput::Binaural;
+
 
 	// Read an initial mapping file for directivities?
 	UPROPERTY(EditAnywhere, meta = (DisplayName = "Read an initial mapping file?", Category = "Directivity Manager"))
-- 
GitLab