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.