Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Preliminary MacOS support (#51)
Browse files Browse the repository at this point in the history
Progress on #12. Blocked on #52.
  • Loading branch information
lnihlen committed Feb 3, 2020
1 parent f40de03 commit ffff407
Show file tree
Hide file tree
Showing 23 changed files with 199 additions and 70 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ before_script:

script:
- make -j2 swiftshader-local
- make -j2 install
- make -j2 coverage_report
- make -j2 lintall
- make -j2 docs
Expand Down
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ endif()
# project. This version is manually kept in sync and should be updated to match. Both C++ and sclang Scintillator code
# is developed in parallel, and is designed to be released together.
project(Scintillator VERSION 0.0.1 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED)

option(SCIN_BUILD_DOCS
"Add docs build target to build C++ documentation with Doxygen" ON)
option(SCIN_USE_OWN_VULKAN
"Use the Vulkan built from third_party/vulkan-dev instead of system-installed Vulkan SDK" OFF)

# If this is a git checkout we can extract the git hash and branch. This code copied verbatim or close to it from the
# SuperCollider CMake files.
Expand Down Expand Up @@ -59,6 +59,8 @@ set(CMAKE_C_FLAGS_COVERAGE
"${CMAKE_C_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping"
CACHE STRING "C coverage compile flags" FORCE)

find_package(Vulkan REQUIRED FATAL_ERROR)

add_subdirectory(third_party)
add_subdirectory(src)

11 changes: 7 additions & 4 deletions classes/ScinServer.sc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ScinServerOptions {
var <>height;
var <>keepOnTop;
var <>swiftshader;
var <>deviceUUID;

// Can install a function to call if server exits with a non-zero error code.
var <>onServerError;
Expand All @@ -27,7 +28,8 @@ ScinServerOptions {
width: 800,
height: 600,
keepOnTop: true,
swiftshader: false
swiftshader: false,
deviceUUID: nil
)
);
}
Expand Down Expand Up @@ -70,6 +72,9 @@ ScinServerOptions {
if (swiftshader != defaultValues[\swiftshader], {
o = o + "--swiftshader=" ++ swiftshader;
});
if (deviceUUID != defaultValues[\deviceUUID], {
o = o + "--device_uuid=" ++ deviceUUID;
});
^o;
}
}
Expand Down Expand Up @@ -104,7 +109,7 @@ ScinServer {
scinQuarkVersion = "unknown";
});

scinBinaryPath = options.quarkPath +/+ "build/src/scinsynth";
scinBinaryPath = options.quarkPath +/+ "bin" +/+ "scinsynth";
statusPoller = ScinServerStatusPoller.new(this);
}

Expand Down Expand Up @@ -217,14 +222,12 @@ ScinServer {
condition.test = false;
id = UniqueID.next;
response = OSCFunc.new({ |msg|
"got sync: %".format(msg[1]).postln;
if (msg[1] == id, {
response.free;
condition.test = true;
condition.signal;
});
}, '/scin_synced');
"sending sync: %".format(id).postln;
this.sendMsg('/scin_sync', id);
condition.wait;
}
Expand Down
56 changes: 47 additions & 9 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CXX_EXTENSIONS OFF)

set(CMAKE_CXX_STANDARD_REQUIRED)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
Expand Down Expand Up @@ -39,8 +40,12 @@ target_link_libraries(scintillator_core
glm
spdlog
yaml-cpp
stdc++fs
)
if (UNIX AND NOT APPLE)
target_link_libraries(scintillator_core
stdc++fs
)
endif()

#### Unit Testing for Core Files
add_executable(run_unittests
Expand All @@ -58,10 +63,16 @@ target_link_libraries(run_unittests
glm
gtest
scintillator_core
stdc++fs
)
if (UNIX AND NOT APPLE)
target_link_libraries(run_unittests
stdc++fs
)
endif()

#### Scintillator Binary


configure_file(Version.hpp.in "${CMAKE_CURRENT_BINARY_DIR}/Version.hpp")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/osc/commands")
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/osc/commands/Command.cpp"
Expand Down Expand Up @@ -101,6 +112,8 @@ set(scintillator_synth_files

osc/Address.cpp
osc/Address.hpp
osc/BlobMessage.cpp
osc/BlobMessage.hpp
osc/Dispatcher.cpp
osc/Dispatcher.hpp
osc/commands/AdvanceFrame.cpp
Expand Down Expand Up @@ -188,28 +201,53 @@ set(scintillator_synth_files

add_executable(scinsynth ${scintillator_synth_files})

find_package(Vulkan REQUIRED FATAL_ERROR)
# Find the ffmpeg dependencies.
find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)
find_library(AVCODEC_LIBRARY avcodec)
find_path(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)
find_library(AVFORMAT_LIBRARY avformat)
find_path(AVUTIL_INCLUDE_DIR libavutil/avutil.h)
find_library(AVUTIL_LIBRARY avutil)

# Find shaderc
find_library(SHADERC_LIBRARY shaderc_combined)

target_link_libraries(scinsynth
"${SCIN_EXT_INSTALL_DIR}/lib/liblo.a"
"${Vulkan_LIBRARY}"
${AVCODEC_LIBRARY}
${AVFORMAT_LIBRARY}
${AVUTIL_LIBRARY}
${SHADERC_LIBRARY}
VulkanMemoryAllocator
avcodec
avformat
avutil
gflags
glfw
glm
scintillator_core
shaderc_combined
spdlog
stdc++fs
)

target_include_directories(scinsynth PRIVATE
${AVCODEC_INCLUDE_DIR}
${AVFORMAT_INCLUDE_DIR}
${AVUTIL_INCLUDE_DIR}
)

if (UNIX AND NOT APPLE)
target_link_libraries(scinsynth
stdc++fs
)
endif()

add_dependencies(scinsynth
liblo-install
)

file(MAKE_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
install(TARGETS scinsynth
RUNTIME
DESTINATION "${PROJECT_SOURCE_DIR}/bin")

#### Automatic Code Formatting and Linting
if (NOT DEFINED CLANG_FORMAT)
set(CLANG_FORMAT clang-format-8)
Expand Down
6 changes: 6 additions & 0 deletions src/core/Intrinsic.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

#include <cstring>

// Some of the gperf generated code uses the register keyword, which is deprecated in C++17.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wregister"

namespace {

%}
Expand All @@ -19,6 +23,8 @@ time, scin::core::Intrinsic::kTime

} // namespace

#pragma clang diagnostic pop

namespace scin { namespace core {

Intrinsic getIntrinsicNamed(const std::string& name) {
Expand Down
12 changes: 12 additions & 0 deletions src/doc/Building-scinsynth.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,15 @@ in varying levels of invasiveness, suggested on StackOverflow as well as elsewhe

The way we do it on travis-ci right now is to supply -DPYTHON_EXECUTABLE=`which python3` to cmake as an argument.


MacOS
-----

You will need the Vulkan SDK for macOS. The instructions
[here](https://vulkan.lunarg.com/doc/sdk/1.1.130.0/mac/getting_started.html) detail how to install it. Running the
install script makes for an easier configuration.

```
brew install ffmpeg doxygen
```

31 changes: 31 additions & 0 deletions src/osc/BlobMessage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "BlobMessage.hpp"

#include <cstring>

namespace scin { namespace osc {

BlobMessage::BlobMessage(): m_size(0) {}

BlobMessage::~BlobMessage() {
if (m_message) {
lo_message_free(m_message);
m_message = nullptr;
}
}

bool BlobMessage::extract(lo_blob blob) {
m_size = lo_blob_datasize(blob);
if (m_size == 0) {
return false;
}
m_bytes.reset(new uint8_t[m_size]);
std::memcpy(m_bytes.get(), lo_blob_dataptr(blob), m_size);
m_message = lo_message_deserialise(m_bytes.get(), m_size, nullptr);
if (!m_message) {
return false;
}
return true;
}

} // namespace osc
} // namespace scin
30 changes: 30 additions & 0 deletions src/osc/BlobMessage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef SRC_OSC_BLOB_MESSAGE_HPP_
#define SRC_OSC_BLOB_MESSAGE_HPP_

#include "lo/lo.h"

#include <memory>

namespace scin { namespace osc {
/*! Can extract a copy of a message from a OSC blob lo_blob data structure.
*/
class BlobMessage {
public:
BlobMessage();
~BlobMessage();

bool extract(lo_blob blob);

lo_message message() { return m_message; }
const char* path() const { return reinterpret_cast<const char*>(m_bytes.get()); }

private:
std::unique_ptr<uint8_t[]> m_bytes;
uint32_t m_size;
lo_message m_message;
};

} // namespace osc
} // namespace scin

#endif // SRC_OSC_BLOB_MESSAGE_HPP_
22 changes: 6 additions & 16 deletions src/osc/Dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "Version.hpp"
#include "av/ImageEncoder.hpp"
#include "core/Archetypes.hpp"
#include "osc/Address.hpp"
#include "osc/BlobMessage.hpp"
#include "osc/commands/AdvanceFrame.hpp"
#include "osc/commands/DefFree.hpp"
#include "osc/commands/DefLoad.hpp"
Expand Down Expand Up @@ -142,22 +144,10 @@ void Dispatcher::callQuitHandler(std::shared_ptr<Address> quitOrigin) {
m_quitHandler();
}

void Dispatcher::processMessageFrom(lo_address address, std::shared_ptr<uint8_t[]> data, uint32_t dataSize) {
// TODO: Internally this is how lo extracts address from an OSC message binary. Any way to make this safer?
char* path = reinterpret_cast<char*>(data.get());
// int pathLength = lo_validate_string(path, dataSize);
// if (pathLength < 0) {
// spdlog::error("Dispatcher failed to extract path from injected message data.");
// return;
//}

lo_message message = lo_message_deserialise(data.get(), dataSize, nullptr);
if (!message) {
spdlog::error("Dispatcher failed to deserialize injected message.");
return;
}
dispatch(path, lo_message_get_argc(message), lo_message_get_argv(message), lo_message_get_types(message), address);
lo_message_free(message);
void Dispatcher::processMessageFrom(lo_address address, std::shared_ptr<BlobMessage> blobMessage) {
lo_message message = blobMessage->message();
dispatch(blobMessage->path(), lo_message_get_argc(message), lo_message_get_argv(message),
lo_message_get_types(message), address);
}

// static
Expand Down
6 changes: 4 additions & 2 deletions src/osc/Dispatcher.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef SRC_OSC_DISPATCHER_HPP_
#define SRC_OSC_DISPATCHER_HPP_

#include "osc/Address.hpp"
#include "osc/commands/Command.hpp"

#include "lo/lo.h"
Expand All @@ -28,6 +27,9 @@ class Offscreen;

namespace osc {

class Address;
class BlobMessage;

/*! The primary interface to the OSC subsystem. Manages bound ports and listening threads, and dispatches incoming OSC
* commands for processing.
*/
Expand Down Expand Up @@ -111,7 +113,7 @@ class Dispatcher {
std::shared_ptr<const vk::FrameTimer> frameTimer() { return m_frameTimer; }
void callQuitHandler(std::shared_ptr<Address> quitOrigin);
void setDumpOSC(bool enable) { m_dumpOSC = enable; }
void processMessageFrom(lo_address address, std::shared_ptr<uint8_t[]> data, uint32_t dataSize);
void processMessageFrom(lo_address address, std::shared_ptr<BlobMessage> onCompletion);

private:
static void loError(int number, const char* message, const char* path);
Expand Down
6 changes: 6 additions & 0 deletions src/osc/commands/Command.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

#include <cstring>

// Some of the gperf generated code uses the register keyword, which is deprecated in C++17.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wregister"

namespace {

%}
Expand Down Expand Up @@ -34,6 +38,8 @@ sleepFor, scin::osc::commands::Command::Number::kSleepFor

} // namespace

#pragma clang diagnostic pop

namespace scin { namespace osc { namespace commands {

// static
Expand Down

0 comments on commit ffff407

Please sign in to comment.