17  halp_meta(name, 
"Expression Audio Generator")
 
   18  halp_meta(c_name, 
"MathAudioGenerator")
 
   19  halp_meta(category, 
"Audio/Utilities")
 
   20  halp_meta(manual_url, 
"https://ossia.io/score-docs/processes/exprtk.html#exprtk-support")
 
   21  halp_meta(author, 
"ossia score, ExprTK (Arash Partow)")
 
   24      "Generate an audio signal from a math expression.\n" 
   25      "Available variables: a,b,c, t (samples), fs (sampling frequency)\n" 
   26      "See the documentation at http://www.partow.net/programming/exprtk")
 
   27  halp_meta(uuid, 
"eae294b3-afeb-4fba-bbe4-337998d3748a")
 
   33        "var phi := 2 * pi * (20 + a * 500) / fs;\n" 
   36        "out[0] := b * sin(m1[0]);\n" 
   37        "out[1] := b * sin(m1[0]);\n">
 
   40    halp::hslider_f32<
"Param (a)", halp::range{0., 1., 0.5}> a;
 
   41    halp::hslider_f32<
"Param (b)", halp::range{0., 1., 0.5}> b;
 
   42    halp::hslider_f32<
"Param (c)", halp::range{0., 1., 0.5}> c;
 
   47    halp::variable_audio_bus<
"out", 
double> audio;
 
   63      expr.add_vector(
"out", cur_out);
 
   64      expr.add_variable(
"t", cur_time);
 
   65      expr.add_variable(
"a", a);
 
   66      expr.add_variable(
"b", b);
 
   67      expr.add_variable(
"c", c);
 
   68      expr.add_variable(
"pa", pa);
 
   69      expr.add_variable(
"pb", pb);
 
   70      expr.add_variable(
"pc", pc);
 
   71      expr.add_vector(
"m1", m1);
 
   72      expr.add_vector(
"m2", m2);
 
   73      expr.add_vector(
"m3", m3);
 
   74      expr.add_variable(
"fs", fs);
 
   77      expr.register_symbol_table();
 
   80    void reset_symbols(std::size_t N)
 
   83      if(N == cur_out.size())
 
   91      expr.rebase_vector(
"out", cur_out);
 
   92      expr.rebase_vector(
"m1", m1);
 
   93      expr.rebase_vector(
"m2", m2);
 
   94      expr.rebase_vector(
"m3", m3);
 
   96    std::vector<double> cur_out{};
 
   99    double pa{}, pb{}, pc{};
 
  100    std::vector<double> m1, m2, m3;
 
  102    ossia::math_expression expr;
 
 
  107  static constexpr int chans = 2; 
 
  108  void prepare(halp::setup s)
 
  111    outputs.audio.request_channels(chans);
 
  112    state.reset_symbols(chans);
 
  115  using tick = halp::tick_flicks;
 
  116  void operator()(
const tick& tk)
 
  121      self.fs = setup.rate;
 
  122      if(!self.expr.set_expression(inputs.expr))
 
  125      self.reset_symbols(chans);
 
  126      self.a = this->inputs.a;
 
  127      self.b = this->inputs.b;
 
  128      self.c = this->inputs.c;
 
  129      for(int64_t i = 0; i < tk.frames; i++)
 
  137        auto& channels = this->outputs.audio.samples;
 
  138        for(
int j = 0; j < std::min(chans, outputs.audio.channels); j++)
 
  140          channels[j][i] = self.cur_out[j];
 
  151    halp_meta(layout, halp::layouts::vbox)
 
  154      halp_meta(layout, halp::layouts::hbox)
 
  155      halp::control<&ins::a> a;
 
  156      halp::control<&ins::b> b;
 
  157      halp::control<&ins::c> c;
 
  160    struct : halp::control<&ins::expr>
 
  162      halp_flag(dynamic_size);