Skip to content

Commit

Permalink
[dmx] Refactor common behaviour across a base class
Browse files Browse the repository at this point in the history
  • Loading branch information
jcelerier committed Feb 21, 2024
1 parent a4836a7 commit 2a1aded
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 247 deletions.
48 changes: 3 additions & 45 deletions src/ossia/protocols/artnet/artnet_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ dmx_buffer::~dmx_buffer() = default;
static constexpr int artnet_port_id = 0;
artnet_protocol::artnet_protocol(
ossia::net::network_context_ptr ctx, const dmx_config& conf)
: protocol_base{flags{}}
, m_context{ctx}
, m_timer{ctx->context}
, m_conf{conf}
: dmx_protocol_base{ctx, conf}
{
if(conf.frequency < 1 || conf.frequency > 44)
throw std::runtime_error("DMX 512 update frequency must be in the range [1, 44] Hz");
Expand Down Expand Up @@ -60,56 +57,17 @@ artnet_protocol::artnet_protocol(

artnet_protocol::~artnet_protocol()
{
m_timer.stop();
stop_processing();
artnet_destroy(m_node);
}

void artnet_protocol::set_device(ossia::net::device_base& dev)
{
m_device = &dev;

if(m_conf.autocreate != m_conf.no_auto)
{
auto& root = dev.get_root_node();
for(unsigned int i = 0; i < DMX_CHANNEL_COUNT; ++i)
{
auto name = m_conf.autocreate == m_conf.channel_index
? fmt::format("Channel-{}", i + 1)
: std::to_string(i + 1);

device_parameter::create_device_parameter<dmx_parameter>(
root, name, 0, m_buffer, i);
}
}
dmx_protocol_base::set_device(dev);

m_timer.start([this] { this->update_function(); });
}

bool artnet_protocol::pull(net::parameter_base& param)
{
return true;
}

bool artnet_protocol::push(const net::parameter_base& param, const ossia::value& v)
{
return true;
}

bool artnet_protocol::observe(net::parameter_base& param, bool enable)
{
return false;
}

bool artnet_protocol::push_raw(const ossia::net::full_parameter_data& data)
{
return false;
}

bool artnet_protocol::update(ossia::net::node_base&)
{
return true;
}

void artnet_protocol::update_function()
{
if(m_buffer.dirty)
Expand Down
28 changes: 2 additions & 26 deletions src/ossia/protocols/artnet/artnet_protocol.hpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,25 @@
#pragma once
#include <ossia/detail/config.hpp>
#if defined(OSSIA_PROTOCOL_ARTNET)
#include <ossia/detail/timer.hpp>
#include <ossia/network/base/protocol.hpp>
#include <ossia/network/common/complex_type.hpp>
#include <ossia/network/context.hpp>
#include <ossia/network/domain/domain.hpp>
#include <ossia/protocols/artnet/dmx_buffer.hpp>

#include <array>
#include <cstdint>
#include <ossia/protocols/artnet/dmx_protocol_base.hpp>

using artnet_node = void*;

namespace ossia::net
{
struct dmx_config;
class OSSIA_EXPORT artnet_protocol final : public ossia::net::protocol_base
class OSSIA_EXPORT artnet_protocol final : public dmx_protocol_base
{
public:
artnet_protocol(ossia::net::network_context_ptr, const dmx_config& conf);
~artnet_protocol();

void set_device(ossia::net::device_base& dev) override;

bool pull(ossia::net::parameter_base& param) override;
bool push(const ossia::net::parameter_base& param, const ossia::value& v) override;
bool push_raw(const ossia::net::full_parameter_data&) override;
bool observe(ossia::net::parameter_base& param, bool enable) override;

bool update(ossia::net::node_base&) override;

dmx_buffer& buffer() noexcept { return m_buffer; }

private:
void update_function();

ossia::net::network_context_ptr m_context;

ossia::timer m_timer;
dmx_buffer m_buffer;

ossia::net::device_base* m_device{};
artnet_node m_node;
dmx_config m_conf{};
};

}
Expand Down
67 changes: 67 additions & 0 deletions src/ossia/protocols/artnet/dmx_protocol_base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "dmx_protocol_base.hpp"

#include <ossia/detail/fmt.hpp>
#include <ossia/protocols/artnet/dmx_parameter.hpp>

namespace ossia::net
{

dmx_protocol_base::dmx_protocol_base(
ossia::net::network_context_ptr ctx, const dmx_config& conf)
: protocol_base{flags{}}
, m_context{ctx}
, m_timer{ctx->context}
, m_conf{conf}
{
}

dmx_protocol_base::~dmx_protocol_base() { }
bool dmx_protocol_base::pull(net::parameter_base& param)
{
return true;
}

bool dmx_protocol_base::push(const net::parameter_base& param, const ossia::value& v)
{
return true;
}

bool dmx_protocol_base::observe(net::parameter_base& param, bool enable)
{
return false;
}

bool dmx_protocol_base::push_raw(const ossia::net::full_parameter_data& data)
{
return false;
}

bool dmx_protocol_base::update(ossia::net::node_base&)
{
return true;
}

void dmx_protocol_base::stop_processing()
{
m_timer.stop();
}

void dmx_protocol_base::set_device(ossia::net::device_base& dev)
{
m_device = &dev;

if(m_conf.autocreate != m_conf.no_auto)
{
auto& root = dev.get_root_node();
for(unsigned int i = 0; i < DMX_CHANNEL_COUNT; ++i)
{
auto name = m_conf.autocreate == m_conf.channel_index
? fmt::format("Channel-{}", i + 1)
: std::to_string(i + 1);

device_parameter::create_device_parameter<dmx_parameter>(
root, name, 0, m_buffer, i);
}
}
}
}
45 changes: 45 additions & 0 deletions src/ossia/protocols/artnet/dmx_protocol_base.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once
#include <ossia/detail/config.hpp>

#include <ossia/detail/timer.hpp>
#include <ossia/network/base/protocol.hpp>
#include <ossia/network/common/complex_type.hpp>
#include <ossia/network/context.hpp>
#include <ossia/network/domain/domain.hpp>
#include <ossia/protocols/artnet/dmx_buffer.hpp>

#include <array>
#include <cstdint>

namespace ossia::net
{
struct dmx_config;
class OSSIA_EXPORT dmx_protocol_base : public ossia::net::protocol_base
{
public:
dmx_protocol_base(ossia::net::network_context_ptr, const dmx_config& conf);
~dmx_protocol_base();

void set_device(ossia::net::device_base& dev) override;

bool pull(ossia::net::parameter_base& param) override;
bool push(const ossia::net::parameter_base& param, const ossia::value& v) override;
bool push_raw(const ossia::net::full_parameter_data&) override;
bool observe(ossia::net::parameter_base& param, bool enable) override;

bool update(ossia::net::node_base&) override;

dmx_buffer& buffer() noexcept { return m_buffer; }
void stop_processing();

protected:
ossia::net::network_context_ptr m_context;

ossia::timer m_timer;
dmx_buffer m_buffer;

ossia::net::device_base* m_device{};
dmx_config m_conf{};
};

}
101 changes: 30 additions & 71 deletions src/ossia/protocols/artnet/dmxusbpro_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,23 @@ namespace ossia::net
dmxusbpro_protocol::dmxusbpro_protocol(
ossia::net::network_context_ptr ctx, const dmx_config& conf,
const ossia::net::serial_configuration& socket)
: protocol_base{flags{}}
, m_context{ctx}
, m_timer{ctx->context}
: dmx_protocol_base{ctx, conf}
, m_port{ctx->context}
, m_conf{conf}
{
if(conf.frequency < 1 || conf.frequency > 44)
throw std::runtime_error("DMX 512 update frequency must be in the range [1, 44] Hz");

{
auto& m_conf = socket;
using proto = boost::asio::serial_port;
m_port.open(m_conf.port);
m_port.open(socket.port);

m_port.set_option(proto::baud_rate(m_conf.baud_rate));
m_port.set_option(proto::character_size(m_conf.character_size));
m_port.set_option(proto::baud_rate(socket.baud_rate));
m_port.set_option(proto::character_size(socket.character_size));
m_port.set_option(proto::flow_control(
static_cast<proto::flow_control::type>(m_conf.flow_control)));
m_port.set_option(proto::parity(static_cast<proto::parity::type>(m_conf.parity)));
static_cast<proto::flow_control::type>(socket.flow_control)));
m_port.set_option(proto::parity(static_cast<proto::parity::type>(socket.parity)));
m_port.set_option(
proto::stop_bits(static_cast<proto::stop_bits::type>(m_conf.stop_bits)));
proto::stop_bits(static_cast<proto::stop_bits::type>(socket.stop_bits)));
}

m_timer.set_delay(std::chrono::milliseconds{
Expand All @@ -36,83 +32,46 @@ dmxusbpro_protocol::dmxusbpro_protocol(

dmxusbpro_protocol::~dmxusbpro_protocol()
{
m_timer.stop();
stop_processing();
}

void dmxusbpro_protocol::set_device(ossia::net::device_base& dev)
{
m_device = &dev;

if(m_conf.autocreate)
{
auto& root = dev.get_root_node();
for(unsigned int i = 0; i < 512; ++i)
device_parameter::create_device_parameter<dmx_parameter>(
root, fmt::format("{}", i + 1), 0, m_buffer, i);
}

dmx_protocol_base::set_device(dev);
m_timer.start([this] { this->update_function(); });
}

bool dmxusbpro_protocol::pull(net::parameter_base& param)
{
return true;
}

bool dmxusbpro_protocol::push(const net::parameter_base& param, const ossia::value& v)
{
return true;
}

bool dmxusbpro_protocol::observe(net::parameter_base& param, bool enable)
{
return false;
}

bool dmxusbpro_protocol::push_raw(const ossia::net::full_parameter_data& data)
{
return false;
}

bool dmxusbpro_protocol::update(ossia::net::node_base&)
{
return true;
}

void dmxusbpro_protocol::update_function()
{
try
{
if(true || m_buffer.dirty)
{
// https://cdn.enttec.com/pdf/assets/70304/70304_DMX_USB_PRO_API.pdf
// 1: 0x7E
// 1: message code (0x6 for DMX send)
// 1: size LSB
// 1: size MSB
// N: message data: [
// 1: start code (0x0 for DMX)
// N-1: DMX channels
// ]
// 1: 0xE7
// https://cdn.enttec.com/pdf/assets/70304/70304_DMX_USB_PRO_API.pdf
// 1: 0x7E
// 1: message code (0x6 for DMX send)
// 1: size LSB
// 1: size MSB
// N: message data: [
// 1: start code (0x0 for DMX)
// N-1: DMX channels
// ]
// 1: 0xE7

constexpr uint32_t channels = 512;
constexpr uint32_t data_size = channels + 1;
constexpr uint32_t buffer_size = 4 + data_size + 1;
constexpr uint32_t channels = 512;
constexpr uint32_t data_size = channels + 1;
constexpr uint32_t buffer_size = 4 + data_size + 1;

constexpr uint8_t data_size_lsb = data_size & 0x00FF;
constexpr uint8_t data_size_msb = (data_size & 0xFF00) >> 8;
constexpr uint8_t data_size_lsb = data_size & 0x00FF;
constexpr uint8_t data_size_msb = (data_size & 0xFF00) >> 8;

unsigned char buf[buffer_size]{0x7E, 0x6, data_size_lsb, data_size_msb, 0};
unsigned char buf[buffer_size]{0x7E, 0x6, data_size_lsb, data_size_msb, 0};

for(uint32_t i = 0; i < channels; i++)
buf[5 + i] = m_buffer.data[i];
buf[buffer_size - 1] = 0xE7;
for(uint32_t i = 0; i < channels; i++)
buf[5 + i] = m_buffer.data[i];
buf[buffer_size - 1] = 0xE7;

boost::asio::write(m_port, boost::asio::buffer(buf));
boost::asio::write(m_port, boost::asio::buffer(buf));

m_buffer.dirty = false;
}
m_buffer.dirty = false;
}
catch(std::exception& e)
{
Expand Down
Loading

0 comments on commit 2a1aded

Please sign in to comment.