OSSIA
Open Scenario System for Interactive Application
merger.hpp
1 #pragma once
2 #include <ossia/dataflow/graph_node.hpp>
3 #include <ossia/dataflow/port.hpp>
4 
5 namespace ossia::nodes
6 {
7 class merger final : public ossia::graph_node
8 {
9  int m_count{};
10 
11 public:
12  merger(int count)
13  : m_count{count}
14  {
15  for(int i = 0; i < count; i++)
16  {
17  auto inl = new ossia::audio_inlet;
18  inl->target<ossia::audio_port>()->set_channels(2);
19  for(auto& channel : *inl->target<ossia::audio_port>())
20  {
21  channel.reserve(512);
22  }
23  m_inlets.push_back(std::move(inl));
24  }
25 
26  m_outlets.push_back(new ossia::audio_outlet);
27  m_outlets.back()->target<ossia::audio_port>()->set_channels(2 * count);
28  for(auto& channel : *m_outlets.back()->target<ossia::audio_port>())
29  {
30  channel.reserve(512);
31  }
32  }
33 
34  ~merger() override = default;
35 
36  void run(const ossia::token_request& t, ossia::exec_state_facade e) noexcept override
37  {
38  auto& op = *m_outlets.back()->target<ossia::audio_port>();
39  op.set_channels(2 * this->m_count);
40  auto& out = op.get();
41  std::size_t cur = 0;
42  for(int i = 0; i < m_count; i++)
43  {
44  auto& in = m_inlets[i]->target<ossia::audio_port>()->get();
45 
46  switch(in.size())
47  {
48  case 1:
49  out[cur++] = in[0];
50  out[cur++] = in[0];
51  break;
52  case 2:
53  out[cur++] = in[0];
54  out[cur++] = in[1];
55  break;
56  default:
57  out[cur++].resize(e.bufferSize());
58  out[cur++].resize(e.bufferSize());
59  break;
60  }
61  }
62 
63  for(auto& c : out)
64  {
65  if(c.size() < e.bufferSize())
66  {
67  c.resize(e.bufferSize());
68  }
69  }
70  }
71 
72  [[nodiscard]] std::string label() const noexcept override { return "Stereo Merger"; }
73 };
74 }