2 Copyright (C) 2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <pbd/error.h>
21 #include <sigc++/retype.h>
22 #include <sigc++/retype_return.h>
23 #include <sigc++/bind.h>
25 #include <ardour/audio_track.h>
26 #include <ardour/diskstream.h>
27 #include <ardour/session.h>
28 #include <ardour/redirect.h>
29 #include <ardour/audioregion.h>
30 #include <ardour/route_group_specialized.h>
31 #include <ardour/insert.h>
32 #include <ardour/audioplaylist.h>
33 #include <ardour/panner.h>
34 #include <ardour/utils.h>
39 using namespace ARDOUR;
41 AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
42 : Route (sess, name, 1, -1, -1, -1, flag),
44 _midi_rec_enable_control (*this, _session.midi_port())
46 DiskStream::Flag dflags = DiskStream::Flag (0);
48 if (_flags & Hidden) {
49 dflags = DiskStream::Flag (dflags | DiskStream::Hidden);
51 dflags = DiskStream::Flag (dflags | DiskStream::Recordable);
54 if (mode == Destructive) {
55 dflags = DiskStream::Flag (dflags | DiskStream::Destructive);
56 cerr << "Creating a new audio track, destructive mode\n";
58 cerr << "Creating a new audio track, NOT destructive mode\n";
61 DiskStream* ds = new DiskStream (_session, name, dflags);
64 _freeze_record.state = NoFreeze;
65 _saved_meter_point = _meter_point;
68 set_diskstream (*ds, this);
70 // we do this even though Route already did it in it's init
71 reset_midi_control (_session.midi_port(), _session.get_midi_control());
75 AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
76 : Route (sess, "to be renamed", 0, 0, -1, -1),
78 _midi_rec_enable_control (*this, _session.midi_port())
80 _freeze_record.state = NoFreeze;
83 _saved_meter_point = _meter_point;
85 // we do this even though Route already did it in it's init
86 reset_midi_control (_session.midi_port(), _session.get_midi_control());
89 AudioTrack::~AudioTrack ()
97 AudioTrack::deprecated_use_diskstream_connections ()
99 if (diskstream->deprecated_io_node == 0) {
103 const XMLProperty* prop;
104 XMLNode& node (*diskstream->deprecated_io_node);
106 /* don't do this more than once. */
108 diskstream->deprecated_io_node = 0;
110 set_input_minimum (-1);
111 set_input_maximum (-1);
112 set_output_minimum (-1);
113 set_output_maximum (-1);
115 if ((prop = node.property ("gain")) != 0) {
116 set_gain (atof (prop->value().c_str()), this);
117 _gain = _desired_gain;
120 if ((prop = node.property ("input-connection")) != 0) {
121 Connection* c = _session.connection_by_name (prop->value());
124 error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
126 if ((c = _session.connection_by_name (_("in 1"))) == 0) {
127 error << _("No input connections available as a replacement")
131 info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
136 use_input_connection (*c, this);
138 } else if ((prop = node.property ("inputs")) != 0) {
139 if (set_inputs (prop->value())) {
140 error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
149 AudioTrack::set_diskstream (DiskStream& ds, void *src)
155 diskstream = &ds.ref();
156 diskstream->set_io (*this);
157 diskstream->set_destructive (_mode == Destructive);
159 if (diskstream->deprecated_io_node) {
161 if (!connecting_legal) {
162 ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
164 deprecated_use_diskstream_connections ();
168 diskstream->set_record_enabled (false, this);
169 diskstream->monitor_input (false);
171 ic_connection.disconnect();
172 ic_connection = input_changed.connect (mem_fun (*diskstream, &DiskStream::handle_input_change));
174 diskstream_changed (src); /* EMIT SIGNAL */
180 AudioTrack::use_diskstream (string name)
184 if ((dstream = _session.diskstream_by_name (name)) == 0) {
185 error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg;
189 return set_diskstream (*dstream, this);
193 AudioTrack::use_diskstream (id_t id)
197 if ((dstream = _session.diskstream_by_id (id)) == 0) {
198 error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg;
202 return set_diskstream (*dstream, this);
206 AudioTrack::record_enabled () const
208 return diskstream->record_enabled ();
212 AudioTrack::set_record_enable (bool yn, void *src)
214 if (_freeze_record.state == Frozen) {
218 if (_mix_group && src != _mix_group && _mix_group->is_active()) {
219 _mix_group->apply (&AudioTrack::set_record_enable, yn, _mix_group);
223 /* keep track of the meter point as it was before we rec-enabled */
225 if (!diskstream->record_enabled()) {
226 _saved_meter_point = _meter_point;
229 diskstream->set_record_enabled (yn, src);
231 if (diskstream->record_enabled()) {
232 set_meter_point (MeterInput, this);
234 set_meter_point (_saved_meter_point, this);
237 if (_session.get_midi_feedback()) {
238 _midi_rec_enable_control.send_feedback (record_enabled());
244 AudioTrack::set_meter_point (MeterPoint p, void *src)
246 Route::set_meter_point (p, src);
250 AudioTrack::state(bool full_state)
252 XMLNode& track_state (Route::state (full_state));
255 /* we don't return diskstream state because we don't
256 own the diskstream exclusively. control of the diskstream
257 state is ceded to the Session, even if we create the
261 snprintf (buf, sizeof (buf), "%" PRIu64, diskstream->id());
262 track_state.add_property ("diskstream-id", buf);
268 AudioTrack::set_state (const XMLNode& node)
270 const XMLProperty *prop;
271 XMLNodeConstIterator iter;
272 XMLNodeList midi_kids;
274 if (Route::set_state (node)) {
278 if ((prop = node.property (X_("mode"))) != 0) {
279 if (prop->value() == X_("normal")) {
281 } else if (prop->value() == X_("destructive")) {
284 warning << string_compose ("unknown audio track mode \"%1\" seen and ignored", prop->value()) << endmsg;
291 midi_kids = node.children ("MIDI");
293 for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) {
296 XMLNodeConstIterator miter;
299 kids = (*iter)->children ();
301 for (miter = kids.begin(); miter != kids.end(); ++miter) {
305 if (child->name() == "rec_enable") {
307 MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
308 MIDI::byte additional = 0; /* ditto */
309 MIDI::channel_t chn = 0; /* ditto */
311 if (get_midi_node_info (child, ev, chn, additional)) {
312 _midi_rec_enable_control.set_control_type (chn, ev, additional);
314 error << string_compose(_("MIDI rec_enable control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
321 if ((prop = node.property ("diskstream-id")) == 0) {
323 /* some old sessions use the diskstream name rather than the ID */
325 if ((prop = node.property ("diskstream")) == 0) {
326 fatal << _("programming error: AudioTrack given state without diskstream!") << endmsg;
331 if (use_diskstream (prop->value())) {
337 id_t id = strtoull (prop->value().c_str(), 0, 10);
339 if (use_diskstream (id)) {
346 XMLNodeConstIterator niter;
349 nlist = node.children();
350 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
353 if (child->name() == X_("remote_control")) {
354 if ((prop = child->property (X_("id"))) != 0) {
356 sscanf (prop->value().c_str(), "%d", &x);
357 set_remote_control_id (x);
362 pending_state = const_cast<XMLNode*> (&node);
364 _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two));
370 AudioTrack::get_state()
372 XMLNode& root (Route::get_state());
373 XMLNode* freeze_node;
376 if (_freeze_record.playlist) {
379 freeze_node = new XMLNode (X_("freeze-info"));
380 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
381 snprintf (buf, sizeof (buf), "%d", (int) _freeze_record.state);
382 freeze_node->add_property ("state", buf);
384 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
385 inode = new XMLNode (X_("insert"));
386 snprintf (buf, sizeof (buf), "%" PRIu64, (*i)->id);
387 inode->add_property (X_("id"), buf);
388 inode->add_child_copy ((*i)->state);
390 freeze_node->add_child_nocopy (*inode);
393 root.add_child_nocopy (*freeze_node);
396 /* Alignment: act as a proxy for the diskstream */
398 XMLNode* align_node = new XMLNode (X_("alignment"));
399 switch (diskstream->alignment_style()) {
400 case ExistingMaterial:
401 snprintf (buf, sizeof (buf), X_("existing"));
404 snprintf (buf, sizeof (buf), X_("capture"));
407 align_node->add_property (X_("style"), buf);
408 root.add_child_nocopy (*align_node);
414 MIDI::byte additional;
415 XMLNode* midi_node = 0;
417 XMLNodeList midikids;
419 midikids = root.children ("MIDI");
420 if (!midikids.empty()) {
421 midi_node = midikids.front();
424 midi_node = root.add_child ("MIDI");
427 if (_midi_rec_enable_control.get_control_info (chn, ev, additional) && midi_node) {
429 child = midi_node->add_child ("rec_enable");
430 set_midi_node_info (child, ev, chn, additional);
433 XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
434 snprintf (buf, sizeof (buf), "%d", _remote_control_id);
435 remote_control_node->add_property (X_("id"), buf);
436 root.add_child_nocopy (*remote_control_node);
440 root.add_property (X_("mode"), X_("normal"));
443 root.add_property (X_("mode"), X_("destructive"));
451 AudioTrack::set_state_part_two ()
455 LocaleGuard lg (X_("POSIX"));
457 /* This is called after all session state has been restored but before
458 have been made ports and connections are established.
461 if (pending_state == 0) {
465 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
468 _freeze_record.have_mementos = false;
469 _freeze_record.state = Frozen;
471 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
474 _freeze_record.insert_info.clear ();
476 if ((prop = fnode->property (X_("playlist"))) != 0) {
477 Playlist* pl = _session.playlist_by_name (prop->value());
479 _freeze_record.playlist = dynamic_cast<AudioPlaylist*> (pl);
481 _freeze_record.playlist = 0;
482 _freeze_record.state = NoFreeze;
487 if ((prop = fnode->property (X_("state"))) != 0) {
488 _freeze_record.state = (FreezeState) atoi (prop->value().c_str());
491 XMLNodeConstIterator citer;
492 XMLNodeList clist = fnode->children();
494 for (citer = clist.begin(); citer != clist.end(); ++citer) {
495 if ((*citer)->name() != X_("insert")) {
499 if ((prop = (*citer)->property (X_("id"))) == 0) {
503 FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()));
505 sscanf (prop->value().c_str(), "%" PRIu64, &frii->id);
506 _freeze_record.insert_info.push_back (frii);
510 /* Alignment: act as a proxy for the diskstream */
512 if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
514 if ((prop = fnode->property (X_("style"))) != 0) {
515 if (prop->value() == "existing") {
516 diskstream->set_persistent_align_style (ExistingMaterial);
517 } else if (prop->value() == "capture") {
518 diskstream->set_persistent_align_style (CaptureTime);
526 AudioTrack::n_process_buffers ()
528 return max ((uint32_t) diskstream->n_channels(), redirect_max_outs);
532 AudioTrack::passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter)
534 uint32_t nbufs = n_process_buffers ();
535 process_output_buffers (_session.get_silent_buffers (nbufs), nbufs, start_frame, end_frame, nframes, offset, true, declick, meter);
539 AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
540 bool session_state_changing, bool can_record, bool rec_monitors_input)
542 if (n_outputs() == 0) {
547 silence (nframes, offset);
551 if (session_state_changing) {
553 /* XXX is this safe to do against transport state changes? */
555 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
559 diskstream->check_record_status (start_frame, nframes, can_record);
563 if (_have_internal_generator) {
564 /* since the instrument has no input streams,
565 there is no reason to send any signal
571 if (_session.get_auto_input()) {
572 if (Config->get_use_sw_monitoring()) {
573 send_silence = false;
578 if (diskstream->record_enabled()) {
579 if (Config->get_use_sw_monitoring()) {
580 send_silence = false;
590 apply_gain_automation = false;
594 /* if we're sending silence, but we want the meters to show levels for the signal,
598 if (_have_internal_generator) {
599 passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
601 if (_meter_point == MeterInput) {
602 just_meter_input (start_frame, end_frame, nframes, offset);
604 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
609 /* we're sending signal, but we may still want to meter the input.
612 passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
619 AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
620 bool can_record, bool rec_monitors_input)
625 jack_nframes_t transport_frame;
628 TentativeRWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
630 // automation snapshot can also be called from the non-rt context
631 // and it uses the redirect list, so we take the lock out here
632 automation_snapshot (start_frame);
636 if (n_outputs() == 0 && _redirects.empty()) {
641 silence (nframes, offset);
645 transport_frame = _session.transport_frame();
647 if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
648 /* need to do this so that the diskstream sets its
649 playback distance to zero, thus causing diskstream::commit
652 return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
656 apply_gain_automation = false;
658 if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
660 silence (nframes, offset);
665 /* special condition applies */
667 if (_meter_point == MeterInput) {
668 just_meter_input (start_frame, end_frame, nframes, offset);
671 if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
673 /* not actually recording, but we want to hear the input material anyway,
674 at least potentially (depending on monitoring options)
677 passthru (start_frame, end_frame, nframes, offset, 0, true);
679 } else if ((b = diskstream->playback_buffer(0)) != 0) {
682 XXX is it true that the earlier test on n_outputs()
683 means that we can avoid checking it again here? i think
684 so, because changing the i/o configuration of an IO
685 requires holding the AudioEngine lock, which we hold
686 while in the process() tree.
690 /* copy the diskstream data to all output buffers */
692 vector<Sample*>& bufs = _session.get_passthru_buffers ();
693 uint32_t limit = n_process_buffers ();
699 for (i = 0, n = 1; i < limit; ++i, ++n) {
700 memcpy (bufs[i], b, sizeof (Sample) * nframes);
701 if (n < diskstream->n_channels()) {
702 tmpb = diskstream->playback_buffer(n);
709 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
711 if (!diskstream->record_enabled() && _session.transport_rolling()) {
712 TentativeLockMonitor am (automation_lock, __LINE__, __FILE__);
714 if (am.locked() && gain_automation_playback()) {
715 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
719 process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !_session.get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
722 /* problem with the diskstream; just be quiet for a bit */
723 silence (nframes, offset);
730 AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
731 bool can_record, bool rec_monitors_input)
733 if (n_outputs() == 0 && _redirects.empty()) {
738 silence (nframes, offset);
743 apply_gain_automation = false;
745 silence (nframes, offset);
747 return diskstream->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
751 AudioTrack::toggle_monitor_input ()
753 for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
754 (*i)->request_monitor_input(!(*i)->monitoring_input());
759 AudioTrack::set_name (string str, void *src)
761 if (record_enabled() && _session.actively_recording()) {
762 /* this messes things up if done while recording */
766 diskstream->set_name (str, src);
767 return IO::set_name (str, src);
771 AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t start, jack_nframes_t nframes)
773 gain_t gain_automation[nframes];
774 gain_t gain_buffer[nframes];
775 float mix_buffer[nframes];
776 RedirectList::iterator i;
777 bool post_fader_work = false;
778 gain_t this_gain = _gain;
779 vector<Sample*>::iterator bi;
782 RWLockMonitor rlock (redirect_lock, false, __LINE__, __FILE__);
784 if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
789 bi = buffers.begin();
792 for (; bi != buffers.end(); ++bi, ++n) {
793 if (n < diskstream->n_channels()) {
794 if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
800 /* duplicate last across remaining buffers */
801 memcpy ((*bi), b, sizeof (Sample) * nframes);
806 /* note: only run inserts during export. other layers in the machinery
807 will already have checked that there are no external port inserts.
810 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
813 if ((insert = dynamic_cast<Insert*>(*i)) != 0) {
814 switch (insert->placement()) {
816 insert->run (buffers, nbufs, nframes, 0);
819 post_fader_work = true;
825 if (_gain_automation_curve.automation_state() == Play) {
827 _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes);
829 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
831 for (jack_nframes_t n = 0; n < nframes; ++n) {
832 b[n] *= gain_automation[n];
838 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
840 for (jack_nframes_t n = 0; n < nframes; ++n) {
846 if (post_fader_work) {
848 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
849 PluginInsert *insert;
851 if ((insert = dynamic_cast<PluginInsert*>(*i)) != 0) {
852 switch ((*i)->placement()) {
856 insert->run (buffers, nbufs, nframes, 0);
867 AudioTrack::set_latency_delay (jack_nframes_t longest_session_latency)
869 Route::set_latency_delay (longest_session_latency);
870 diskstream->set_roll_delay (_roll_delay);
874 AudioTrack::update_total_latency ()
878 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
879 if ((*i)->active ()) {
880 _own_latency += (*i)->latency ();
884 set_port_latency (_own_latency);
890 AudioTrack::bounce (InterThreadInfo& itt)
892 vector<Source*> srcs;
893 _session.write_one_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
898 AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
900 vector<Source*> srcs;
901 _session.write_one_track (*this, start, end, false, srcs, itt);
905 AudioTrack::freeze (InterThreadInfo& itt)
908 vector<Source*> srcs;
909 string new_playlist_name;
910 Playlist* new_playlist;
915 if ((_freeze_record.playlist = diskstream->playlist()) == 0) {
921 while (n < (UINT_MAX-1)) {
925 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
927 if (_session.playlist_by_name (candidate) == 0) {
928 new_playlist_name = candidate;
936 if (n == (UINT_MAX-1)) {
937 error << string_compose (X_("There Are too many frozen versions of playlist \"%1\""
938 " to create another one"), _freeze_record.playlist->name())
943 if (_session.write_one_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) {
947 _freeze_record.insert_info.clear ();
948 _freeze_record.have_mementos = true;
951 RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__);
953 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
955 if ((insert = dynamic_cast<Insert*>(*r)) != 0) {
957 FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state());
959 frii->insert = insert;
960 frii->id = insert->id();
961 frii->memento = (*r)->get_memento();
963 _freeze_record.insert_info.push_back (frii);
965 /* now deactivate the insert */
967 insert->set_active (false, this);
972 new_playlist = new AudioPlaylist (_session, new_playlist_name, false);
973 region_name = new_playlist_name;
975 /* create a new region from all filesources, keep it private */
977 region = new AudioRegion (srcs, 0, srcs[0]->length(),
979 (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
982 new_playlist->set_orig_diskstream_id (diskstream->id());
983 new_playlist->add_region (*region, 0);
984 new_playlist->set_frozen (true);
985 region->set_locked (true);
987 diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
988 diskstream->set_record_enabled (false, this);
990 _freeze_record.state = Frozen;
991 FreezeChange(); /* EMIT SIGNAL */
995 AudioTrack::unfreeze ()
997 if (_freeze_record.playlist) {
998 diskstream->use_playlist (_freeze_record.playlist);
1000 if (_freeze_record.have_mementos) {
1002 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
1008 RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); // should this be a write lock? jlc
1009 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1010 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
1011 if ((*ii)->id == (*i)->id()) {
1012 (*i)->set_state (((*ii)->state));
1019 _freeze_record.playlist = 0;
1022 _freeze_record.state = UnFrozen;
1023 FreezeChange (); /* EMIT SIGNAL */
1026 AudioTrack::FreezeRecord::~FreezeRecord ()
1028 for (vector<FreezeRecordInsertInfo*>::iterator i = insert_info.begin(); i != insert_info.end(); ++i) {
1033 AudioTrack::FreezeState
1034 AudioTrack::freeze_state() const
1036 return _freeze_record.state;
1041 AudioTrack::reset_midi_control (MIDI::Port* port, bool on)
1043 MIDI::channel_t chn;
1047 Route::reset_midi_control (port, on);
1049 _midi_rec_enable_control.get_control_info (chn, ev, extra);
1053 _midi_rec_enable_control.midi_rebind (port, chn);
1057 AudioTrack::send_all_midi_feedback ()
1059 if (_session.get_midi_feedback()) {
1061 Route::send_all_midi_feedback();
1063 _midi_rec_enable_control.send_feedback (record_enabled());
1068 AudioTrack::MIDIRecEnableControl::MIDIRecEnableControl (AudioTrack& s, MIDI::Port* port)
1069 : MIDI::Controllable (port, 0), track (s), setting(false)
1071 last_written = false; /* XXX need a good out of bound value */
1075 AudioTrack::MIDIRecEnableControl::set_value (float val)
1077 bool bval = ((val >= 0.5f) ? true: false);
1080 track.set_record_enable (bval, this);
1085 AudioTrack::MIDIRecEnableControl::send_feedback (bool value)
1088 if (!setting && get_midi_feedback()) {
1089 MIDI::byte val = (MIDI::byte) (value ? 127: 0);
1090 MIDI::channel_t ch = 0;
1091 MIDI::eventType ev = MIDI::none;
1092 MIDI::byte additional = 0;
1093 MIDI::EventTwoBytes data;
1095 if (get_control_info (ch, ev, additional)) {
1096 data.controller_number = additional;
1099 track._session.send_midi_message (get_port(), ev, ch, data);
1106 AudioTrack::MIDIRecEnableControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force)
1108 if (get_midi_feedback()) {
1110 MIDI::channel_t ch = 0;
1111 MIDI::eventType ev = MIDI::none;
1112 MIDI::byte additional = 0;
1114 if (get_control_info (ch, ev, additional)) {
1115 if (val != last_written || force) {
1117 *buf++ = additional; /* controller number */
1118 *buf++ = (MIDI::byte) (val ? 127: 0);
1129 AudioTrack::set_mode (TrackMode m)
1134 diskstream->set_destructive (m == Destructive);