11  halp_meta(name, 
"Spammer")
 
   12  halp_meta(author, 
"ossia team")
 
   13  halp_meta(category, 
"Control/Data processing")
 
   14  halp_meta(description, 
"Send a message at a given frequency")
 
   15  halp_meta(c_name, 
"avnd_pattern_spam")
 
   16  halp_meta(manual_url, 
"https://ossia.io/score-docs/processes/spammer.html")
 
   17  halp_meta(uuid, 
"0fa9415b-dcda-4ab8-b3f5-353c5d35fc8a")
 
   21    halp::val_port<
"Input", ossia::value> input;
 
   23    struct : halp::time_chooser<
"Delay", halp::range{0.0001, 30., 0.2}>
 
   25      using mapper = halp::log_mapper<std::ratio<95, 100>>;
 
   29    halp::knob_f32<
"Smooth", halp::range{0., 1., 0.5}> smooth;
 
   39    m_thread = std::jthread{};
 
   40    inputs.pattern.reprocess();
 
   41    m_thread = std::jthread([
this, roots = this->roots, cur = ossia::value{},
 
   42                             smooth = ossia::value{}](std::stop_token tk) 
mutable {
 
   43      while(!tk.stop_requested())
 
   45        std::this_thread::sleep_for(m_delay.load(std::memory_order_relaxed));
 
   46        float s = m_smooth.load(std::memory_order_relaxed);
 
   47        this->m_buffer.consume(cur);
 
   49        smooth_recursively(smooth, cur, 1.f - s);
 
   56            p->get_parameter()->push_value(cur);
 
   68    m_smooth.store(inputs.smooth.value, std::memory_order_relaxed);
 
   69    m_buffer.produce(inputs.input.value);
 
   72        std::chrono::nanoseconds(int64_t(1e9 * inputs.delay.value)),
 
   73        std::memory_order_release);
 
   74    if(!m_thread.joinable() || inputs.pattern.devices_dirty)
 
   83    void operator()(
const int& in, 
int& filtered)
 
   85      filtered = in * a + filtered * (1.0f - a);
 
   88    void operator()(
const float& in, 
float& filtered)
 
   90      filtered = in * a + filtered * (1.0f - a);
 
   93    void operator()(
const bool& in, 
bool& filtered)
 
   95      filtered = in * a + filtered * (1.0f - a);
 
   98    template <std::
size_t N>
 
   99    void operator()(
const std::array<float, N>& in, std::array<float, N>& filtered)
 
  101      for(std::size_t i = 0; i < N; i++)
 
  102        filtered[i] = in[i] * a + filtered[i] * (1.0f - a);
 
  106    operator()(
const std::vector<ossia::value>& in, std::vector<ossia::value>& filtered)
 
  108      if(in.size() != filtered.size()) [[unlikely]]
 
  109        filtered.resize(in.size());
 
  111      for(std::size_t i = 0; i < in.size(); i++)
 
  113        if(filtered[i].get_type() != in[i].get_type()) [[unlikely]]
 
  116          ossia::apply(*
this, in[i], filtered[i]);
 
  120    void operator()(
const std::string& in, std::string& filtered) { filtered = in; }
 
  121    template <
typename T>
 
  122    void operator()(
const T& in, T& filtered)
 
  127    template <
typename T>
 
  128    void operator()(
const ossia::impulse& in, T& filtered)
 
  130      (*this)(filtered, filtered);
 
  133    void operator()(
const ossia::impulse& in, ossia::impulse& filtered) { }
 
  134    template <
typename T, 
typename U>
 
  135    void operator()(
const T& in, U& filtered)
 
 
  141  smooth_recursively(ossia::value& prev, 
const ossia::value& next, 
float alpha)
 
  143    if(prev.get_type() != next.get_type()) [[unlikely]]
 
  147      if(prev.valid() && next.valid())
 
  148        ossia::apply(
do_smooth{alpha}, next, prev);
 
  152  static_assert(std::atomic<std::chrono::nanoseconds>::is_always_lock_free);
 
  153  std::atomic<std::chrono::nanoseconds> m_delay{std::chrono::nanoseconds{100000}};
 
  154  std::atomic<float> m_smooth{};
 
  155  std::jthread m_thread;
 
  156  ossia::triple_buffer<ossia::value> m_buffer{ossia::value{}};