6#define PDEBUG(...)     Ase::debug ("combo", __VA_ARGS__) 
   18    audio_chain_ (*audiochain)
 
   38    for (
size_t i = 0; i < ni; i++)
 
 
 
   44AudioCombo::AudioCombo (
const ProcessorSetup &psetup) :
 
   48AudioCombo::~AudioCombo ()
 
   60    pos = processors_.size(); 
 
   61  const size_t index = 
CLAMP (pos, 0, processors_.size());
 
   62  processors_.insert (processors_.begin() + index, proc);
 
 
   74  AudioProcessorP processorp;
 
   76  for (pos = 0; pos < processors_.size(); pos++)
 
   77    if (processors_[pos].get() == &proc)
 
   79        processorp = processors_[pos]; 
 
   80        processors_.erase (processors_.begin() + pos);
 
   86  pm_disconnect_ibuses (*processorp);
 
   87  pm_disconnect_obuses (*processorp);
 
 
  100  return processors_[nth];
 
 
  107  for (
size_t i = 0; i < processors_.size(); i++)
 
  108    if (processors_[i].get() == &proc)
 
 
  117  return processors_.size();
 
 
  139  ispeakers_ (iobuses), ospeakers_ (iobuses)
 
  141  assert_return (speaker_arrangement_count_channels (iobuses) > 0);
 
  142  inlet_ = AudioProcessor::create_processor<AudioChain::Inlet> (engine_, 
this);
 
  144  probe_block_ = SERVER->telemem_allocate (
sizeof (ProbeArray));
 
  145  probes_ = 
new (probe_block_.block_start) ProbeArray{};
 
  148AudioChain::~AudioChain()
 
  150  pm_remove_all_buses (*inlet_);
 
  152  probes_->~ProbeArray();
 
  154  SERVER->telemem_release (probe_block_);
 
  158AudioChain::static_info (AudioProcessorInfo &info)
 
  175AudioChain::schedule_children()
 
  177  last_output_ = 
nullptr;
 
  179  for (
auto procp : processors_)
 
  183      if (procp->n_obuses())
 
  184        last_output_ = procp.get();
 
  194  const size_t nlastchannels = last_output_ ? last_output_->
n_ochannels (OUT1) : 0;
 
  197  for (
size_t c = 0; c < n_och; c++)
 
  204            (*probes)[c].dbspl = -192;
 
  208          const float *cblock = last_output_->
ofloats (OUT1, 
std::min (c, nlastchannels - 1));
 
  214              const float sqrsig = 
square_max (n_frames, cblock);
 
  215              const float log2div = 3.01029995663981; 
 
  216              const float db_spl = 
ISLIKELY (sqrsig > 0.0) ? log2div * 
fast_log2 (sqrsig) : -192;
 
  217              (*probes)[c].dbspl = db_spl;
 
 
  229  for (
size_t i = index; i < processors_.size(); i++)
 
  230    pm_disconnect_ibuses (*processors_[i]);
 
  232  for (
size_t i = index; i < processors_.size(); i++)
 
  233    chain_up (*(i ? processors_[i - 1] : inlet_), *processors_[i]);
 
 
  242  const uint ni = next.n_ibuses();
 
  243  const uint no = prev.n_obuses();
 
  247      if (prev.has_event_input())
 
  248        pm_connect_event_input (*eproc_, prev);
 
  249      if (next.has_event_input())
 
  250        pm_connect_event_input (*eproc_, next);
 
  253  if (ni == 0 || no == 0)
 
  255  uint n_connected = 0;
 
  257  const OBusId obusid { 1 };
 
  258  const IBusId ibusid { 1 };
 
  259  SpeakerArrangement ospa = speaker_arrangement_channels (prev.bus_info (obusid).speakers);
 
  260  SpeakerArrangement ispa = speaker_arrangement_channels (next.bus_info (ibusid).speakers);
 
  263       ispa == SpeakerArrangement::STEREO))
 
  265      n_connected += speaker_arrangement_count_channels (ispa);
 
  266      pm_connect (next, ibusid, prev, obusid);
 
 
  272AudioChain::run_probes (
bool enable)
 
  274  if (enable && !probes_enabled_)
 
  275    for (
size_t i = 0; i < probes_->
size(); i++)
 
  276      (*probes_)[i] = Probe{};
 
  277  probes_enabled_ = enable;
 
  278  return probes_enabled_ ? probes_ : 
nullptr;
 
  281static const auto audio_chain_id = register_audio_processor<AudioChain>();
 
void initialize(SpeakerArrangement busses) override
 
void reset(uint64 target_stamp) override
Reset all state variables.
 
void render(uint n_frames) override
 
void render(uint n_frames) override
 
void initialize(SpeakerArrangement busses) override
 
uint chain_up(AudioProcessor &pfirst, AudioProcessor &psecond)
Connect the main audio input of next to audio output of prev.
 
void reconnect(size_t index, bool insertion) override
Reconnect AudioChain child processors at start and after.
 
void reset(uint64 target_stamp) override
Reset all state variables.
 
bool remove(AudioProcessor &proc)
Remove a previously added AudioProcessor proc from the AudioCombo.
 
AudioProcessorS list_processors() const
Retrieve list of AudioProcessorS contained in this AudioCombo.
 
void insert(AudioProcessorP proc, ssize_t pos=~size_t(0))
 
AudioProcessorP at(uint nth)
Return the AudioProcessor at position nth in the AudioCombo.
 
void set_event_source(AudioProcessorP eproc)
Assign event source for future auto-connections of chld processors.
 
size_t size()
Return the number of AudioProcessor instances in the AudioCombo.
 
ssize_t find_pos(AudioProcessor &proc)
Return the index of AudioProcessor proc in the AudioCombo.
 
Audio signal AudioProcessor base class, implemented by all effects and instruments.
 
void redirect_oblock(OBusId b, uint c, const float *block)
Redirect output buffer of bus b, channel c to point to block, or zeros if block==nullptr.
 
void enotify_enqueue_mt(uint32 pushmask)
 
void remove_all_buses()
Remove existing bus configurations, useful at the start of configure().
 
const float * ifloats(IBusId b, uint c) const
Access readonly float buffer of input bus b, channel c, see also ofloats().
 
uint n_ochannels(OBusId busid) const
Number of channels of output bus busid configured for this AudioProcessor.
 
OBusId add_output_bus(CString uilabel, SpeakerArrangement speakerarrangement, const String &hints="", const String &blurb="")
Add an output bus with uilabel and channels configured via speakerarrangement.
 
const float * ofloats(OBusId b, uint c) const
Access readonly float buffer of output bus b, channel c, see also oblock().
 
void reschedule()
Request recreation of the audio engine rendering schedule.
 
IBusId add_input_bus(CString uilabel, SpeakerArrangement speakerarrangement, const String &hints="", const String &blurb="")
Add an input bus with uilabel and channels configured via speakerarrangement.
 
uint schedule_processor()
Schedule this node and its dependencies for engine rendering.
 
uint n_ichannels(IBusId busid) const
Number of channels of input bus busid configured for this AudioProcessor.
 
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
 
#define return_unless(cond,...)
Return silently if cond does not evaluate to true with return value ...
 
#define CLAMP(v, mi, ma)
Yield v clamped to [mi … ma].
 
#define UNLIKELY(cond)
Hint to the compiler to optimize for cond == FALSE.
 
#define ISLIKELY(cond)
Hint to the compiler to optimize for cond == TRUE.
 
The Anklang C++ API namespace.
 
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
IBusId
ID type for AudioProcessor input buses, buses are numbered with increasing index.
 
OBusId
ID type for AudioProcessor output buses, buses are numbered with increasing index.
 
float square_max(uint n_values, const float *ivalues)
Find the maximum suqared value in a block of floats.
 
uint32_t uint
Provide 'uint' as convenience type.