17TrackImpl::TrackImpl (ProjectImpl &project,
bool masterflag)
19 gadget_flags (masterflag ? MASTER_TRACK : 0);
22TrackImpl::~TrackImpl()
28TrackImpl::project ()
const
30 return static_cast<ProjectImpl*
> (
_parent());
34TrackImpl::fallback_name ()
const
38 if (
auto project_ = project())
40 ssize_t i = project_->track_index (*
this);
43 return DeviceImpl::fallback_name();
52 for (
auto &bclip : clips_)
54 ClipImplP clip = shared_ptr_cast<ClipImpl> (bclip);
55 if (!clip->needs_serialize())
59 const int64 index = clip_index (*clip);
60 xc.front (
"clip-index") << index;
66 for (
auto &xc : xs[
"clips"].
to_nodes())
68 int64 index = xc[
"clip-index"].as_int();
69 if (index < 0 ||
size_t (index) >= clips.size())
71 ClipImplP clip = shared_ptr_cast<ClipImpl> (clips[index]);
90 midi_prod_ = create_processor_device (*engine,
"Ase::MidiLib::MidiProducerImpl",
true);
92 midi_prod_->_set_parent (
this);
93 AudioProcessorP esource = midi_prod_->_audio_processor()->engine().get_event_source();
94 midi_prod_->_set_event_source (esource);
95 midi_prod_->_audio_processor()->connect_event_input (*esource);
97 chain_ = create_processor_device (*engine,
"Ase::AudioChain",
true);
99 chain_->_set_parent (
this);
100 chain_->_set_event_source (midi_prod_->_audio_processor());
104 midi_prod_->_disconnect_remove();
105 chain_->_disconnect_remove();
106 chain_->_set_parent (
nullptr);
108 midi_prod_->_set_parent (
nullptr);
109 midi_prod_ =
nullptr;
119 midi_prod_->_activate();
127 chain_->_deactivate();
128 midi_prod_->_deactivate();
133TrackImpl::queue_cmd (
CallbackS &queue, Cmd cmd,
double arg)
137 auto func = [midi_iface, cmd, arg] () {
140 else if (cmd == STOP)
141 midi_iface->stop (arg);
147TrackImpl::queue_cmd (DCallbackS &queue, Cmd cmd)
151 auto func = [midi_iface, cmd] (
const double arg) {
154 else if (cmd == STOP)
155 midi_iface->stop (arg);
157 queue.push_back (func);
163 midichannel =
CLAMP (midichannel, 0, 16);
165 midi_channel_ = midichannel;
169static constexpr const uint MAX_LAUNCHER_CLIPS = 8;
174 const uint max_clips = MAX_LAUNCHER_CLIPS;
175 if (clips_.size() < max_clips)
177 clips_.reserve (max_clips);
178 while (clips_.size() < max_clips)
179 clips_.push_back (ClipImpl::make_shared (*
this));
182 return Aux::container_copy<ClipS> (clips_);
186TrackImpl::clip_index (
const ClipImpl &clip)
const
188 for (
size_t i = 0; i < clips_.size(); i++)
189 if (clips_[i].get() == &clip)
195TrackImpl::clip_succession (
const ClipImpl &clip)
const
197 ssize_t index = clip_index (clip);
201 if (index >= clips_.size())
203 return clips_[index] ? index : NONE;
207TrackImpl::update_clips ()
212 MidiLib::MidiFeed &feed = *feedp;
213 feed.generators.resize (clips_.size());
214 for (
size_t i = 0; i < clips_.size(); i++)
215 feed.generators[i].setup (*clips_[i]);
217 for (
size_t i = 0; i < clips_.size(); i++)
218 scout_indices[i] = clips_[i] ? clip_succession (*clips_[i]) : NONE;
219 feed.scout.setup (scout_indices);
220 auto job = [midi_iface, feedp] ()
mutable {
221 midi_iface->update_feed (feedp);
224 midi_iface->engine().async_jobs += job;
234TrackImpl::create_monitor (
int32 ochannel)
248 v.push_back (telemetry_field (
"current_clip", &position->current));
249 v.push_back (telemetry_field (
"current_tick", &position->tick));
250 v.push_back (telemetry_field (
"next_clip", &position->next));
251 v.push_back (telemetry_field (
"dbspl0", &(*probes)[0].dbspl));
252 v.push_back (telemetry_field (
"dbspl1", &(*probes)[1].dbspl));
269TrackImpl::_set_event_source (AudioProcessorP esource)
275TrackImpl::ClipScout::ClipScout() noexcept
291 if (previous >= 0 && previous < indices_.size())
294 return indices_[last_];
310 indices_ = other.indices_;
bool is_active() override
Check whether this is the active synthesis engine project.
void _deactivate() override
Stop processing the corresponding AudioProcessor.
void _activate() override
Add AudioProcessor to the Engine and start processing.
void _set_parent(GadgetImpl *parent) override
Assign parent container.
void emit_notify(const String &detail) override
Emit notify:detail, multiple notifications maybe coalesced if a CoalesceNotifies instance exists.
Base type for classes that have a Property.
GadgetImpl * _parent() const override
Retrieve parent container.
Interface for serializable objects with Reflink support.
virtual void serialize(WritNode &xs)=0
Serialize members and childern.
MIDI clip playback succession generator.
int advance(int previous)
Determine clip succession.
void reset()
Reset state (history), preserves succession order.
void setup(const std::vector< int > &indices)
Setup clip succession order.
void update(const ClipScout &other)
Assign new succession order, preserves history.
ClipS launcher_clips() override
Retrieve the list of clips that can be directly played.
void _activate() override
Add AudioProcessor to the Engine and start processing.
void serialize(WritNode &xs) override
Serialize members and childern.
void _deactivate() override
Stop processing the corresponding AudioProcessor.
void _set_parent(GadgetImpl *parent) override
Assign parent container.
bool is_master() const override
Flag set on the main output track.
DeviceP access_device() override
Retrieve Device handle for this track.
DeviceInfo device_info() override
Describe this Device type.
TelemetryFieldS telemetry() const override
Create signal monitor for an output channel.
AudioProcessorP _audio_processor() const override
Retrieve the corresponding AudioProcessor.
int32 midi_channel() const override
Midi channel assigned to this track, 0 uses internal per-track channel.
One entry in a Writ serialization document.
WritNode push()
Append new WritNode for serializing arrays during in_save().
bool in_load() const
Return true during deserialization.
bool in_save() const
Return true during serialization.
WritNodeS to_nodes()
Create std::vector<WritNode> for serialized arrays during in_load().
#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].
The Anklang C++ API namespace.
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
int32_t int32
A 32-bit signed integer.
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
std::string String
Convenience alias for std::string.
uint32_t uint
Provide 'uint' as convenience type.