2#ifndef __ASE_PROCESSOR_HH__
3#define __ASE_PROCESSOR_HH__
18ASE_DEFINE_ENUM_EQUALITY (
ParamId);
22ASE_DEFINE_ENUM_EQUALITY (
IBusId);
26ASE_DEFINE_ENUM_EQUALITY (
OBusId);
57 double *values =
nullptr;
87 bool operator== (
const OConnection &o)
const {
return proc == o.proc && ibusid == o.ibusid; }
97 enum { INITIALIZED = 1 << 0,
100 PARAMCHANGE = 1 << 3,
102 BUSDISCONNECT = 1 << 5,
105 ENGINE_OUTPUT = 1 << 8,
109 uint32 output_offset_ = 0;
122 template<
class F>
void modify_t0events (
const F&);
123 void assign_iobufs ();
124 void release_iobufs ();
125 void ensure_initialized (DeviceP devicep);
130 void render_block (
uint64 target_stamp);
131 void reset_state (
uint64 target_stamp);
133 virtual void render (
uint n_frames) = 0;
134 virtual void reset (
uint64 target_stamp) = 0;
135 PropertyS access_properties ()
const;
150 virtual uint schedule_children () {
return 0; }
156 virtual void adjust_param (uint32_t paramid) {}
166 const IOBus&
iobus (
OBusId busid)
const {
return const_cast<AudioProcessor*
> (
this)->
iobus (busid); }
167 const IOBus&
iobus (
IBusId busid)
const {
return const_cast<AudioProcessor*
> (
this)->
iobus (busid); }
185 using MakeProcessor = AudioProcessorP (*) (AudioEngine&);
191 String debug_name ()
const;
194 uint sample_rate () const ASE_CONST;
195 double nyquist () const ASE_CONST;
204 void adjust_all_params ();
207 virtual
double value_to_normalized (
Id32 paramid,
double value) const;
208 virtual
double value_from_normalized (
Id32 paramid,
double normalized) const;
242 template<class AudioProc, class ...Args>
std::shared_ptr<AudioProc>
245 static
bool enotify_pending ();
246 static
void enotify_dispatch ();
248 AudioProcessorP nqueue_guard_;
250 static constexpr uint32 NOTIFYMASK = PARAMCHANGE | BUSCONNECT | BUSDISCONNECT | INSERTION | REMOVAL;
251 static __thread
uint64 tls_timestamp;
260 alignas (64)
float fblock[AUDIO_BLOCK_MAX_RENDER_SIZE] = { 0, };
261 const uint64 canary0_ = const_canary;
262 const uint64 canary1_ = const_canary;
263 struct {
uint64 d1, d2, d3, d4; };
266 static constexpr uint64 const_canary = 0xE14D8A302B97C56F;
269 float *buffer = &fblock[0];
280 {
return p.
connect (i, d, o); }
288 enum IOTag :
uint { IBUS = 1, OBUS = 2 };
298 uint fbuffer_concounter;
302 uint mem_[4] = { 0, 0, 0, 0 };
309 static constexpr auto EVENT_ISTREAM =
IBusId (0xff01);
312 bool has_event_input =
false;
313 bool has_event_output =
false;
320 if (
id - 1 < count && ids[
id - 1] ==
id) [[likely]]
322 if (
id < count && ids[
id] ==
id) [[likely]]
325 [] (
auto a,
auto b) {
return a < b ? -1 : a > b; },
327 return found ? it - ids : -1;
334 const auto idx =
index (
id);
335 return idx < 0 ? 0.0 : values[idx];
342 const auto idx =
index (
id);
343 if (idx < 0)
return 0.0;
344 const double old = values[idx];
345 values[idx] = newval;
346 if (!wprops[idx].expired()) {
357 return bits[idx >> 6] &
uint64_t (1) << (idx & (64-1));
365 bits[idx >> 6] |=
uint64_t (1) << (idx & (64-1));
367 bits[idx >> 6] &= ~(
uint64_t (1) << (idx & (64-1)));
371template<
class F>
void
372AudioProcessor::modify_t0events (
const F &mod)
375 MidiEventVector *t0events =
nullptr;
376 t0events = t0events_.
exchange (t0events);
380 if (!t0events->empty())
381 t0events = t0events_.
exchange (t0events);
391 case MidiEvent::PARAM_VALUE:
392 params_.
value (event.param, event.pvalue);
405 for (
const auto &event : evinput)
408 case MidiEvent::PARAM_VALUE:
410 adjust_param (event.param);
420 return speaker_arrangement_count_channels (
speakers);
434 return engine_.transport();
438AudioProcessor::sample_rate ()
const
440 return engine_.sample_rate();
447 return engine_.nyquist();
454 return engine_.inyquist();
461 return estreams_ && estreams_->has_event_input;
468 return estreams_ && estreams_->has_event_output;
475 return output_offset_;
482 return iobuses_.size() - output_offset_;
489 return iobus (busid);
496 return iobus (busid);
517AudioProcessor::adjust_all_params()
519 for (
size_t idx = 0; idx < params_.count; idx++)
520 adjust_param (params_.ids[idx]);
528 if (idx < 0) [[unlikely]]
530 return params_.values[idx];
539 if (idx < 0) [[unlikely]]
548 return float_buffer (b, c).buffer;
555 return const_cast<AudioProcessor*
> (
this)->float_buffer (b, c).buffer;
563 return float_buffer (b, c,
true).buffer;
570 return tls_timestamp;
575AudioProcessor::FloatBuffer::speaker_arrangement ()
const
577 return speaker_arrangement_;
581template<
typename T>
extern inline CString
584 CString aseid = caseid ? caseid : typeid_name<T>();
594 static_assert (
sizeof (T) < 0,
"type `T` must be constructible from `T(AudioEngine&)`");
599AudioProcessor::create_processor (AudioEngine &
engine,
const Args &...args)
601 String aseid = typeid_name<AudioProc>();
602 const ProcessorSetup psetup { aseid,
engine };
605 AudioProcessorP aproc = proc;
606 aproc->ensure_initialized (
nullptr);
Vector of atomic bits, operates in blocks of 64 bits.
Audio signal AudioProcessor base class, implemented by all effects and instruments.
bool set_normalized(Id32 paramid, double normalized)
Set param value normalized into 0…1.
static const String GUIONLY
":G:r:w:" - GUI READABLE WRITABLE
static uint64 timestamp()
The current timestamp in sample frames.
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)
BusInfo bus_info(IBusId busid) const
Retrieve BusInfo for an input bus.
void remove_all_buses()
Remove existing bus configurations, useful at the start of configure().
float note_to_freq(int note) const
Convert MIDI note to Hertz according to the current MusicalTuning.
const float * ifloats(IBusId b, uint c) const
Access readonly float buffer of input bus b, channel c, see also ofloats().
void apply_input_events()
IBusId find_ibus(const String &name) const
Return the IBusId for input bus uilabel or else 0.
double get_param(Id32 paramid)
Fetch value of parameter id.
double inyquist() const
Inverse Nyquist frequency, i.e. 1.0 / nyquist().
void prepare_event_input()
IOBus & iobus(OBusId busid)
Get internal output bus handle.
virtual String param_value_to_text(uint32_t paramid, double value) const
bool send_param(Id32 paramid, double value)
Set parameter id to value within ParamInfo.get_minmax().
MidiEventInput midi_event_input()
Access the current MidiEvent inputs during render(), needs prepare_event_input().
MidiEventOutput & midi_event_output()
Access the current output EventStream during render(), needs prepare_event_output().
uint n_ibuses() const
Number of input buses configured for this AudioProcessor.
uint n_ochannels(OBusId busid) const
Number of channels of output bus busid configured for this AudioProcessor.
virtual double param_value_from_text(uint32_t paramid, const String &text) const
const AudioTransport & transport() const
Sample rate mixing frequency in Hz as unsigned, used for render().
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().
bool has_event_input() const
Returns true if this AudioProcessor has an event input stream.
bool is_initialized() const
Check if AudioProcessor has been properly intiialized (so the parameter set is fixed).
void atomic_bits_resize(size_t count)
Prepare count bits for atomic notifications.
void reschedule()
Request recreation of the audio engine rendering schedule.
void prepare_event_output()
AtomicBits::Iter atomic_bits_iter(size_t pos=0) const
Allow iterations over the atomic bits.
MaybeParamId find_param(const String &identifier) const
Return the ParamId for parameter identifier or else 0.
void connect_event_input(AudioProcessor &oproc)
Connect event input to event output of AudioProcessor oproc.
uint text_param_to_quark(uint32_t paramid, const String &text)
Ase main-thread helper for temporary string<->uint conversions.
double get_normalized(Id32 paramid)
Get param value normalized into 0…1.
static void registry_foreach(const std::function< void(const String &aseid, StaticInfo)> &fun)
Iterate over the known AudioProcessor types.
void disconnect_obuses()
Disconnect inputs of all Processors that are connected to outputs of this.
bool atomic_bit_notify(size_t nth)
Set the nth atomic notification bit, return if enotify_enqueue_mt() is needed.
ParameterC parameter(Id32 paramid) const
Retrieve supplemental information for parameters, usually to enhance the user interface.
String text_param_from_quark(uint32_t paramid, uint vint)
Helper for temporary uint<->string conversions.
double peek_param_mt(Id32 paramid) const
AudioEngine & engine() const
Retrieve AudioEngine handle for this AudioProcessor.
void disconnect(IBusId ibus)
Disconnect input ibusid.
virtual void initialize(SpeakerArrangement busses)=0
bool connected(OBusId obusid) const
MinMax param_range(Id32 paramid) const
Retrieve the minimum / maximum values for a parameter.
void enable_engine_output(bool onoff)
Configure if the main output of this module is mixed into the engine output.
bool check_dirty(Id32 paramid) const
void apply_event(const MidiEvent &event)
Assign MidiEvent::PARAM_VALUE event values to parameters.
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.
virtual ~AudioProcessor()
The destructor is called when the last std::shared_ptr<> reference drops.
uint n_obuses() const
Number of output buses configured for this AudioProcessor.
uint schedule_processor()
Schedule this node and its dependencies for engine rendering.
static double param_peek_mt(const AudioProcessorP proc, Id32 paramid)
bool has_event_output() const
Returns true if this AudioProcessor has an event output stream.
double nyquist() const
Half the sample rate in Hz as double, used for render().
void disconnect_ibuses()
Reset input bus buffer data.
static void registry_add(CString aseid, StaticInfo, MakeProcessorP)
uint n_ichannels(IBusId busid) const
Number of channels of input bus busid configured for this AudioProcessor.
void disconnect_event_input()
Disconnect event input if a connection is present.
void install_params(const AudioParams::Map ¶ms)
Reset list of parameters, enqueues parameter value initializaiton events.
float * oblock(OBusId b, uint c)
static const String STANDARD
":G:S:r:w:" - GUI STORAGE READABLE WRITABLE
OBusId find_obus(const String &name) const
Return the OBusId for output bus uilabel or else 0.
void assign_oblock(OBusId b, uint c, float val)
Fill the output buffer of bus b, channel c with v.
void connect(IBusId ibus, AudioProcessor &oproc, OBusId obus)
Connect input ibusid to output obusid of AudioProcessor prev.
static const String STORAGEONLY
":S:r:w:" - STORAGE READABLE WRITABLE
DeviceP get_device() const
Gain access to the Device handle of this AudioProcessor.
Compact, deduplicating string variant for constant strings.
A stream of writable MidiEvent structures.
An in-order MidiEvent reader for multiple MidiEvent sources.
Interface for management, connecting and processing of AudioProcessor instances.
#define ASE_ASSERT_RETURN(expr,...)
Return from the current function if expr evaluates to false and issue an assertion warning.
std::pair< RandIter, bool > binary_lookup_insertion_pos(RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
The Anklang C++ API namespace.
CString website_url
Website of/about this AudioProcessor.
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.
CString version
Version identifier.
CString description
Elaborate description for help dialogs.
ParamId
ID type for AudioProcessor parameters, the ID numbers are user assignable.
CString creator_url
Internet contact of the creator.
CString blurb
Short description for overviews.
CString creator_name
Name of the creator.
CString register_audio_processor(const char *aseid=nullptr)
Add an AudioProcessor derived type to the audio processor registry.
uint16_t uint16
A 16-bit unsigned integer.
CString label
Preferred user interface name.
std::string String
Convenience alias for std::string.
uint32_t uint32
A 32-bit unsigned integer.
uint32_t uint
Provide 'uint' as convenience type.
CString category
Category to allow grouping for processors of similar function.
Detailed information and common properties of AudioProcessor subclasses.
Audio parameter handling, internal to AudioProcessor.
double value(uint32_t id) const
Read current value of parameter identified by id.
void install(const Map ¶ms)
Clear and install a new set of parameters.
void clear()
Clear all fields.
ssize_t index(uint32_t id) const
Find index of parameter identified by id or return -1.
bool dirty_index(uint32_t idx) const
Check if parameter is dirty (changed).
Transport information for AudioSignal processing.
Structure providing supplementary information about input/output buses.
uint n_channels() const
Number of channels described by speakers.
SpeakerArrangement speakers
Channel to speaker arrangement.
CString label
Preferred user interface name.
CString blurb
Short description for user interface tooltips.
CString ident
Identifier used for serialization.
CString hints
Hints for parameter handling.
Helper class for integer IDs up to 32 Bit, possibly of enum type.
MidiEvent data structure.
MidiEventType type
MidiEvent type, one of the MidiEventType members.