OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
dmx_buffer.hpp
1#pragma once
2#include <ossia/detail/config.hpp>
3
4#include <ossia/detail/span.hpp>
5
6#include <boost/dynamic_bitset.hpp>
7
8#include <cstdint>
9
10#define DMX_CHANNEL_COUNT 512
11
12namespace ossia::net
13{
14
15struct dmx_config
16{
17 uint32_t frequency{44};
18 uint16_t start_universe{0};
19 uint16_t universe_count{1};
20 uint16_t channels_per_universe{512};
21
22 enum
23 {
24 no_auto,
25 channel_index, // "Channel-123"
26 just_index, // "123"
27 just_universes, // no individual dmx channels, instead create one 512-length array per universe
28 } autocreate{no_auto};
29
30 enum
31 {
32 source, // ossia sends DX
33 sink // ossia receives DMX
34 } mode{source};
35
36 bool multicast{true};
37};
38
39struct dmx_buffer
40{
41 explicit dmx_buffer(int universe_size);
42 ~dmx_buffer();
43
44 int universes() const noexcept { return dirty.size(); }
45 void set_universe_count(int universes)
46 {
47 // Some data is reserved for the case where the last parameter
48 // has a bit depth of 255.. and some padding for safety
49 data.resize(universes * universe_size + 255 + 16);
50 dirty.resize(universes);
51 }
52
53 tcb::span<uint8_t> write_channels(int start, int count) noexcept
54 {
55 int first_universe = start / universe_size;
56 int last_universe = (start + count) / universe_size;
57 assert(first_universe >= 0);
58 assert(first_universe < dirty.size());
59 assert(last_universe >= 0);
60 assert(last_universe < dirty.size());
61
62 for(int i = first_universe; i <= last_universe; i++)
63 dirty[i] = true;
64 return {data.data() + start, std::size_t(count)};
65 }
66
67 tcb::span<uint8_t> write_universe(int u) noexcept
68 {
69 if(data.size() < (u + 1) * universe_size)
70 return {};
71 dirty[u] = true;
72 return {data.data() + u * universe_size, (std::size_t)universe_size};
73 }
74
75 tcb::span<const uint8_t> read_universe(int u) const noexcept
76 {
77 if(data.size() < (u + 1) * universe_size)
78 return {};
79 dirty[u] = false;
80 return {data.data() + u * universe_size, (std::size_t)universe_size};
81 }
82
83 ossia::pod_vector<uint8_t> data;
84 mutable boost::dynamic_bitset<> dirty;
85 int universe_size{};
86};
87
88}