2#include "trkn/tracktion.hh"
22 te::LevelMeasurer::Client meter_client_;
27 float dbspl0 = -100.0f;
28 float dbspl1 = -100.0f;
31 asetrack_ (asetrack), track_state_ (asetrack_.track_->state),
32 telemetry_block_ (SERVER->telemem_allocate (sizeof (
Telemetry))),
33 telemetry (*new (telemetry_block_.block_start)
Telemetry{})
36 if (
auto t = asetrack_.track_.get()) {
38 if (
auto lmp = at->getLevelMeterPlugin()) {
39 measurer_ = &lmp->measurer;
40 measurer_->addClient (meter_client_);
44 if (
auto vol = asetrack_.volume_plugin()) {
45 volume_plugin_state_ = vol->state;
49 ~TrackStateListener()
override
51 if (volume_plugin_state_.
isValid())
54 measurer_->removeClient (meter_client_);
56 SERVER->telemem_release (telemetry_block_);
62 return { -100.0f, -100.0f };
70 if (tree == track_state_) {
71 if (property == tracktion::engine::IDs::name)
73 if (property == tracktion::engine::IDs::mute)
75 if (property == tracktion::engine::IDs::hidden)
77 if (property == tracktion::engine::IDs::solo)
80 if (tree == volume_plugin_state_) {
81 if (property == tracktion::engine::IDs::volume) {
85 if (property == tracktion::engine::IDs::pan)
88 asetrack_.update_telemetry();
93 if (parent == track_state_ && te::Clip::isClipState (child))
99 if (parent == track_state_ && te::Clip::isClipState (child))
104 valueTreeChildOrderChanged (
juce::ValueTree &parent,
int,
int newIndex)
override
107 if (parent == track_state_ && te::Clip::isClipState (parent.
getChild (newIndex)))
121trkn_track_type (tracktion::Track &track)
127 if (track.isTempoTrack())
129 if (track.isMarkerTrack())
131 if (track.isChordTrack())
133 if (track.isArrangerTrack())
135 if (track.isMasterTrack())
141TrackImpl::from_trkn (tracktion::Track &t)
143 TrackImpl *track = find_ase_obj<TrackImpl> (t);
145 return shared_ptr_cast<TrackImpl> (track);
146 TrackImplP trackp = TrackImpl::make_shared (t);
150TrackImpl::TrackImpl (tracktion::Track &track) :
152 track_ (&track), te_type_ (trkn_track_type (track))
159TrackImpl::TrackImpl (ProjectImpl &project,
bool masterflag) :
162 gadget_flags (masterflag ? MASTER_TRACK : 0);
165TrackImpl::~TrackImpl()
168 state_listener_ =
nullptr;
173TrackImpl::name()
const
175 if (
auto trackp = track_.get())
176 return trackp->getName().toStdString();
183 if (
auto trackp = track_.get())
184 if (!trkn_fixed_name (*trackp))
186 trackp->edit.getUndoManager().beginNewTransaction (
"Set Track Name");
192TrackImpl::project ()
const
200 if (
auto t = track_.get())
201 return t->isMuted (
false);
208 if (
auto t = track_.get())
215 if (
auto t = track_.get())
216 return t->isHidden ();
223 if (
auto t = track_.get())
230 if (
auto t = track_.get())
231 return t->isSolo (
false);
238 if (
auto t = track_.get())
245 if (
auto t = track_.get())
246 return t->isMasterTrack();
253 if (
auto t = track_.get())
254 return t->isTempoTrack() || t->isMarkerTrack() || t->isChordTrack() ||
255 t->isArrangerTrack() || t->isMasterTrack();
260TrackImpl::volume_plugin ()
const
262 if (
auto t = track_.get()) {
263 if (t->isMasterTrack())
264 return t->edit.getMasterVolumePlugin().get();
266 return at->getVolumePlugin();
274 if (
auto vol = volume_plugin())
275 return trkn_volume_db (*vol);
282 if (
auto vol = volume_plugin())
283 trkn_volume_db (*vol, db);
289 if (
auto vol = volume_plugin())
290 return trkn_slider_pos (*vol);
297 if (
auto vol = volume_plugin())
298 trkn_slider_pos (*vol, pos);
304 if (
auto vol = volume_plugin())
305 return trkn_pan (*vol);
312 if (
auto vol = volume_plugin())
313 trkn_pan (*vol,
pan);
319 StringS props = {
"launcher_clips" };
320 auto t = track_.get();
321 if (t && trkn_fixed_name (*t))
324 props.
insert (props.
end(), {
"muted",
"solo" });
325 if (!volume_plugin())
326 props.
insert (props.
end(), {
"pan",
"slider_pos",
"volume_db" });
334 if (
auto t = track_.get())
336 for (
auto *clip : ct->getClips())
338 if (
auto clipimpl = ClipImpl::from_trkn (*clip))
351TrackImpl::clip_index (
const ClipImpl &clip)
const
353 if (
auto t = track_.get())
355 auto &clips = ct->getClips();
356 for (
int i = 0; i < clips.size(); i++)
357 if (clips[i] == clip.clip_.get())
364TrackImpl::clip_succession (
const ClipImpl &clip)
const
366 ssize_t idx = clip_index (clip);
369 if (
auto t = track_.get())
371 auto &clips = ct->getClips();
372 if (idx + 1 < clips.size())
385TrackImpl::create_monitor (
int32 ochannel)
395 auto &t = state_listener_->telemetry;
396 v.push_back (telemetry_field (
"dbspl0", &t.dbspl0));
397 v.push_back (telemetry_field (
"dbspl1", &t.dbspl1));
402TrackImpl::update_telemetry()
405 auto &t = state_listener_->telemetry;
406 auto [left, right] = state_listener_->get_levels();
421 auto *track = track_.get();
424 track_->edit.deleteTrack (track);
427 state_listener_ =
nullptr;
433TrackImpl::ClipScout::ClipScout() noexcept
449 if (previous >= 0 && previous < indices_.size()) {
451 return indices_[last_];
467 indices_ = other.indices_;
473 if (
auto t = track_.get()) {
474 if (
auto at =
dynamic_cast<tracktion::AudioTrack *
> (t)) {
475 const tracktion::TimeRange range (tracktion::TimePosition::fromSeconds (start), tracktion::TimeDuration::fromSeconds (length));
476 auto clip = at->insertMIDIClip (
juce::String (name), range,
nullptr);
478 return ClipImpl::from_trkn (*clip);
480 warning (
"insertMIDIClip returned null");
483 warning (
"dynamic_cast<AudioTrack*> failed for track type: %s", trkn_track_type (*t).
c_str());
486 warning (
"track_.get() returned null");
493 if (
auto t = track_.get()) {
494 if (
auto ct =
dynamic_cast<tracktion::ClipTrack *
> (t)) {
495 const tracktion::TimeRange range (tracktion::TimePosition::fromSeconds (start), tracktion::TimeDuration::fromSeconds (length));
496 auto clip = ct->insertNewClip (tracktion::TrackItem::Type::wave,
juce::String (name), range,
nullptr);
498 return ClipImpl::from_trkn (*clip);
500 warning (
"insertNewClip returned null");
503 warning (
"dynamic_cast<ClipTrack*> failed for track type: %s", trkn_track_type (*t).
c_str());
506 warning (
"track_.get() returned null");
513 if (
auto t = track_.get()) {
514 auto plugin = t->edit.getPluginCache().createNewPlugin (type.
c_str(), {});
516 t->pluginList.insertPlugin (plugin, 0,
nullptr);
517 return PluginImpl::from_trkn (*plugin);
520 warning (
"createNewPlugin returned null");
523 warning (
"track_.get() returned null");
531 if (
auto t = track_.get()) {
532 auto &pluginList = t->pluginList;
533 for (
int i = 0; i < pluginList.size(); i++) {
534 if (
auto *plugin = pluginList[i]) {
535 if (
auto pluginimpl = PluginImpl::from_trkn (*plugin))
536 plugins.push_back (pluginimpl);
void emit_notify(const String &detail) override
Emit notify:detail, multiple notifications maybe coalesced if a CoalesceNotifies instance exists.
GadgetImpl * _parent() const override
Retrieve parent container.
void remove_self() override
Remove self from parent container.
Mimick tracktion::engine::SafeSelectable<> for tracktion::Selectable descendants.
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.
Ase::Track implementation.
float volume_db() const override
Get track volume in dB.
StringS read_only_properties() const override
List x()/x (v) properties that this object can't change, their setters ignore the value or warn.
ClipS launcher_clips() const override
Retrieve the list of clips that can be directly played; changes on notify:launcher_clips.
ClipP create_audio_clip(const String &name, double start, double length) override
Create a new audio clip on this track.
float pan() const override
Get track pan (-1.0 to 1.0).
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.
PluginS list_plugins() override
List plugins on this track.
bool is_control_track() const override
Flag set on tempo/marker/chord/arranger/master tracks.
ClipP create_midi_clip(const String &name, double start, double length) override
Create a new MIDI clip on this track.
float slider_pos() const override
Get track volume fader position.
bool muted() const override
Check if track is muted.
PluginP create_plugin(const String &type) override
Create a new plugin on this track by type identifier.
bool hidden() const override
Check if track is hidden from view.
void remove_self() override
Remove self from parent container.
bool solo() const override
Check if track is soloed.
ValueTree getChild(int index) const
bool isValid() const noexcept
void addListener(Listener *listener)
void removeListener(Listener *listener)
virtual bool isMarkerTrack() const
virtual bool isTempoTrack() const
virtual bool isMasterTrack() const
virtual bool isArrangerTrack() const
#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 ...
The Anklang C++ API namespace.
int32_t int32
A 32-bit signed integer.
void register_ase_obj(VirtualBase *ase_impl, tracktion::Selectable &selectable)
Helper: register AseImpl with a tracktion Selectable via ase_obj_.
AseType * find_ase_obj(tracktion::Selectable &selectable)
Helper: lookup AseType from tracktion Selectable via ase_obj_.
std::string String
Convenience alias for std::string.
void unregister_ase_obj(VirtualBase *ase_impl, tracktion::Selectable *selectable)
Helper: unregister AseImpl from a tracktion Selectable (selectable may be nullptr)
RangeType< TimePosition > TimeRange
Reference for an allocated memory block.