-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from outoftheboxplugins/master
Support for Unreal 5
- Loading branch information
Showing
5 changed files
with
171 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Binaries/ | ||
Intermediate/ |
107 changes: 46 additions & 61 deletions
107
BrainFlowPlugin/Source/BrainFlowPlugin/BrainFlowPlugin.Build.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,68 @@ | ||
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using UnrealBuildTool; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
public class BrainFlowPlugin : ModuleRules | ||
{ | ||
public BrainFlowPlugin(ReadOnlyTargetRules Target) : base(Target) | ||
{ | ||
public BrainFlowPlugin(ReadOnlyTargetRules Target) : base(Target) | ||
{ | ||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; | ||
|
||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); | ||
|
||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); | ||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "Projects" }); | ||
|
||
if(Target.Platform == UnrealTargetPlatform.Win32) | ||
{ | ||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "inc")); | ||
PublicLibraryPaths.Add(Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib")); | ||
PublicAdditionalLibraries.Add("Brainflow32.lib"); | ||
PublicAdditionalLibraries.Add("DataHandler32.lib"); | ||
PublicAdditionalLibraries.Add("BoardController32.lib"); | ||
PublicAdditionalLibraries.Add("MLModule32.lib"); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/BoardController32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "BoardController32.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/DataHandler32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "DataHandler32.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/GanglionLib32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "GanglionLib32.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/gforce32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "gforce32.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/gForceSDKWrapper32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "gForceSDKWrapper32.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/neurosdk-x86.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "neurosdk-x86.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/BrainBitLib32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "BrainBitLib32.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/eego-SDK32.dll", Path.Combine(ModuleDirectory, "Compiled", "Win32_dynamic", "lib", "eego-SDK32.dll")); | ||
} | ||
if(Target.Platform == UnrealTargetPlatform.Win64) | ||
{ | ||
PublicLibraryPaths.Add(Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib")); | ||
String PrecompiledFolder = Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib"); | ||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "inc")); | ||
PublicAdditionalLibraries.Add("Brainflow.lib"); | ||
PublicAdditionalLibraries.Add("DataHandler.lib"); | ||
PublicAdditionalLibraries.Add("BoardController.lib"); | ||
PublicAdditionalLibraries.Add("MLModule.lib"); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/BoardController.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "BoardController.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/DataHandler.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "DataHandler.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/GanglionLib.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "GanglionLib.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/gforce64.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "gforce64.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/gForceSDKWrapper.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "gForceSDKWrapper.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/neurosdk-x64.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "neurosdk-x64.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/Unicorn.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "Unicorn.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/BrainBitLib.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "BrainBitLib.dll")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/eego-SDK.dll", Path.Combine(ModuleDirectory, "Compiled", "x64_dynamic", "lib", "eego-SDK.dll")); | ||
|
||
PublicAdditionalLibraries.Add(Path.Combine(PrecompiledFolder, "Brainflow.lib")); | ||
PublicAdditionalLibraries.Add(Path.Combine(PrecompiledFolder, "DataHandler.lib")); | ||
PublicAdditionalLibraries.Add(Path.Combine(PrecompiledFolder, "BoardController.lib")); | ||
PublicAdditionalLibraries.Add(Path.Combine(PrecompiledFolder, "MLModule.lib")); | ||
|
||
PublicDelayLoadDLLs.Add("BoardController.dll"); | ||
PublicDelayLoadDLLs.Add("DataHandler.dll"); | ||
PublicDelayLoadDLLs.Add("MLModule.dll"); | ||
|
||
AddRuntimeDependencies(PrecompiledFolder, "*.dll"); | ||
} | ||
if(Target.Platform == UnrealTargetPlatform.Mac) | ||
{ | ||
String PrecompiledFolder = Path.Combine(ModuleDirectory, "Compiled", "macos", "lib"); | ||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Compiled", "macos", "inc")); | ||
PublicLibraryPaths.Add(Path.Combine(ModuleDirectory, "Compiled", "macos", "lib")); | ||
PublicAdditionalLibraries.Add("libBrainflow.a"); | ||
PublicDelayLoadDLLs.Add("libDataHandler.dylib"); | ||
PublicDelayLoadDLLs.Add("libBoardController.dylib"); | ||
PublicDelayLoadDLLs.Add("libMLModule.dylib"); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libBoardController.dylib", Path.Combine(ModuleDirectory, "Compiled", "macos", "lib", "libBoardController.dylib")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libDataHandler.dylib", Path.Combine(ModuleDirectory, "Compiled", "macos", "lib", "libDataHandler.dylib")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libGanglionLib.dylib", Path.Combine(ModuleDirectory, "Compiled", "macos", "lib", "libGanglionLib.dylib")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libMLModule.dylib", Path.Combine(ModuleDirectory, "Compiled", "macos", "lib", "libMLModule.dylib")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libneurosdk-shared.dylib", Path.Combine(ModuleDirectory, "Compiled", "macos", "lib", "libneurosdk-shared.dylib")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libBrainBitLib.dylib", Path.Combine(ModuleDirectory, "Compiled", "macos", "lib", "libBrainBitLib.dylib")); | ||
|
||
PublicAdditionalLibraries.Add(Path.Combine(PrecompiledFolder, "libBrainflow.a")); | ||
|
||
PublicDelayLoadDLLs.Add(Path.Combine(PrecompiledFolder, "libBoardController.dylib")); | ||
PublicDelayLoadDLLs.Add(Path.Combine(PrecompiledFolder, "libDataHandler.dylib")); | ||
PublicDelayLoadDLLs.Add(Path.Combine(PrecompiledFolder, "libMLModule.dylib")); | ||
|
||
AddRuntimeDependencies(PrecompiledFolder, "*.dylib"); | ||
} | ||
if(Target.Platform == UnrealTargetPlatform.Linux) | ||
{ | ||
String PrecompiledFolder = Path.Combine(ModuleDirectory, "Compiled", "linux", "lib"); | ||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Compiled", "linux", "inc")); | ||
PublicLibraryPaths.Add(Path.Combine(ModuleDirectory, "Compiled", "linux", "lib")); | ||
PublicAdditionalLibraries.Add("libBrainflow.a"); | ||
PublicDelayLoadDLLs.Add("libDataHandler.so"); | ||
PublicDelayLoadDLLs.Add("libBoardController.so"); | ||
PublicDelayLoadDLLs.Add("libMLModule.so"); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libBoardController.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libBoardController.so")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libDataHandler.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libDataHandler.so")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libGanglionLib.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libGanglionLib.so")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libMLModule.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libMLModule.so")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libunicorn.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libunicorn.so")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libBrainBitLib.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libBrainBitLib.so")); | ||
RuntimeDependencies.Add("$(TargetOutputDir)/libeego-SDK.so", Path.Combine(ModuleDirectory, "Compiled", "linux", "lib", "libeego-SDK.so")); | ||
|
||
PublicAdditionalLibraries.Add(Path.Combine(PrecompiledFolder, "libBrainflow.a")); | ||
|
||
PublicDelayLoadDLLs.Add(Path.Combine(PrecompiledFolder, "libBoardController.so")); | ||
PublicDelayLoadDLLs.Add(Path.Combine(PrecompiledFolder, "libDataHandler.so")); | ||
PublicDelayLoadDLLs.Add(Path.Combine(PrecompiledFolder, "libMLModule.so")); | ||
|
||
AddRuntimeDependencies(PrecompiledFolder, "*.so"); | ||
} | ||
} | ||
|
||
public void AddRuntimeDependencies(string FolderPath, string Extension) | ||
{ | ||
List<string> Files = Directory.GetFiles(FolderPath, Extension, SearchOption.AllDirectories).ToList(); | ||
foreach (string File in Files) | ||
{ | ||
RuntimeDependencies.Add(Path.Combine(FolderPath, File)); | ||
Console.WriteLine(Name + "adding runtime dependency:" + File); | ||
} | ||
} | ||
} |
125 changes: 114 additions & 11 deletions
125
BrainFlowPlugin/Source/BrainFlowPlugin/Private/BrainFlowPlugin.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,123 @@ | ||
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. | ||
|
||
#include "BrainFlowPlugin.h" | ||
|
||
#define LOCTEXT_NAMESPACE "FBrainFlowPluginModule" | ||
#include <Interfaces/IPluginManager.h> | ||
|
||
#define RUN_EXAMPLE 1 | ||
|
||
#ifdef RUN_EXAMPLE | ||
#include <iostream> | ||
#include <stdlib.h> | ||
#include <string> | ||
|
||
#include "board_shim.h" | ||
#include "data_filter.h" | ||
#endif | ||
|
||
#ifdef RUN_EXAMPLE | ||
template <typename T> | ||
void UEPrint(const T& In) | ||
{ | ||
std::stringstream ss; | ||
ss << In; | ||
std::string dataString = ss.str(); | ||
|
||
void FBrainFlowPluginModule::StartupModule() { | ||
// This code will execute after your module is loaded into memory; the exact | ||
// timing is specified in the .uplugin file per-module | ||
// Unreal's UE_LOG stops at the first '/n', so we are going to remove them from the string so we can see the full message | ||
std::erase(dataString, '\n'); | ||
|
||
const FString StringMessage = UTF8_TO_TCHAR(dataString.c_str()); | ||
|
||
UE_LOG(LogTemp, Warning, TEXT("[Data] %s"), *StringMessage); | ||
} | ||
|
||
void FBrainFlowPluginModule::ShutdownModule() { | ||
// This function may be called during shutdown to clean up your module. For | ||
// modules that support dynamic reloading, we call this function before | ||
// unloading the module. | ||
int RunExample() | ||
{ | ||
if(IsRunningCommandlet()) | ||
{ | ||
return 0; | ||
} | ||
|
||
BoardShim::enable_dev_board_logger (); | ||
|
||
struct BrainFlowInputParams params; | ||
int res = 0; | ||
int board_id = static_cast<int>(BoardIds::SYNTHETIC_BOARD); | ||
// use synthetic board for demo | ||
BoardShim *board = new BoardShim (board_id, params); | ||
|
||
board->prepare_session (); | ||
board->start_stream (); | ||
|
||
FPlatformProcess::Sleep(5); | ||
|
||
board->stop_stream (); | ||
BrainFlowArray<double, 2> data = board->get_board_data (); | ||
board->release_session (); | ||
std::cout << "Original data:" << std::endl << data << std::endl; | ||
UEPrint(data); | ||
|
||
// apply filters | ||
int sampling_rate = BoardShim::get_sampling_rate (static_cast<int>(BoardIds::SYNTHETIC_BOARD)); | ||
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id); | ||
for (int i = 0; i < eeg_channels.size (); i++) | ||
{ | ||
switch (i) | ||
{ | ||
// just for test and demo - apply different filters to different eeg channels | ||
// signal filtering methods work in-place | ||
case 0: | ||
DataFilter::perform_lowpass (data.get_address (eeg_channels[i]), | ||
data.get_size (1), BoardShim::get_sampling_rate (board_id), 50.0, 3, | ||
static_cast<int>(FilterTypes::BUTTERWORTH_ZERO_PHASE), 0); | ||
break; | ||
case 1: | ||
DataFilter::perform_highpass (data.get_address (eeg_channels[i]), | ||
data.get_size (1), BoardShim::get_sampling_rate (board_id), 3.0, 5, | ||
static_cast<int>(FilterTypes::CHEBYSHEV_TYPE_1_ZERO_PHASE), 1); | ||
break; | ||
case 2: | ||
DataFilter::perform_bandpass (data.get_address (eeg_channels[i]), | ||
data.get_size (1), BoardShim::get_sampling_rate (board_id), 3.0, 45.0, 3, | ||
static_cast<int>(FilterTypes::BESSEL_ZERO_PHASE), 0); | ||
break; | ||
case 3: | ||
DataFilter::perform_bandstop (data.get_address (eeg_channels[i]), | ||
data.get_size (1), BoardShim::get_sampling_rate (board_id), 48.0, 62.0, 4, | ||
static_cast<int>(FilterTypes::BUTTERWORTH), 0); | ||
break; | ||
default: | ||
DataFilter::remove_environmental_noise (data.get_address (eeg_channels[i]), | ||
data.get_size (1), BoardShim::get_sampling_rate (board_id), | ||
static_cast<int>(NoiseTypes::FIFTY)); | ||
break; | ||
} | ||
} | ||
std::cout << "Filtered data:" << std::endl << data << std::endl; | ||
UEPrint(data); | ||
|
||
delete board; | ||
return res; | ||
} | ||
#endif | ||
|
||
void FBrainFlowPluginModule::StartupModule() | ||
{ | ||
const FString DllDirectory = IPluginManager::Get().FindPlugin(TEXT("BrainFlowPlugin"))->GetBaseDir() / TEXT("Source/BrainFlowPlugin/Compiled/x64_dynamic/lib/"); | ||
|
||
#undef LOCTEXT_NAMESPACE | ||
FPlatformProcess::PushDllDirectory(*DllDirectory); | ||
#if PLATFORM_WINDOWS | ||
FPlatformProcess::GetDllHandle(*FPaths::Combine(DllDirectory, TEXT("BoardController.dll"))); | ||
FPlatformProcess::GetDllHandle(*FPaths::Combine(DllDirectory, TEXT("DataHandler.dll"))); | ||
FPlatformProcess::GetDllHandle(*FPaths::Combine(DllDirectory, TEXT("MLModule.dll"))); | ||
#endif | ||
FPlatformProcess::PopDllDirectory(*DllDirectory); | ||
|
||
#ifdef RUN_EXAMPLE | ||
RunExample(); | ||
#endif | ||
} | ||
|
||
void FBrainFlowPluginModule::ShutdownModule() | ||
{ | ||
} | ||
|
||
IMPLEMENT_MODULE(FBrainFlowPluginModule, BrainFlowPlugin) |
7 changes: 0 additions & 7 deletions
7
BrainFlowPlugin/Source/BrainFlowPlugin/Public/BrainFlowPlugin.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters