Skip to content

Commit

Permalink
Merge pull request #18 from 4Players/ue-networking-5.4
Browse files Browse the repository at this point in the history
Ue networking 5.4
  • Loading branch information
SFuhrmann authored Nov 14, 2024
2 parents 06bbd83 + 9e1e11d commit 27c661c
Show file tree
Hide file tree
Showing 38 changed files with 576 additions and 138 deletions.
Binary file modified Content/Blueprints/Game/GameInstance_TD.uasset
Binary file not shown.
Binary file modified Content/Blueprints/Game/SettingsSaveGame.uasset
Binary file not shown.
Binary file modified Content/Blueprints/Game/TopDownCharacter.uasset
Binary file not shown.
Binary file modified Content/Blueprints/Widgets/IngameHud.uasset
Binary file not shown.
Binary file modified Content/Blueprints/Widgets/OptionsMenu/WBP_Options.uasset
Binary file not shown.
Binary file not shown.
Binary file modified Content/Maps/TopDownExampleMap.umap
Binary file not shown.
Binary file modified Content/Sound/TopDownExampleMap_StaticGeometry.uasset
Binary file not shown.
10 changes: 5 additions & 5 deletions Plugins/Odin/Odin.uplugin
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"FileVersion": 2,
"EngineVersion": "5.4.0",
"Version": 447,
"WhitelistPlatforms": [ "Win64", "Mac", "IOS", "Linux", "LinuxArm64", "Android" ],
"VersionName": "1.8.11",
"Version": 499,
"PlatformAllowList": [ "Win64", "Mac", "IOS", "Linux", "LinuxArm64", "Android"],
"VersionName": "1.8.12",
"FriendlyName": "4Players ODIN",
"Description": "Unreal integration plugin to integrate real-time chat technology into your game",
"Category": "Other",
Expand All @@ -21,7 +21,7 @@
"Name": "Odin",
"Type": "Runtime",
"LoadingPhase": "PreDefault",
"WhitelistPlatforms": [ "Win64", "Mac", "IOS", "Linux", "LinuxArm64", "Android" ],
"PlatformAllowList": [ "Win64", "Mac", "IOS", "Linux", "LinuxArm64", "Android"],
"AdditionalDependencies": [
"AudioMixer",
"AudioCapture"
Expand All @@ -32,7 +32,7 @@
{
"Name": "AudioCapture",
"Enabled": true,
"WhitelistPlatforms": [ "Win64", "Mac", "IOS", "Linux", "LinuxArm64", "Android" ]
"PlatformAllowList": [ "Win64", "Mac", "IOS", "Linux", "LinuxArm64", "Android"]
}
]
}
91 changes: 69 additions & 22 deletions Plugins/Odin/Source/Odin/Private/OdinCaptureMedia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,56 +22,65 @@ void UOdinCaptureMedia::RemoveRoom()
}

void UOdinCaptureMedia::SetAudioCapture(UAudioCapture* audio_capture)
{
SetAudioGenerator(audio_capture);
}

void UOdinCaptureMedia::SetAudioGenerator(UAudioGenerator* audioGenerator)
{
TRACE_CPUPROFILER_EVENT_SCOPE(UOdinCaptureMedia::SetAudioCapture)

if (!audio_capture) {
if (!audioGenerator) {
UE_LOG(Odin, Error,
TEXT("UOdinCaptureMedia::SetAudioCapture - audio capture is null, microphone will "
"not work."));
return;
}

this->audio_capture_ = audio_capture;
this->audio_capture_ = audioGenerator;

if (this->stream_handle_) {
TRACE_CPUPROFILER_EVENT_SCOPE(UOdinCaptureMedia::SetAudioCapture Odin Create Audio Stream)
odin_media_stream_destroy(this->stream_handle_);
this->SetMediaHandle(0);
}

if (audio_capture) {
stream_sample_rate_ = audio_capture->GetSampleRate();
stream_num_channels_ = audio_capture->GetNumChannels();
if (audio_capture_) {
stream_sample_rate_ = audio_capture_->GetSampleRate();
stream_num_channels_ = audio_capture_->GetNumChannels();
}
{
TRACE_CPUPROFILER_EVENT_SCOPE(UOdinCaptureMedia::SetAudioCapture Odin Create Audio Stream)

UE_LOG(Odin, Log,
TEXT("Initializing Audio Capture stream with Sample Rate: %d and Channels: %d"),
stream_sample_rate_, stream_num_channels_);
this->stream_handle_ = odin_audio_stream_create(

const int32 OdinForcedNumChannels = GetEnableMonoMixing() ? 1 : stream_num_channels_;
this->stream_handle_ = odin_audio_stream_create(
OdinAudioStreamConfig{static_cast<uint32_t>(stream_sample_rate_),
static_cast<uint8_t>(stream_num_channels_)});
static_cast<uint8_t>(OdinForcedNumChannels)});
}

TWeakObjectPtr<UOdinCaptureMedia> WeakThisPtr = this;
if (audio_capture && audio_capture->IsValidLowLevel()) {
if (audio_capture_ && IsValid(audio_capture_)) {
// Create generator delegate
TFunction<void(const float* InAudio, int32 NumSamples)> audioGeneratorDelegate =
[WeakThisPtr](const float* InAudio, int32 NumSamples) {
if (UOdinCaptureMedia* This = WeakThisPtr.Get()) {
UAudioCapture* AudioCapture = This->audio_capture_;
UAudioGenerator* AudioCapture = This->audio_capture_;

if (!AudioCapture || !AudioCapture->IsValidLowLevel()) {
if (!AudioCapture || !IsValid(AudioCapture)) {
UE_LOG(Odin, Warning,
TEXT("Aborting audio generator callback due to LowLevelCheck."));
return;
}

int32 StreamSampleRate = This->stream_sample_rate_;
int32 StreamNumChannels = This->stream_num_channels_;
const int32 StreamSampleRate = This->stream_sample_rate_;
const int32 StreamNumChannels = This->stream_num_channels_;
// Avoid Checking for num channel equality because we're mixing to mono
if (StreamSampleRate != AudioCapture->GetSampleRate()
|| StreamNumChannels != AudioCapture->GetNumChannels()) {
/* || StreamNumChannels != AudioCapture->GetNumChannels()*/) {
UE_LOG(Odin, Display,
TEXT("Incompatible sample rate, stream: %d, capture: %d. Restarting "
"stream."),
Expand All @@ -82,22 +91,43 @@ void UOdinCaptureMedia::SetAudioCapture(UAudioCapture* audio_capture)
}

if (This->stream_handle_) {
if (This->volume_adjusted_audio_size_ < NumSamples) {
int32 TargetSampleCount = This->GetEnableMonoMixing()
? NumSamples / StreamNumChannels
: NumSamples;
if (This->volume_adjusted_audio_size_ < TargetSampleCount) {
delete[] This->volume_adjusted_audio_;
This->volume_adjusted_audio_ = new float[NumSamples];
This->volume_adjusted_audio_size_ = NumSamples;
This->volume_adjusted_audio_ = new float[TargetSampleCount];
This->volume_adjusted_audio_size_ = TargetSampleCount;
}
for (int i = 0; i < NumSamples; ++i) {
This->volume_adjusted_audio_[i] =
InAudio[i] * This->GetVolumeMultiplierAdjusted();

if (This->GetEnableMonoMixing()) {
// Simple mix to mono
for (int32 i = 0; i < TargetSampleCount; ++i) {
float MixingResult = 0.0f;
for (int32 ChannelIndex = 0; ChannelIndex < StreamNumChannels;
++ChannelIndex) {
float Sample = InAudio[i * StreamNumChannels + ChannelIndex];
MixingResult += Sample;
}
This->volume_adjusted_audio_[i] =
(MixingResult / StreamNumChannels)
* This->GetVolumeMultiplierAdjusted();
}
} else {
for (int32 i = 0; i < TargetSampleCount; ++i) {
This->volume_adjusted_audio_[i] =
InAudio[i] * This->GetVolumeMultiplierAdjusted();
}
}

odin_audio_push_data(This->stream_handle_, This->volume_adjusted_audio_,
NumSamples);
TargetSampleCount);
}
}
};
this->audio_generator_handle_ = audio_capture->AddGeneratorDelegate(audioGeneratorDelegate);
FScopeLock lock(&this->capture_generator_delegate_);
this->audio_generator_handle_ =
audio_capture_->AddGeneratorDelegate(audioGeneratorDelegate);
}
}

Expand Down Expand Up @@ -155,6 +185,22 @@ void UOdinCaptureMedia::SetMaxVolumeMultiplier(const float newValue)
this->max_volume_multiplier_ = newValue;
}

bool UOdinCaptureMedia::GetEnableMonoMixing() const
{
return bEnableMonoMixing;
}

void UOdinCaptureMedia::SetEnableMonoMixing(const bool bShouldEnableMonoMixing)
{
const bool bOldValue = this->bEnableMonoMixing;
this->bEnableMonoMixing = bShouldEnableMonoMixing;
if (bOldValue != bShouldEnableMonoMixing) {
UE_LOG(Odin, Verbose,
TEXT("UOdinCaptureMedia: Reconnecting due to EnableMonoMixing Value switch."))
Reconnect();
}
}

void UOdinCaptureMedia::Reconnect()
{
ReconnectCaptureMedia(this);
Expand All @@ -164,6 +210,7 @@ void UOdinCaptureMedia::BeginDestroy()
{
Reset();
delete[] volume_adjusted_audio_;
volume_adjusted_audio_ = nullptr;
Super::BeginDestroy();
}

Expand Down Expand Up @@ -203,7 +250,7 @@ void UOdinCaptureMedia::ReconnectCaptureMedia(TWeakObjectPtr<UOdinCaptureMedia>
roomPointer->UnbindCaptureMedia(OdinCaptureMedia);
// reset audio capture generator delegate and media stream
OdinCaptureMedia->ResetOdinStream();
OdinCaptureMedia->SetAudioCapture(capturePointer);
OdinCaptureMedia->SetAudioGenerator(capturePointer);
const OdinRoomHandle room_handle = roomPointer->RoomHandle();
const OdinMediaStreamHandle media_handle = OdinCaptureMedia->GetMediaHandle();
const OdinReturnCode result = odin_room_add_media(room_handle, media_handle);
Expand Down
9 changes: 5 additions & 4 deletions Plugins/Odin/Source/Odin/Private/OdinFunctionLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ UOdinFunctionLibrary* UOdinFunctionLibrary::getOdinFunctionLibrary()
return g_odinFunctionLibrary;
}

UOdinCaptureMedia* UOdinFunctionLibrary::Odin_CreateMedia(UPARAM(ref) UAudioCapture*& audioCapture)
UOdinCaptureMedia* UOdinFunctionLibrary::Odin_CreateMedia(UPARAM(ref)
UAudioGenerator*& audioGenerator)
{
if (!audioCapture)
if (!audioGenerator)
return nullptr;
auto capture_media = NewObject<UOdinCaptureMedia>(audioCapture);
capture_media->SetAudioCapture(audioCapture);
auto capture_media = NewObject<UOdinCaptureMedia>(audioGenerator);
capture_media->SetAudioGenerator(audioGenerator);
return capture_media;
}

Expand Down
3 changes: 2 additions & 1 deletion Plugins/Odin/Source/Odin/Private/OdinRoom.AsyncNodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

#include "OdinRoom.h"
#include "OdinRoom.AsyncTasks.h"
#include "OdinFunctionLibrary.h"
#include "odin_sdk.h"
#include "Odin.h"
#include "OdinSubsystem.h"
#include "Async/AsyncWork.h"
#include "GenericPlatform/GenericPlatform.h"
#include "Async/Async.h"

UOdinRoomJoin* UOdinRoomJoin::JoinRoom(UObject* WorldContextObject, UPARAM(ref) UOdinRoom*& room,
const FString url, const FString token,
Expand Down
34 changes: 21 additions & 13 deletions Plugins/Odin/Source/Odin/Private/OdinRoom.AsyncTasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "Odin.h"
#include "OdinSubsystem.h"
#include "GenericPlatform/GenericPlatform.h"
#include "Async/Async.h"

void JoinRoomTask::DoWork()
{
Expand Down Expand Up @@ -306,18 +308,24 @@ void SendMessageTask::DoWork()

void DestroyRoomTask::DoWork()
{
OdinReturnCode ReturnCode = odin_room_close(roomHandle);
if (odin_is_error(ReturnCode)) {
FOdinModule::LogErrorCode(TEXT("Destroy Room Task: Error while closing room"), ReturnCode);
}
ReturnCode = odin_room_set_event_callback(roomHandle, nullptr, nullptr);
if (odin_is_error(ReturnCode)) {
FOdinModule::LogErrorCode(TEXT("Destroy Room Task: Error while reseting event callback"),
ReturnCode);
}

UOdinSubsystem* OdinSubsystem = UOdinSubsystem::Get();
if (OdinSubsystem) {
OdinSubsystem->DeregisterRoom(roomHandle);
if (roomHandle > 0) {
OdinReturnCode ReturnCode = odin_room_close(roomHandle);
if (odin_is_error(ReturnCode)) {
FOdinModule::LogErrorCode(TEXT("Destroy Room Task: Error while closing room"),
ReturnCode);
}
ReturnCode = odin_room_set_event_callback(roomHandle, nullptr, nullptr);
if (odin_is_error(ReturnCode)) {
FOdinModule::LogErrorCode(
TEXT("Destroy Room Task: Error while reseting event callback"), ReturnCode);
}
UOdinSubsystem* OdinSubsystem = UOdinSubsystem::Get();
if (OdinSubsystem) {
OdinSubsystem->DeregisterRoom(roomHandle);
}
} else {
UE_LOG(Odin, Log,
TEXT("DestroyRoomTask::DoWork(): Aborted closing room, room handle is already "
"invalid."));
}
}
Loading

0 comments on commit 27c661c

Please sign in to comment.