-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
305 additions
and
0 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,84 @@ | ||
find_path(LIBMAPPER_INCLUDE_DIR | ||
mapper/mapper.h | ||
HINTS | ||
/opt/libmapper/include | ||
) | ||
|
||
find_library(LIBMAPPER_LIBRARIES mapper | ||
HINTS | ||
/opt/libmapper/lib | ||
) | ||
|
||
if(LIBMAPPER_INCLUDE_DIR AND LIBMAPPER_LIBRARIES) | ||
add_library(mapper INTERFACE) | ||
target_include_directories(mapper INTERFACE "${LIBMAPPER_INCLUDE_DIR}") | ||
target_link_libraries(mapper INTERFACE "${LIBMAPPER_LIBRARIES}") | ||
endif() | ||
|
||
if(NOT LIBMAPPER_INCLUDE_DIR) | ||
function(avnd_make_libmapper) | ||
endfunction() | ||
|
||
return() | ||
endif() | ||
|
||
function(avnd_make_libmapper) | ||
cmake_parse_arguments(AVND "" "TARGET;MAIN_FILE;MAIN_CLASS;C_NAME" "" ${ARGN}) | ||
|
||
string(MAKE_C_IDENTIFIER "${AVND_MAIN_CLASS}" MAIN_OUT_FILE) | ||
|
||
configure_file( | ||
"${AVND_SOURCE_DIR}/include/avnd/binding/libmapper/prototype.cpp.in" | ||
"${CMAKE_BINARY_DIR}/${MAIN_OUT_FILE}_libmapper.cpp" | ||
@ONLY | ||
NEWLINE_STYLE LF | ||
) | ||
|
||
set(AVND_FX_TARGET "${AVND_TARGET}_libmapper") | ||
add_executable(${AVND_FX_TARGET}) | ||
|
||
set_target_properties( | ||
${AVND_FX_TARGET} | ||
PROPERTIES | ||
OUTPUT_NAME "${AVND_C_NAME}" | ||
LIBRARY_OUTPUT_DIRECTORY libmapper | ||
RUNTIME_OUTPUT_DIRECTORY libmapper | ||
) | ||
|
||
target_sources( | ||
${AVND_FX_TARGET} | ||
PRIVATE | ||
"${AVND_MAIN_FILE}" | ||
"${CMAKE_BINARY_DIR}/${MAIN_OUT_FILE}_libmapper.cpp" | ||
) | ||
|
||
target_include_directories( | ||
${AVND_FX_TARGET} | ||
PRIVATE | ||
"${LIBMAPPER_INCLUDE_DIR}" | ||
) | ||
|
||
target_compile_definitions( | ||
${AVND_FX_TARGET} | ||
PRIVATE | ||
AVND_LIBMAPPER=1 | ||
) | ||
|
||
target_link_libraries( | ||
${AVND_FX_TARGET} | ||
PRIVATE | ||
Avendish::Avendish_libmapper | ||
mapper | ||
DisableExceptions | ||
) | ||
|
||
avnd_common_setup("${AVND_TARGET}" "${AVND_FX_TARGET}") | ||
endfunction() | ||
|
||
add_library(Avendish_libmapper INTERFACE) | ||
target_link_libraries(Avendish_libmapper INTERFACE Avendish) | ||
add_library(Avendish::Avendish_libmapper ALIAS Avendish_libmapper) | ||
|
||
target_sources(Avendish PRIVATE | ||
"${AVND_SOURCE_DIR}/include/avnd/binding/libmapper/libmapper.hpp" | ||
) |
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,14 @@ | ||
#pragma once | ||
#include <avnd/wrappers/configure.hpp> | ||
#include <avnd/helpers/log.hpp> | ||
|
||
#include <utility> | ||
|
||
namespace libmapper | ||
{ | ||
struct config | ||
{ | ||
using logger_type = avnd::basic_logger; | ||
}; | ||
|
||
} |
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,181 @@ | ||
#pragma once | ||
|
||
/* SPDX-License-Identifier: GPL-3.0-or-later */ | ||
|
||
#include <avnd/wrappers/avnd.hpp> | ||
#include <avnd/wrappers/controls.hpp> | ||
#include <avnd/wrappers/process_adapter.hpp> | ||
#include <avnd/introspection/messages.hpp> | ||
#include <avnd/common/export.hpp> | ||
#include <avnd/helpers/callback.hpp> | ||
|
||
|
||
#include <mapper/mapper_cpp.h> | ||
|
||
|
||
#include <span> | ||
#include <cmath> | ||
#include <string> | ||
|
||
namespace libmapper | ||
{ | ||
template <typename T> | ||
struct processor | ||
{ | ||
T& t; | ||
mapper::Device dev; | ||
|
||
|
||
static constexpr const int input_controls = avnd::parameter_input_introspection<T>::size; | ||
static constexpr const int output_controls = avnd::parameter_output_introspection<T>::size; | ||
|
||
std::array<mapper::Signal, input_controls> input_signals; | ||
std::array<mapper::Signal, output_controls> output_signals; | ||
|
||
template <auto Idx, typename C> | ||
static std::string input_name(avnd::field_reflection<Idx, C>) | ||
{ | ||
if constexpr (requires { C::name(); }) | ||
return "/" + std::string(C::name()); | ||
else | ||
return "/in." + std::to_string(Idx); | ||
} | ||
|
||
template <auto Idx, typename C> | ||
static std::string output_name(avnd::field_reflection<Idx, C>) | ||
{ | ||
if constexpr (requires { C::name(); }) | ||
return "/" + std::string(C::name()); | ||
else | ||
return "/out." + std::to_string(Idx); | ||
} | ||
|
||
template <auto Idx, typename C> | ||
void setup_input(avnd::field_reflection<Idx, C> refl) | ||
{ | ||
using namespace std::literals; | ||
{ | ||
const std::string param_name = input_name(refl); | ||
if constexpr(avnd::float_parameter<C>) | ||
{ | ||
std::cerr << param_name << std::endl; | ||
static auto callback = [] (mapper::Signal&& sig, float value, mapper::Time&& time) { | ||
T& obj = *(T*)(void*)sig["object"]; | ||
boost::pfr::get<Idx>(obj.inputs).value = value; | ||
}; | ||
if constexpr(requires { C::control(); }) | ||
{ | ||
static const auto ctl = C::control(); | ||
input_signals[Idx] = dev.add_signal( | ||
mapper::Direction::INCOMING, param_name, 1, | ||
mapper::Type::FLOAT, "", (void*)&ctl.min, (void*)&ctl.max, nullptr) | ||
.set_property("object", (void*)&t) | ||
.set_callback(callback, mapper::Signal::Event::UPDATE); | ||
} | ||
else | ||
{ | ||
static float min0 = 0.f; | ||
static float max1 = 1.f; | ||
input_signals[Idx] = dev.add_signal( | ||
mapper::Direction::INCOMING, param_name, 1, | ||
mapper::Type::FLOAT, "", (void*)&min0, (void*)&max1, nullptr) | ||
.set_property("object", (void*)&t) | ||
.set_callback(callback, mapper::Signal::Event::UPDATE); | ||
} | ||
} | ||
else if constexpr(avnd::int_parameter<C>) | ||
{ | ||
static auto callback = [] (mapper::Signal&& sig, int value, mapper::Time&& time) { | ||
T& obj = *(T*)(void*)sig["object"]; | ||
boost::pfr::get<Idx>(obj.inputs).value = value; | ||
}; | ||
if constexpr(requires { C::control(); }) | ||
{ | ||
static const auto ctl = C::control(); | ||
input_signals[Idx] = dev.add_signal( | ||
mapper::Direction::INCOMING, param_name, 1, | ||
mapper::Type::INT32, "", (void*)&ctl.min, (void*)&ctl.max, nullptr) | ||
.set_property("object", (void*)&t) | ||
.set_callback(callback, mapper::Signal::Event::UPDATE); | ||
} | ||
} | ||
} | ||
} | ||
|
||
template <auto Idx, typename C> | ||
void setup_output(avnd::field_reflection<Idx, C> refl) | ||
{ | ||
using namespace std::literals; | ||
{ | ||
const std::string param_name = output_name(refl); | ||
|
||
if constexpr(avnd::float_parameter<C>) | ||
{ | ||
if constexpr(requires { C::control(); }) | ||
{ | ||
static const auto ctl = C::control(); | ||
output_signals[Idx] = dev.add_signal( | ||
mapper::Direction::OUTGOING, param_name, 1, | ||
mapper::Type::FLOAT, "", (void*)&ctl.min, (void*)&ctl.max, nullptr); | ||
} | ||
else | ||
{ | ||
static float min0 = 0.f; | ||
static float max1 = 1.f; | ||
output_signals[Idx] = dev.add_signal( | ||
mapper::Direction::OUTGOING, param_name, 1, | ||
mapper::Type::FLOAT, "", (void*)&min0, (void*)&max1, nullptr); | ||
} | ||
} | ||
else if constexpr(avnd::int_parameter<C>) | ||
{ | ||
if constexpr(requires { C::control(); }) | ||
{ | ||
static const auto ctl = C::control(); | ||
output_signals[Idx] = dev.add_signal( | ||
mapper::Direction::OUTGOING, param_name, 1, | ||
mapper::Type::INT32, "", (void*)&ctl.min, (void*)&ctl.max, nullptr); | ||
} | ||
} | ||
} | ||
} | ||
|
||
explicit processor(T& t) | ||
: t{t} | ||
, dev{T::name()} | ||
{ | ||
if constexpr (avnd::inputs_is_value<T>) | ||
{ | ||
avnd::parameter_input_introspection<T>::for_all([this](auto a) | ||
{ setup_input(a); }); | ||
} | ||
|
||
if constexpr (avnd::outputs_is_value<T>) | ||
{ | ||
avnd::parameter_output_introspection<T>::for_all([this](auto a) | ||
{ setup_output(a); }); | ||
} | ||
fflush(stdout); | ||
fflush(stderr); | ||
} | ||
|
||
void poll() | ||
{ | ||
dev.poll(10); | ||
} | ||
|
||
void commit() | ||
{ | ||
if constexpr (avnd::outputs_is_value<T>) | ||
{ | ||
int k = 0; | ||
avnd::parameter_output_introspection<T>::for_all( | ||
t.outputs, | ||
[this, &k] (auto& c) { | ||
mapper::Signal& sig = this->output_signals[k++]; | ||
sig.set_value(c.value); | ||
}); | ||
} | ||
} | ||
}; | ||
} |
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,26 @@ | ||
/* SPDX-License-Identifier: GPL-3.0-or-later */ | ||
|
||
#include <@AVND_MAIN_FILE@> | ||
#include <avnd/binding/libmapper/configure.hpp> | ||
#include <avnd/binding/libmapper/libmapper.hpp> | ||
|
||
void run(auto& t) | ||
{ | ||
if_possible(t()); | ||
} | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
// Create the object | ||
using type = decltype(avnd::configure<libmapper::config, @AVND_MAIN_CLASS@>())::type; | ||
|
||
type t; | ||
static libmapper::processor< type > instance{t}; | ||
|
||
while (true) | ||
{ | ||
instance.poll(); | ||
run(t); | ||
instance.commit(); | ||
} | ||
} |