OSSIA
Open Scenario System for Interactive Application
dataflow/nodes/gain.hpp
1 #pragma once
2 #include <ossia/dataflow/graph_node.hpp>
3 #include <ossia/dataflow/port.hpp>
4 
5 namespace ossia::nodes
6 {
7 
8 struct gain_node final : public ossia::nonowning_graph_node
9 {
10 public:
11  double gain{0.005};
12 
13  gain_node()
14  {
15  m_inlets.push_back(&audio_in);
16  m_inlets.push_back(&gain_in);
17  gain_in.target<ossia::value_port>()->type = ossia::decibel_u{};
18  m_outlets.push_back(&audio_out);
19  }
20 
21  void run(const ossia::token_request& t, ossia::exec_state_facade st) noexcept override
22  {
23  auto& vals = gain_in.target<ossia::value_port>()->get_data();
24  if(!vals.empty())
25  gain = ossia::clamp(
26  ossia::linear{ossia::decibel{ossia::convert<float>(vals.back().value)}}
27  .dataspace_value,
28  0.f, 1.f);
29 
30  auto& in = *audio_in;
31  auto& out = *audio_out;
32 
33  const auto [first_pos, N] = st.timings(t);
34  const int64_t last_pos = first_pos + N;
35 
36  const auto channels = in.channels();
37  out.set_channels(channels);
38 
39  for(std::size_t i = 0; i < channels; i++)
40  {
41  auto& in_c = in.channel(i);
42  auto& out_c = out.channel(i);
43 
44  const int64_t cur_chan_size = in_c.size();
45 
46  out_c.resize(st.bufferSize());
47 
48  const auto* input = in_c.data();
49  auto* output = out_c.data();
50  if(cur_chan_size < last_pos)
51  {
52  for(int64_t j = first_pos; j < cur_chan_size; j++)
53  output[j] = gain * input[j];
54 
55  for(int64_t j = cur_chan_size; j < last_pos; j++)
56  output[j] = 0.;
57  }
58  else
59  {
60  for(int64_t j = first_pos; j < last_pos; j++)
61  output[j] = gain * input[j];
62  }
63  }
64  }
65 
66 private:
67  ossia::audio_inlet audio_in;
68  ossia::value_inlet gain_in;
69  ossia::audio_outlet audio_out;
70 };
71 }
constexpr OSSIA_INLINE T clamp(T d, const T min, const T max) noexcept
clamp Returns the value bounded by a min and a max
Definition: math.hpp:154