2 Copyright (C) 1999-2004 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.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/utils.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/midi_diskstream.h>
53 #include <ardour/midi_playlist.h>
54 #include <ardour/midi_region.h>
55 #include <ardour/smf_source.h>
56 #include <ardour/auditioner.h>
57 #include <ardour/recent_sessions.h>
58 #include <ardour/redirect.h>
59 #include <ardour/send.h>
60 #include <ardour/insert.h>
61 #include <ardour/connection.h>
62 #include <ardour/slave.h>
63 #include <ardour/tempo.h>
64 #include <ardour/audio_track.h>
65 #include <ardour/midi_track.h>
66 #include <ardour/cycle_timer.h>
67 #include <ardour/named_selection.h>
68 #include <ardour/crossfade.h>
69 #include <ardour/playlist.h>
70 #include <ardour/click.h>
71 #include <ardour/data_type.h>
72 #include <ardour/buffer_set.h>
73 #include <ardour/source_factory.h>
74 #include <ardour/region_factory.h>
75 #include <ardour/filename_extensions.h>
76 #include <ardour/session_directory.h>
79 #include <ardour/osc.h>
85 using namespace ARDOUR;
87 using boost::shared_ptr;
90 static const int CPU_CACHE_ALIGN = 64;
92 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::StartTimeChanged;
100 sigc::signal<void> Session::EndTimeChanged;
102 Session::Session (AudioEngine &eng,
104 string snapshot_name,
105 string* mix_template)
108 _scratch_buffers(new BufferSet()),
109 _silent_buffers(new BufferSet()),
110 _send_buffers(new BufferSet()),
111 _mmc_port (default_mmc_port),
112 _mtc_port (default_mtc_port),
113 _midi_port (default_midi_port),
114 pending_events (2048),
115 //midi_requests (128), // the size of this should match the midi request pool size
116 _send_smpte_update (false),
117 diskstreams (new DiskstreamList),
118 routes (new RouteList),
119 auditioner ((Auditioner*) 0),
123 if (!eng.connected()) {
124 throw failed_constructor();
127 n_physical_outputs = _engine.n_physical_outputs();
128 n_physical_inputs = _engine.n_physical_inputs();
130 first_stage_init (fullpath, snapshot_name);
132 initialize_start_and_end_locations(0, compute_initial_length ());
134 SessionDirectory sdir(fullpath);
138 create_session_file_from_template (*mix_template)) {
140 cerr << "Creating session " << fullpath
141 <<" using template" << *mix_template
144 } else if (sdir.is_valid ()) {
146 cerr << "Loading session " << fullpath
147 << " using snapshot " << snapshot_name << " (1)"
152 throw failed_constructor ();
155 if (second_stage_init (false)) {
157 throw failed_constructor ();
160 store_recent_sessions(_name, _path);
162 bool was_dirty = dirty();
164 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
166 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
169 DirtyChanged (); /* EMIT SIGNAL */
173 Session::Session (AudioEngine &eng,
175 string snapshot_name,
176 AutoConnectOption input_ac,
177 AutoConnectOption output_ac,
178 uint32_t control_out_channels,
179 uint32_t master_out_channels,
180 uint32_t requested_physical_in,
181 uint32_t requested_physical_out,
182 nframes_t initial_length)
185 _scratch_buffers(new BufferSet()),
186 _silent_buffers(new BufferSet()),
187 _send_buffers(new BufferSet()),
188 _mmc_port (default_mmc_port),
189 _mtc_port (default_mtc_port),
190 _midi_port (default_midi_port),
191 pending_events (2048),
192 //midi_requests (16),
193 _send_smpte_update (false),
194 diskstreams (new DiskstreamList),
195 routes (new RouteList),
199 if (!eng.connected()) {
200 throw failed_constructor();
203 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
205 n_physical_outputs = _engine.n_physical_outputs();
206 n_physical_inputs = _engine.n_physical_inputs();
208 if (n_physical_inputs) {
209 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
212 if (n_physical_outputs) {
213 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
216 first_stage_init (fullpath, snapshot_name);
218 initialize_start_and_end_locations(0, initial_length);
220 SessionDirectory sdir(fullpath);
222 if (!sdir.create () || !create_session_file ()) {
224 throw failed_constructor ();
228 /* set up Master Out and Control Out if necessary */
233 if (control_out_channels) {
234 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
235 r->set_remote_control_id (control_id++);
240 if (master_out_channels) {
241 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
242 r->set_remote_control_id (control_id);
246 /* prohibit auto-connect to master, because there isn't one */
247 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
256 Config->set_input_auto_connect (input_ac);
257 Config->set_output_auto_connect (output_ac);
259 if (second_stage_init (true)) {
261 throw failed_constructor ();
264 store_recent_sessions(_name, _path);
266 bool was_dirty = dirty ();
268 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
270 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
273 DirtyChanged (); /* EMIT SIGNAL */
285 /* if we got to here, leaving pending capture state around
289 remove_pending_capture_state ();
291 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
292 _engine.remove_session ();
294 GoingAway (); /* EMIT SIGNAL */
300 /* clear history so that no references to objects are held any more */
304 /* clear state tree so that no references to objects are held any more */
310 terminate_butler_thread ();
311 //terminate_midi_thread ();
313 if (click_data && click_data != default_click) {
314 delete [] click_data;
317 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
318 delete [] click_emphasis_data;
323 delete _scratch_buffers;
324 delete _silent_buffers;
325 delete _send_buffers;
327 AudioDiskstream::free_working_buffers();
329 #undef TRACK_DESTRUCTION
330 #ifdef TRACK_DESTRUCTION
331 cerr << "delete named selections\n";
332 #endif /* TRACK_DESTRUCTION */
333 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
334 NamedSelectionList::iterator tmp;
343 #ifdef TRACK_DESTRUCTION
344 cerr << "delete playlists\n";
345 #endif /* TRACK_DESTRUCTION */
346 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
347 PlaylistList::iterator tmp;
352 (*i)->drop_references ();
357 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
358 PlaylistList::iterator tmp;
363 (*i)->drop_references ();
369 unused_playlists.clear ();
371 #ifdef TRACK_DESTRUCTION
372 cerr << "delete regions\n";
373 #endif /* TRACK_DESTRUCTION */
375 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
376 RegionList::iterator tmp;
381 i->second->drop_references ();
388 #ifdef TRACK_DESTRUCTION
389 cerr << "delete routes\n";
390 #endif /* TRACK_DESTRUCTION */
392 RCUWriter<RouteList> writer (routes);
393 boost::shared_ptr<RouteList> r = writer.get_copy ();
394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
395 (*i)->drop_references ();
398 /* writer goes out of scope and updates master */
403 #ifdef TRACK_DESTRUCTION
404 cerr << "delete diskstreams\n";
405 #endif /* TRACK_DESTRUCTION */
407 RCUWriter<DiskstreamList> dwriter (diskstreams);
408 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
409 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
410 (*i)->drop_references ();
414 diskstreams.flush ();
416 #ifdef TRACK_DESTRUCTION
417 cerr << "delete audio sources\n";
418 #endif /* TRACK_DESTRUCTION */
419 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
420 SourceMap::iterator tmp;
425 i->second->drop_references ();
432 #ifdef TRACK_DESTRUCTION
433 cerr << "delete mix groups\n";
434 #endif /* TRACK_DESTRUCTION */
435 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
436 list<RouteGroup*>::iterator tmp;
446 #ifdef TRACK_DESTRUCTION
447 cerr << "delete edit groups\n";
448 #endif /* TRACK_DESTRUCTION */
449 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
450 list<RouteGroup*>::iterator tmp;
460 #ifdef TRACK_DESTRUCTION
461 cerr << "delete connections\n";
462 #endif /* TRACK_DESTRUCTION */
463 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
464 ConnectionList::iterator tmp;
474 if (butler_mixdown_buffer) {
475 delete [] butler_mixdown_buffer;
478 if (butler_gain_buffer) {
479 delete [] butler_gain_buffer;
482 Crossfade::set_buffer_size (0);
490 Session::set_worst_io_latencies ()
492 _worst_output_latency = 0;
493 _worst_input_latency = 0;
495 if (!_engine.connected()) {
499 boost::shared_ptr<RouteList> r = routes.reader ();
501 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
502 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
503 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
508 Session::when_engine_running ()
510 string first_physical_output;
512 /* we don't want to run execute this again */
514 set_block_size (_engine.frames_per_cycle());
515 set_frame_rate (_engine.frame_rate());
517 Config->map_parameters (mem_fun (*this, &Session::config_changed));
519 /* every time we reconnect, recompute worst case output latencies */
521 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
523 if (synced_to_jack()) {
524 _engine.transport_stop ();
527 if (Config->get_jack_time_master()) {
528 _engine.transport_locate (_transport_frame);
536 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
538 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
540 /* existing state for Click */
542 if (_click_io->set_state (*child->children().front()) == 0) {
544 _clicking = Config->get_clicking ();
548 error << _("could not setup Click I/O") << endmsg;
554 /* default state for Click */
556 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
558 if (first_physical_output.length()) {
559 if (_click_io->add_output_port (first_physical_output, this)) {
560 // relax, even though its an error
562 _clicking = Config->get_clicking ();
568 catch (failed_constructor& err) {
569 error << _("cannot setup Click I/O") << endmsg;
572 set_worst_io_latencies ();
575 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
578 /* Create a set of Connection objects that map
579 to the physical outputs currently available
584 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
586 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
588 Connection* c = new OutputConnection (buf, true);
591 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
596 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
598 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
600 Connection* c = new InputConnection (buf, true);
603 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
610 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
612 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
614 Connection* c = new OutputConnection (buf, true);
618 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
619 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
624 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
626 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
628 Connection* c = new InputConnection (buf, true);
632 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
633 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
642 /* create master/control ports */
647 /* force the master to ignore any later call to this */
649 if (_master_out->pending_state_node) {
650 _master_out->ports_became_legal();
653 /* no panner resets till we are through */
655 _master_out->defer_pan_reset ();
657 while (_master_out->n_inputs().n_audio()
658 < _master_out->input_maximum().n_audio()) {
659 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
660 error << _("cannot setup master inputs")
666 while (_master_out->n_outputs().n_audio()
667 < _master_out->output_maximum().n_audio()) {
668 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
669 error << _("cannot setup master outputs")
676 _master_out->allow_pan_reset ();
680 Connection* c = new OutputConnection (_("Master Out"), true);
682 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
684 c->add_connection ((int) n, _master_out->input(n)->name());
691 /* catch up on send+insert cnts */
695 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
698 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
699 if (id > insert_cnt) {
707 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
710 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
718 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
720 /* hook us up to the engine */
722 _engine.set_session (this);
727 osc->set_session (*this);
730 _state_of_the_state = Clean;
732 DirtyChanged (); /* EMIT SIGNAL */
736 Session::hookup_io ()
738 /* stop graph reordering notifications from
739 causing resorts, etc.
742 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
744 if (auditioner == 0) {
746 /* we delay creating the auditioner till now because
747 it makes its own connections to ports.
748 the engine has to be running for this to work.
752 auditioner.reset (new Auditioner (*this));
755 catch (failed_constructor& err) {
756 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
760 /* Tell all IO objects to create their ports */
766 vector<string> cports;
768 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
769 if (_control_out->add_input_port ("", this)) {
770 error << _("cannot setup control inputs")
776 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
777 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
778 error << _("cannot set up master outputs")
786 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
788 for (n = 0; n < ni; ++n) {
789 cports.push_back (_control_out->input(n)->name());
792 boost::shared_ptr<RouteList> r = routes.reader ();
794 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
795 (*x)->set_control_outs (cports);
799 /* Tell all IO objects to connect themselves together */
801 IO::enable_connecting ();
803 /* Now reset all panners */
805 IO::reset_panners ();
807 /* Anyone who cares about input state, wake up and do something */
809 IOConnectionsComplete (); /* EMIT SIGNAL */
811 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
813 /* now handle the whole enchilada as if it was one
819 /* update mixer solo state */
825 Session::playlist_length_changed ()
827 /* we can't just increase end_location->end() if pl->get_maximum_extent()
828 if larger. if the playlist used to be the longest playlist,
829 and its now shorter, we have to decrease end_location->end(). hence,
830 we have to iterate over all diskstreams and check the
831 playlists currently in use.
837 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
839 boost::shared_ptr<Playlist> playlist;
841 if ((playlist = dstream->playlist()) != 0) {
842 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
845 /* see comment in playlist_length_changed () */
850 Session::record_enabling_legal () const
852 /* this used to be in here, but survey says.... we don't need to restrict it */
853 // if (record_status() == Recording) {
857 if (Config->get_all_safe()) {
864 Session::reset_input_monitor_state ()
866 if (transport_rolling()) {
868 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
870 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
871 if ((*i)->record_enabled ()) {
872 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
873 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
877 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
879 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
880 if ((*i)->record_enabled ()) {
881 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
882 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
889 Session::auto_punch_start_changed (Location* location)
891 replace_event (Event::PunchIn, location->start());
893 if (get_record_enabled() && Config->get_punch_in()) {
894 /* capture start has been changed, so save new pending state */
895 save_state ("", true);
900 Session::auto_punch_end_changed (Location* location)
902 nframes_t when_to_stop = location->end();
903 // when_to_stop += _worst_output_latency + _worst_input_latency;
904 replace_event (Event::PunchOut, when_to_stop);
908 Session::auto_punch_changed (Location* location)
910 nframes_t when_to_stop = location->end();
912 replace_event (Event::PunchIn, location->start());
913 //when_to_stop += _worst_output_latency + _worst_input_latency;
914 replace_event (Event::PunchOut, when_to_stop);
918 Session::auto_loop_changed (Location* location)
920 replace_event (Event::AutoLoop, location->end(), location->start());
922 if (transport_rolling() && play_loop) {
924 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
926 if (_transport_frame > location->end()) {
927 // relocate to beginning of loop
928 clear_events (Event::LocateRoll);
930 request_locate (location->start(), true);
933 else if (Config->get_seamless_loop() && !loop_changing) {
935 // schedule a locate-roll to refill the diskstreams at the
937 loop_changing = true;
939 if (location->end() > last_loopend) {
940 clear_events (Event::LocateRoll);
941 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
948 last_loopend = location->end();
953 Session::set_auto_punch_location (Location* location)
957 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
958 auto_punch_start_changed_connection.disconnect();
959 auto_punch_end_changed_connection.disconnect();
960 auto_punch_changed_connection.disconnect();
961 existing->set_auto_punch (false, this);
962 remove_event (existing->start(), Event::PunchIn);
963 clear_events (Event::PunchOut);
964 auto_punch_location_changed (0);
973 if (location->end() <= location->start()) {
974 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
978 auto_punch_start_changed_connection.disconnect();
979 auto_punch_end_changed_connection.disconnect();
980 auto_punch_changed_connection.disconnect();
982 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
983 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
984 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
986 location->set_auto_punch (true, this);
987 auto_punch_location_changed (location);
991 Session::set_auto_loop_location (Location* location)
995 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
996 auto_loop_start_changed_connection.disconnect();
997 auto_loop_end_changed_connection.disconnect();
998 auto_loop_changed_connection.disconnect();
999 existing->set_auto_loop (false, this);
1000 remove_event (existing->end(), Event::AutoLoop);
1001 auto_loop_location_changed (0);
1006 if (location == 0) {
1010 if (location->end() <= location->start()) {
1011 error << _("Session: you can't use a mark for auto loop") << endmsg;
1015 last_loopend = location->end();
1017 auto_loop_start_changed_connection.disconnect();
1018 auto_loop_end_changed_connection.disconnect();
1019 auto_loop_changed_connection.disconnect();
1021 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1022 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1023 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1025 location->set_auto_loop (true, this);
1026 auto_loop_location_changed (location);
1030 Session::locations_added (Location* ignored)
1036 Session::locations_changed ()
1038 _locations.apply (*this, &Session::handle_locations_changed);
1042 Session::handle_locations_changed (Locations::LocationList& locations)
1044 Locations::LocationList::iterator i;
1046 bool set_loop = false;
1047 bool set_punch = false;
1049 for (i = locations.begin(); i != locations.end(); ++i) {
1053 if (location->is_auto_punch()) {
1054 set_auto_punch_location (location);
1057 if (location->is_auto_loop()) {
1058 set_auto_loop_location (location);
1065 set_auto_loop_location (0);
1068 set_auto_punch_location (0);
1075 Session::enable_record ()
1077 /* XXX really atomic compare+swap here */
1078 if (g_atomic_int_get (&_record_status) != Recording) {
1079 g_atomic_int_set (&_record_status, Recording);
1080 _last_record_location = _transport_frame;
1081 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1083 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1084 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1085 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1086 if ((*i)->record_enabled ()) {
1087 (*i)->monitor_input (true);
1092 RecordStateChanged ();
1097 Session::disable_record (bool rt_context, bool force)
1101 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1103 if (!Config->get_latched_record_enable () || force) {
1104 g_atomic_int_set (&_record_status, Disabled);
1106 if (rs == Recording) {
1107 g_atomic_int_set (&_record_status, Enabled);
1111 // FIXME: timestamp correct? [DR]
1112 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1113 // does this /need/ to be sent in all cases?
1115 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1117 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1118 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1120 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1121 if ((*i)->record_enabled ()) {
1122 (*i)->monitor_input (false);
1127 RecordStateChanged (); /* emit signal */
1130 remove_pending_capture_state ();
1136 Session::step_back_from_record ()
1138 g_atomic_int_set (&_record_status, Enabled);
1140 if (Config->get_monitoring_model() == HardwareMonitoring) {
1141 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1143 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1144 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1145 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1146 (*i)->monitor_input (false);
1153 Session::maybe_enable_record ()
1155 g_atomic_int_set (&_record_status, Enabled);
1157 /* this function is currently called from somewhere other than an RT thread.
1158 this save_state() call therefore doesn't impact anything.
1161 save_state ("", true);
1163 if (_transport_speed) {
1164 if (!Config->get_punch_in()) {
1168 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1169 RecordStateChanged (); /* EMIT SIGNAL */
1176 Session::audible_frame () const
1182 /* the first of these two possible settings for "offset"
1183 mean that the audible frame is stationary until
1184 audio emerges from the latency compensation
1187 the second means that the audible frame is stationary
1188 until audio would emerge from a physical port
1189 in the absence of any plugin latency compensation
1192 offset = _worst_output_latency;
1194 if (offset > current_block_size) {
1195 offset -= current_block_size;
1197 /* XXX is this correct? if we have no external
1198 physical connections and everything is internal
1199 then surely this is zero? still, how
1200 likely is that anyway?
1202 offset = current_block_size;
1205 if (synced_to_jack()) {
1206 tf = _engine.transport_frame();
1208 tf = _transport_frame;
1211 if (_transport_speed == 0) {
1221 if (!non_realtime_work_pending()) {
1225 /* take latency into account */
1234 Session::set_frame_rate (nframes_t frames_per_second)
1236 /** \fn void Session::set_frame_size(nframes_t)
1237 the AudioEngine object that calls this guarantees
1238 that it will not be called while we are also in
1239 ::process(). Its fine to do things that block
1243 _base_frame_rate = frames_per_second;
1247 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1249 // XXX we need some equivalent to this, somehow
1250 // SndFileSource::setup_standard_crossfades (frames_per_second);
1254 /* XXX need to reset/reinstantiate all LADSPA plugins */
1258 Session::set_block_size (nframes_t nframes)
1260 /* the AudioEngine guarantees
1261 that it will not be called while we are also in
1262 ::process(). It is therefore fine to do things that block
1268 current_block_size = nframes;
1270 ensure_buffers(_scratch_buffers->available());
1272 if (_gain_automation_buffer) {
1273 delete [] _gain_automation_buffer;
1275 _gain_automation_buffer = new gain_t[nframes];
1277 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1279 boost::shared_ptr<RouteList> r = routes.reader ();
1281 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1282 (*i)->set_block_size (nframes);
1285 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1286 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1287 (*i)->set_block_size (nframes);
1290 set_worst_io_latencies ();
1295 Session::set_default_fade (float steepness, float fade_msecs)
1298 nframes_t fade_frames;
1300 /* Don't allow fade of less 1 frame */
1302 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1309 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1313 default_fade_msecs = fade_msecs;
1314 default_fade_steepness = steepness;
1317 // jlc, WTF is this!
1318 Glib::RWLock::ReaderLock lm (route_lock);
1319 AudioRegion::set_default_fade (steepness, fade_frames);
1324 /* XXX have to do this at some point */
1325 /* foreach region using default fade, reset, then
1326 refill_all_diskstream_buffers ();
1331 struct RouteSorter {
1332 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1333 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1335 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1338 if (r1->fed_by.empty()) {
1339 if (r2->fed_by.empty()) {
1340 /* no ardour-based connections inbound to either route. just use signal order */
1341 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1343 /* r2 has connections, r1 does not; run r1 early */
1347 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1354 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1356 shared_ptr<Route> r2;
1358 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1359 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1363 /* make a copy of the existing list of routes that feed r1 */
1365 set<shared_ptr<Route> > existing = r1->fed_by;
1367 /* for each route that feeds r1, recurse, marking it as feeding
1371 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1374 /* r2 is a route that feeds r1 which somehow feeds base. mark
1375 base as being fed by r2
1378 rbase->fed_by.insert (r2);
1382 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1386 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1390 /* now recurse, so that we can mark base as being fed by
1391 all routes that feed r2
1394 trace_terminal (r2, rbase);
1401 Session::resort_routes ()
1403 /* don't do anything here with signals emitted
1404 by Routes while we are being destroyed.
1407 if (_state_of_the_state & Deletion) {
1414 RCUWriter<RouteList> writer (routes);
1415 shared_ptr<RouteList> r = writer.get_copy ();
1416 resort_routes_using (r);
1417 /* writer goes out of scope and forces update */
1422 Session::resort_routes_using (shared_ptr<RouteList> r)
1424 RouteList::iterator i, j;
1426 for (i = r->begin(); i != r->end(); ++i) {
1428 (*i)->fed_by.clear ();
1430 for (j = r->begin(); j != r->end(); ++j) {
1432 /* although routes can feed themselves, it will
1433 cause an endless recursive descent if we
1434 detect it. so don't bother checking for
1442 if ((*j)->feeds (*i)) {
1443 (*i)->fed_by.insert (*j);
1448 for (i = r->begin(); i != r->end(); ++i) {
1449 trace_terminal (*i, *i);
1456 cerr << "finished route resort\n";
1458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1459 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1466 list<boost::shared_ptr<MidiTrack> >
1467 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1469 char track_name[32];
1470 uint32_t track_id = 0;
1472 uint32_t channels_used = 0;
1474 RouteList new_routes;
1475 list<boost::shared_ptr<MidiTrack> > ret;
1477 /* count existing midi tracks */
1480 shared_ptr<RouteList> r = routes.reader ();
1482 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1483 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1484 if (!(*i)->hidden()) {
1486 channels_used += (*i)->n_inputs().n_midi();
1494 /* check for duplicate route names, since we might have pre-existing
1495 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1496 save, close,restart,add new route - first named route is now
1504 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1506 if (route_by_name (track_name) == 0) {
1510 } while (track_id < (UINT_MAX-1));
1513 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1515 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1516 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1519 channels_used += track->n_inputs ().n_midi();
1521 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1522 track->set_remote_control_id (ntracks());
1524 new_routes.push_back (track);
1525 ret.push_back (track);
1528 catch (failed_constructor &err) {
1529 error << _("Session: could not create new midi track.") << endmsg;
1530 // XXX should we delete the tracks already created?
1538 if (!new_routes.empty()) {
1539 add_routes (new_routes, false);
1540 save_state (_current_snapshot_name);
1546 list<boost::shared_ptr<AudioTrack> >
1547 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1549 char track_name[32];
1550 uint32_t track_id = 0;
1552 uint32_t channels_used = 0;
1554 RouteList new_routes;
1555 list<boost::shared_ptr<AudioTrack> > ret;
1556 uint32_t control_id;
1558 /* count existing audio tracks */
1561 shared_ptr<RouteList> r = routes.reader ();
1563 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1564 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1565 if (!(*i)->hidden()) {
1567 channels_used += (*i)->n_inputs().n_audio();
1573 vector<string> physinputs;
1574 vector<string> physoutputs;
1575 uint32_t nphysical_in;
1576 uint32_t nphysical_out;
1578 _engine.get_physical_outputs (physoutputs);
1579 _engine.get_physical_inputs (physinputs);
1580 control_id = ntracks() + nbusses() + 1;
1584 /* check for duplicate route names, since we might have pre-existing
1585 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1586 save, close,restart,add new route - first named route is now
1594 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1596 if (route_by_name (track_name) == 0) {
1600 } while (track_id < (UINT_MAX-1));
1602 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1603 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1608 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1609 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1614 shared_ptr<AudioTrack> track;
1617 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1619 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1620 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1621 input_channels, output_channels)
1627 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1631 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1632 port = physinputs[(channels_used+x)%nphysical_in];
1635 if (port.length() && track->connect_input (track->input (x), port, this)) {
1641 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1645 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1646 port = physoutputs[(channels_used+x)%nphysical_out];
1647 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1649 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1653 if (port.length() && track->connect_output (track->output (x), port, this)) {
1658 channels_used += track->n_inputs ().n_audio();
1660 track->audio_diskstream()->non_realtime_input_change();
1662 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1663 track->set_remote_control_id (control_id);
1666 new_routes.push_back (track);
1667 ret.push_back (track);
1670 catch (failed_constructor &err) {
1671 error << _("Session: could not create new audio track.") << endmsg;
1674 /* we need to get rid of this, since the track failed to be created */
1675 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1678 RCUWriter<DiskstreamList> writer (diskstreams);
1679 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1680 ds->remove (track->audio_diskstream());
1687 catch (AudioEngine::PortRegistrationFailure& pfe) {
1689 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1692 /* we need to get rid of this, since the track failed to be created */
1693 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1696 RCUWriter<DiskstreamList> writer (diskstreams);
1697 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1698 ds->remove (track->audio_diskstream());
1709 if (!new_routes.empty()) {
1710 add_routes (new_routes, false);
1711 save_state (_current_snapshot_name);
1718 Session::set_remote_control_ids ()
1720 RemoteModel m = Config->get_remote_model();
1722 shared_ptr<RouteList> r = routes.reader ();
1724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1725 if ( MixerOrdered == m) {
1726 long order = (*i)->order_key(N_("signal"));
1727 (*i)->set_remote_control_id( order+1 );
1728 } else if ( EditorOrdered == m) {
1729 long order = (*i)->order_key(N_("editor"));
1730 (*i)->set_remote_control_id( order+1 );
1731 } else if ( UserOrdered == m) {
1732 //do nothing ... only changes to remote id's are initiated by user
1739 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1742 uint32_t bus_id = 1;
1746 uint32_t control_id;
1748 /* count existing audio busses */
1751 shared_ptr<RouteList> r = routes.reader ();
1753 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1754 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1755 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1762 vector<string> physinputs;
1763 vector<string> physoutputs;
1765 _engine.get_physical_outputs (physoutputs);
1766 _engine.get_physical_inputs (physinputs);
1767 control_id = ntracks() + nbusses() + 1;
1772 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1776 if (route_by_name (bus_name) == 0) {
1780 } while (bus_id < (UINT_MAX-1));
1783 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1785 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1786 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1787 input_channels, output_channels)
1792 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1796 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1797 port = physinputs[((n+x)%n_physical_inputs)];
1800 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1805 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1809 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1810 port = physoutputs[((n+x)%n_physical_outputs)];
1811 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1813 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1817 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1822 bus->set_remote_control_id (control_id);
1825 ret.push_back (bus);
1829 catch (failed_constructor &err) {
1830 error << _("Session: could not create new audio route.") << endmsg;
1834 catch (AudioEngine::PortRegistrationFailure& pfe) {
1835 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1845 add_routes (ret, false);
1846 save_state (_current_snapshot_name);
1854 Session::add_routes (RouteList& new_routes, bool save)
1857 RCUWriter<RouteList> writer (routes);
1858 shared_ptr<RouteList> r = writer.get_copy ();
1859 r->insert (r->end(), new_routes.begin(), new_routes.end());
1860 resort_routes_using (r);
1863 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1865 boost::weak_ptr<Route> wpr (*x);
1867 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1868 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1869 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1870 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1872 if ((*x)->master()) {
1876 if ((*x)->control()) {
1877 _control_out = (*x);
1881 if (_control_out && IO::connecting_legal) {
1883 vector<string> cports;
1884 uint32_t ni = _control_out->n_inputs().n_audio();
1886 for (uint32_t n = 0; n < ni; ++n) {
1887 cports.push_back (_control_out->input(n)->name());
1890 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1891 (*x)->set_control_outs (cports);
1898 save_state (_current_snapshot_name);
1901 RouteAdded (new_routes); /* EMIT SIGNAL */
1905 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1907 /* need to do this in case we're rolling at the time, to prevent false underruns */
1908 dstream->do_refill_with_alloc ();
1910 dstream->set_block_size (current_block_size);
1913 RCUWriter<DiskstreamList> writer (diskstreams);
1914 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1915 ds->push_back (dstream);
1916 /* writer goes out of scope, copies ds back to main */
1919 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1920 /* this will connect to future changes, and check the current length */
1921 diskstream_playlist_changed (dstream);
1923 dstream->prepare ();
1928 Session::remove_route (shared_ptr<Route> route)
1931 RCUWriter<RouteList> writer (routes);
1932 shared_ptr<RouteList> rs = writer.get_copy ();
1936 /* deleting the master out seems like a dumb
1937 idea, but its more of a UI policy issue
1941 if (route == _master_out) {
1942 _master_out = shared_ptr<Route> ();
1945 if (route == _control_out) {
1946 _control_out = shared_ptr<Route> ();
1948 /* cancel control outs for all routes */
1950 vector<string> empty;
1952 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1953 (*r)->set_control_outs (empty);
1957 update_route_solo_state ();
1959 /* writer goes out of scope, forces route list update */
1963 boost::shared_ptr<Diskstream> ds;
1965 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1966 ds = t->diskstream();
1972 RCUWriter<DiskstreamList> dsl (diskstreams);
1973 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1978 find_current_end ();
1980 update_latency_compensation (false, false);
1983 // We need to disconnect the routes inputs and outputs
1984 route->disconnect_inputs(NULL);
1985 route->disconnect_outputs(NULL);
1987 /* get rid of it from the dead wood collection in the route list manager */
1989 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1993 /* try to cause everyone to drop their references */
1995 route->drop_references ();
1997 /* save the new state of the world */
1999 if (save_state (_current_snapshot_name)) {
2000 save_history (_current_snapshot_name);
2005 Session::route_mute_changed (void* src)
2011 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2013 if (solo_update_disabled) {
2019 boost::shared_ptr<Route> route = wpr.lock ();
2022 /* should not happen */
2023 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2027 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2029 shared_ptr<RouteList> r = routes.reader ();
2031 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2033 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2037 /* don't mess with busses */
2039 if (dynamic_cast<Track*>((*i).get()) == 0) {
2045 /* don't mess with tracks */
2047 if (dynamic_cast<Track*>((*i).get()) != 0) {
2052 if ((*i) != route &&
2053 ((*i)->mix_group () == 0 ||
2054 (*i)->mix_group () != route->mix_group () ||
2055 !route->mix_group ()->is_active())) {
2057 if ((*i)->soloed()) {
2059 /* if its already soloed, and solo latching is enabled,
2060 then leave it as it is.
2063 if (Config->get_solo_latched()) {
2070 solo_update_disabled = true;
2071 (*i)->set_solo (false, src);
2072 solo_update_disabled = false;
2076 bool something_soloed = false;
2077 bool same_thing_soloed = false;
2078 bool signal = false;
2080 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2081 if ((*i)->soloed()) {
2082 something_soloed = true;
2083 if (dynamic_cast<Track*>((*i).get())) {
2085 same_thing_soloed = true;
2090 same_thing_soloed = true;
2098 if (something_soloed != currently_soloing) {
2100 currently_soloing = something_soloed;
2103 modify_solo_mute (is_track, same_thing_soloed);
2106 SoloActive (currently_soloing); /* EMIT SIGNAL */
2109 SoloChanged (); /* EMIT SIGNAL */
2115 Session::update_route_solo_state ()
2118 bool is_track = false;
2119 bool signal = false;
2121 /* caller must hold RouteLock */
2123 /* this is where we actually implement solo by changing
2124 the solo mute setting of each track.
2127 shared_ptr<RouteList> r = routes.reader ();
2129 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2130 if ((*i)->soloed()) {
2132 if (dynamic_cast<Track*>((*i).get())) {
2139 if (mute != currently_soloing) {
2141 currently_soloing = mute;
2144 if (!is_track && !mute) {
2146 /* nothing is soloed */
2148 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2149 (*i)->set_solo_mute (false);
2159 modify_solo_mute (is_track, mute);
2162 SoloActive (currently_soloing);
2167 Session::modify_solo_mute (bool is_track, bool mute)
2169 shared_ptr<RouteList> r = routes.reader ();
2171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2175 /* only alter track solo mute */
2177 if (dynamic_cast<Track*>((*i).get())) {
2178 if ((*i)->soloed()) {
2179 (*i)->set_solo_mute (!mute);
2181 (*i)->set_solo_mute (mute);
2187 /* only alter bus solo mute */
2189 if (!dynamic_cast<Track*>((*i).get())) {
2191 if ((*i)->soloed()) {
2193 (*i)->set_solo_mute (false);
2197 /* don't mute master or control outs
2198 in response to another bus solo
2201 if ((*i) != _master_out &&
2202 (*i) != _control_out) {
2203 (*i)->set_solo_mute (mute);
2214 Session::catch_up_on_solo ()
2216 /* this is called after set_state() to catch the full solo
2217 state, which can't be correctly determined on a per-route
2218 basis, but needs the global overview that only the session
2221 update_route_solo_state();
2225 Session::route_by_name (string name)
2227 shared_ptr<RouteList> r = routes.reader ();
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if ((*i)->name() == name) {
2235 return shared_ptr<Route> ((Route*) 0);
2239 Session::route_by_id (PBD::ID id)
2241 shared_ptr<RouteList> r = routes.reader ();
2243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2244 if ((*i)->id() == id) {
2249 return shared_ptr<Route> ((Route*) 0);
2253 Session::route_by_remote_id (uint32_t id)
2255 shared_ptr<RouteList> r = routes.reader ();
2257 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2258 if ((*i)->remote_control_id() == id) {
2263 return shared_ptr<Route> ((Route*) 0);
2267 Session::find_current_end ()
2269 if (_state_of_the_state & Loading) {
2273 nframes_t max = get_maximum_extent ();
2275 if (max > end_location->end()) {
2276 end_location->set_end (max);
2278 DurationChanged(); /* EMIT SIGNAL */
2283 Session::get_maximum_extent () const
2288 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2290 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2291 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2292 if ((me = pl->get_maximum_extent()) > max) {
2300 boost::shared_ptr<Diskstream>
2301 Session::diskstream_by_name (string name)
2303 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2305 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2306 if ((*i)->name() == name) {
2311 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2314 boost::shared_ptr<Diskstream>
2315 Session::diskstream_by_id (const PBD::ID& id)
2317 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2319 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2320 if ((*i)->id() == id) {
2325 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2328 /* Region management */
2331 Session::new_region_name (string old)
2333 string::size_type last_period;
2335 string::size_type len = old.length() + 64;
2338 if ((last_period = old.find_last_of ('.')) == string::npos) {
2340 /* no period present - add one explicitly */
2343 last_period = old.length() - 1;
2348 number = atoi (old.substr (last_period+1).c_str());
2352 while (number < (UINT_MAX-1)) {
2354 RegionList::const_iterator i;
2359 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2362 for (i = regions.begin(); i != regions.end(); ++i) {
2363 if (i->second->name() == sbuf) {
2368 if (i == regions.end()) {
2373 if (number != (UINT_MAX-1)) {
2377 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2382 Session::region_name (string& result, string base, bool newlevel) const
2387 assert(base.find("/") == string::npos);
2391 Glib::Mutex::Lock lm (region_lock);
2393 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2401 /* XXX this is going to be slow. optimize me later */
2406 string::size_type pos;
2408 pos = base.find_last_of ('.');
2410 /* pos may be npos, but then we just use entire base */
2412 subbase = base.substr (0, pos);
2416 bool name_taken = true;
2419 Glib::Mutex::Lock lm (region_lock);
2421 for (int n = 1; n < 5000; ++n) {
2424 snprintf (buf, sizeof (buf), ".%d", n);
2429 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2430 if (i->second->name() == result) {
2443 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2451 Session::add_region (boost::shared_ptr<Region> region)
2453 boost::shared_ptr<Region> other;
2457 Glib::Mutex::Lock lm (region_lock);
2459 RegionList::iterator x;
2461 for (x = regions.begin(); x != regions.end(); ++x) {
2465 if (region->region_list_equivalent (other)) {
2470 if (x == regions.end()) {
2472 pair<RegionList::key_type,RegionList::mapped_type> entry;
2474 entry.first = region->id();
2475 entry.second = region;
2477 pair<RegionList::iterator,bool> x = regions.insert (entry);
2489 /* mark dirty because something has changed even if we didn't
2490 add the region to the region list.
2496 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2497 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2498 RegionAdded (region); /* EMIT SIGNAL */
2503 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2505 boost::shared_ptr<Region> region (weak_region.lock ());
2511 if (what_changed & Region::HiddenChanged) {
2512 /* relay hidden changes */
2513 RegionHiddenChange (region);
2518 Session::remove_region (boost::weak_ptr<Region> weak_region)
2520 RegionList::iterator i;
2521 boost::shared_ptr<Region> region (weak_region.lock ());
2527 bool removed = false;
2530 Glib::Mutex::Lock lm (region_lock);
2532 if ((i = regions.find (region->id())) != regions.end()) {
2538 /* mark dirty because something has changed even if we didn't
2539 remove the region from the region list.
2545 RegionRemoved(region); /* EMIT SIGNAL */
2549 boost::shared_ptr<Region>
2550 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2552 RegionList::iterator i;
2553 boost::shared_ptr<Region> region;
2555 Glib::Mutex::Lock lm (region_lock);
2557 for (i = regions.begin(); i != regions.end(); ++i) {
2561 if (region->whole_file()) {
2563 if (child->source_equivalent (region)) {
2569 return boost::shared_ptr<Region> ();
2573 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2575 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2576 (*i)->get_region_list_equivalent_regions (region, result);
2580 Session::destroy_region (boost::shared_ptr<Region> region)
2582 vector<boost::shared_ptr<Source> > srcs;
2585 boost::shared_ptr<AudioRegion> aregion;
2587 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2591 if (aregion->playlist()) {
2592 aregion->playlist()->destroy_region (region);
2595 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2596 srcs.push_back (aregion->source (n));
2600 region->drop_references ();
2602 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2604 if (!(*i)->used()) {
2605 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2608 (afs)->mark_for_remove ();
2611 (*i)->drop_references ();
2613 cerr << "source was not used by any playlist\n";
2621 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2623 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2624 destroy_region (*i);
2630 Session::remove_last_capture ()
2632 list<boost::shared_ptr<Region> > r;
2634 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2636 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2637 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2640 r.insert (r.end(), l.begin(), l.end());
2645 destroy_regions (r);
2647 save_state (_current_snapshot_name);
2653 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2659 /* Source Management */
2661 Session::add_source (boost::shared_ptr<Source> source)
2663 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2664 pair<SourceMap::iterator,bool> result;
2666 entry.first = source->id();
2667 entry.second = source;
2670 Glib::Mutex::Lock lm (source_lock);
2671 result = sources.insert (entry);
2674 if (result.second) {
2675 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2681 Session::remove_source (boost::weak_ptr<Source> src)
2683 SourceMap::iterator i;
2684 boost::shared_ptr<Source> source = src.lock();
2691 Glib::Mutex::Lock lm (source_lock);
2694 Glib::Mutex::Lock lm (source_lock);
2696 if ((i = sources.find (source->id())) != sources.end()) {
2702 if (!_state_of_the_state & InCleanup) {
2704 /* save state so we don't end up with a session file
2705 referring to non-existent sources.
2708 save_state (_current_snapshot_name);
2712 boost::shared_ptr<Source>
2713 Session::source_by_id (const PBD::ID& id)
2715 Glib::Mutex::Lock lm (source_lock);
2716 SourceMap::iterator i;
2717 boost::shared_ptr<Source> source;
2719 if ((i = sources.find (id)) != sources.end()) {
2723 /* XXX search MIDI or other searches here */
2729 boost::shared_ptr<Source>
2730 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2732 Glib::Mutex::Lock lm (source_lock);
2734 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2735 cerr << "comparing " << path << " with " << i->second->name() << endl;
2736 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2738 if (afs && afs->path() == path && chn == afs->channel()) {
2743 return boost::shared_ptr<Source>();
2747 Session::peak_path_from_audio_path (string audio_path) const
2752 res += PBD::basename_nosuffix (audio_path);
2759 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2762 string old_basename = PBD::basename_nosuffix (oldname);
2763 string new_legalized = legalize_for_path (newname);
2765 /* note: we know (or assume) the old path is already valid */
2769 /* destructive file sources have a name of the form:
2771 /path/to/Tnnnn-NAME(%[LR])?.wav
2773 the task here is to replace NAME with the new name.
2776 /* find last slash */
2780 string::size_type slash;
2781 string::size_type dash;
2783 if ((slash = path.find_last_of ('/')) == string::npos) {
2787 dir = path.substr (0, slash+1);
2789 /* '-' is not a legal character for the NAME part of the path */
2791 if ((dash = path.find_last_of ('-')) == string::npos) {
2795 prefix = path.substr (slash+1, dash-(slash+1));
2800 path += new_legalized;
2801 path += ".wav"; /* XXX gag me with a spoon */
2805 /* non-destructive file sources have a name of the form:
2807 /path/to/NAME-nnnnn(%[LR])?.wav
2809 the task here is to replace NAME with the new name.
2814 string::size_type slash;
2815 string::size_type dash;
2816 string::size_type postfix;
2818 /* find last slash */
2820 if ((slash = path.find_last_of ('/')) == string::npos) {
2824 dir = path.substr (0, slash+1);
2826 /* '-' is not a legal character for the NAME part of the path */
2828 if ((dash = path.find_last_of ('-')) == string::npos) {
2832 suffix = path.substr (dash+1);
2834 // Suffix is now everything after the dash. Now we need to eliminate
2835 // the nnnnn part, which is done by either finding a '%' or a '.'
2837 postfix = suffix.find_last_of ("%");
2838 if (postfix == string::npos) {
2839 postfix = suffix.find_last_of ('.');
2842 if (postfix != string::npos) {
2843 suffix = suffix.substr (postfix);
2845 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2849 const uint32_t limit = 10000;
2850 char buf[PATH_MAX+1];
2852 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2854 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2856 if (access (buf, F_OK) != 0) {
2864 error << "FATAL ERROR! Could not find a " << endl;
2873 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2877 char buf[PATH_MAX+1];
2878 const uint32_t limit = 10000;
2882 legalized = legalize_for_path (name);
2884 /* find a "version" of the file name that doesn't exist in
2885 any of the possible directories.
2888 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2890 vector<space_and_path>::iterator i;
2891 uint32_t existing = 0;
2893 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2897 spath += sound_dir (false);
2901 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2902 } else if (nchan == 2) {
2904 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2906 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2908 } else if (nchan < 26) {
2909 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2911 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2920 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2921 } else if (nchan == 2) {
2923 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2925 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2927 } else if (nchan < 26) {
2928 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2930 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2934 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2940 if (existing == 0) {
2945 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2947 throw failed_constructor();
2951 /* we now have a unique name for the file, but figure out where to
2957 spath = discover_best_sound_dir ();
2960 string::size_type pos = foo.find_last_of ('/');
2962 if (pos == string::npos) {
2965 spath += foo.substr (pos + 1);
2971 boost::shared_ptr<AudioFileSource>
2972 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2974 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2975 return boost::dynamic_pointer_cast<AudioFileSource> (
2976 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2979 // FIXME: _terrible_ code duplication
2981 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
2984 string old_basename = PBD::basename_nosuffix (oldname);
2985 string new_legalized = legalize_for_path (newname);
2987 /* note: we know (or assume) the old path is already valid */
2991 /* destructive file sources have a name of the form:
2993 /path/to/Tnnnn-NAME(%[LR])?.wav
2995 the task here is to replace NAME with the new name.
2998 /* find last slash */
3002 string::size_type slash;
3003 string::size_type dash;
3005 if ((slash = path.find_last_of ('/')) == string::npos) {
3009 dir = path.substr (0, slash+1);
3011 /* '-' is not a legal character for the NAME part of the path */
3013 if ((dash = path.find_last_of ('-')) == string::npos) {
3017 prefix = path.substr (slash+1, dash-(slash+1));
3022 path += new_legalized;
3023 path += ".mid"; /* XXX gag me with a spoon */
3027 /* non-destructive file sources have a name of the form:
3029 /path/to/NAME-nnnnn(%[LR])?.wav
3031 the task here is to replace NAME with the new name.
3036 string::size_type slash;
3037 string::size_type dash;
3038 string::size_type postfix;
3040 /* find last slash */
3042 if ((slash = path.find_last_of ('/')) == string::npos) {
3046 dir = path.substr (0, slash+1);
3048 /* '-' is not a legal character for the NAME part of the path */
3050 if ((dash = path.find_last_of ('-')) == string::npos) {
3054 suffix = path.substr (dash+1);
3056 // Suffix is now everything after the dash. Now we need to eliminate
3057 // the nnnnn part, which is done by either finding a '%' or a '.'
3059 postfix = suffix.find_last_of ("%");
3060 if (postfix == string::npos) {
3061 postfix = suffix.find_last_of ('.');
3064 if (postfix != string::npos) {
3065 suffix = suffix.substr (postfix);
3067 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3071 const uint32_t limit = 10000;
3072 char buf[PATH_MAX+1];
3074 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3076 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3078 if (access (buf, F_OK) != 0) {
3086 error << "FATAL ERROR! Could not find a " << endl;
3095 Session::midi_path_from_name (string name)
3099 char buf[PATH_MAX+1];
3100 const uint32_t limit = 10000;
3104 legalized = legalize_for_path (name);
3106 /* find a "version" of the file name that doesn't exist in
3107 any of the possible directories.
3110 for (cnt = 1; cnt <= limit; ++cnt) {
3112 vector<space_and_path>::iterator i;
3113 uint32_t existing = 0;
3115 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3119 // FIXME: different directory from audio?
3120 spath += sound_dir(false) + "/" + legalized;
3122 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3124 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3129 if (existing == 0) {
3134 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3135 throw failed_constructor();
3139 /* we now have a unique name for the file, but figure out where to
3145 // FIXME: different directory than audio?
3146 spath = discover_best_sound_dir ();
3149 string::size_type pos = foo.find_last_of ('/');
3151 if (pos == string::npos) {
3154 spath += foo.substr (pos + 1);
3160 boost::shared_ptr<MidiSource>
3161 Session::create_midi_source_for_session (MidiDiskstream& ds)
3163 string spath = midi_path_from_name (ds.name());
3165 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3169 /* Playlist management */
3171 boost::shared_ptr<Playlist>
3172 Session::playlist_by_name (string name)
3174 Glib::Mutex::Lock lm (playlist_lock);
3175 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3176 if ((*i)->name() == name) {
3180 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3181 if ((*i)->name() == name) {
3186 return boost::shared_ptr<Playlist>();
3190 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3192 if (playlist->hidden()) {
3197 Glib::Mutex::Lock lm (playlist_lock);
3198 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3199 playlists.insert (playlists.begin(), playlist);
3200 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3201 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3207 PlaylistAdded (playlist); /* EMIT SIGNAL */
3211 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3214 Glib::Mutex::Lock lm (playlist_lock);
3215 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3218 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3225 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3227 boost::shared_ptr<Playlist> pl(wpl.lock());
3233 PlaylistList::iterator x;
3236 /* its not supposed to be visible */
3241 Glib::Mutex::Lock lm (playlist_lock);
3245 unused_playlists.insert (pl);
3247 if ((x = playlists.find (pl)) != playlists.end()) {
3248 playlists.erase (x);
3254 playlists.insert (pl);
3256 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3257 unused_playlists.erase (x);
3264 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3266 if (_state_of_the_state & Deletion) {
3270 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3277 Glib::Mutex::Lock lm (playlist_lock);
3279 PlaylistList::iterator i;
3281 i = find (playlists.begin(), playlists.end(), playlist);
3282 if (i != playlists.end()) {
3283 playlists.erase (i);
3286 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3287 if (i != unused_playlists.end()) {
3288 unused_playlists.erase (i);
3295 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3299 Session::set_audition (boost::shared_ptr<Region> r)
3301 pending_audition_region = r;
3302 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3303 schedule_butler_transport_work ();
3307 Session::audition_playlist ()
3309 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3310 ev->region.reset ();
3315 Session::non_realtime_set_audition ()
3317 if (!pending_audition_region) {
3318 auditioner->audition_current_playlist ();
3320 auditioner->audition_region (pending_audition_region);
3321 pending_audition_region.reset ();
3323 AuditionActive (true); /* EMIT SIGNAL */
3327 Session::audition_region (boost::shared_ptr<Region> r)
3329 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3335 Session::cancel_audition ()
3337 if (auditioner->active()) {
3338 auditioner->cancel_audition ();
3339 AuditionActive (false); /* EMIT SIGNAL */
3344 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3346 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3350 Session::remove_empty_sounds ()
3352 PathScanner scanner;
3354 vector<string *>* possible_audiofiles = scanner (sound_dir(), Config->get_possible_audio_file_regexp (), false, true);
3356 Glib::Mutex::Lock lm (source_lock);
3358 regex_t compiled_tape_track_pattern;
3361 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3365 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3367 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3371 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3373 /* never remove files that appear to be a tape track */
3375 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3380 if (AudioFileSource::is_empty (*this, *(*i))) {
3382 unlink ((*i)->c_str());
3384 string peak_path = peak_path_from_audio_path (**i);
3385 unlink (peak_path.c_str());
3391 delete possible_audiofiles;
3395 Session::is_auditioning () const
3397 /* can be called before we have an auditioner object */
3399 return auditioner->active();
3406 Session::set_all_solo (bool yn)
3408 shared_ptr<RouteList> r = routes.reader ();
3410 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3411 if (!(*i)->hidden()) {
3412 (*i)->set_solo (yn, this);
3420 Session::set_all_mute (bool yn)
3422 shared_ptr<RouteList> r = routes.reader ();
3424 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3425 if (!(*i)->hidden()) {
3426 (*i)->set_mute (yn, this);
3434 Session::n_diskstreams () const
3438 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3440 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3441 if (!(*i)->hidden()) {
3449 Session::graph_reordered ()
3451 /* don't do this stuff if we are setting up connections
3452 from a set_state() call or creating new tracks.
3455 if (_state_of_the_state & InitialConnecting) {
3459 /* every track/bus asked for this to be handled but it was deferred because
3460 we were connecting. do it now.
3463 request_input_change_handling ();
3467 /* force all diskstreams to update their capture offset values to
3468 reflect any changes in latencies within the graph.
3471 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3473 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3474 (*i)->set_capture_offset ();
3479 Session::record_disenable_all ()
3481 record_enable_change_all (false);
3485 Session::record_enable_all ()
3487 record_enable_change_all (true);
3491 Session::record_enable_change_all (bool yn)
3493 shared_ptr<RouteList> r = routes.reader ();
3495 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3498 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3499 at->set_record_enable (yn, this);
3503 /* since we don't keep rec-enable state, don't mark session dirty */
3507 Session::add_redirect (Redirect* redirect)
3511 PortInsert* port_insert;
3512 PluginInsert* plugin_insert;
3514 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3515 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3516 _port_inserts.insert (_port_inserts.begin(), port_insert);
3517 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3518 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3520 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3523 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3524 _sends.insert (_sends.begin(), send);
3526 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3530 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3536 Session::remove_redirect (Redirect* redirect)
3540 PortInsert* port_insert;
3541 PluginInsert* plugin_insert;
3543 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3544 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3545 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3546 if (x != _port_inserts.end()) {
3547 insert_bitset[port_insert->bit_slot()] = false;
3548 _port_inserts.erase (x);
3550 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3551 _plugin_inserts.remove (plugin_insert);
3553 fatal << string_compose (_("programming error: %1"),
3554 X_("unknown type of Insert deleted!"))
3558 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3559 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3560 if (x != _sends.end()) {
3561 send_bitset[send->bit_slot()] = false;
3565 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3573 Session::available_capture_duration ()
3575 float sample_bytes_on_disk = 4.0; // keep gcc happy
3577 switch (Config->get_native_file_data_format()) {
3579 sample_bytes_on_disk = 4.0;
3583 sample_bytes_on_disk = 3.0;
3587 /* impossible, but keep some gcc versions happy */
3588 fatal << string_compose (_("programming error: %1"),
3589 X_("illegal native file data format"))
3594 double scale = 4096.0 / sample_bytes_on_disk;
3596 if (_total_free_4k_blocks * scale > (double) max_frames) {
3600 return (nframes_t) floor (_total_free_4k_blocks * scale);
3604 Session::add_connection (ARDOUR::Connection* connection)
3607 Glib::Mutex::Lock guard (connection_lock);
3608 _connections.push_back (connection);
3611 ConnectionAdded (connection); /* EMIT SIGNAL */
3617 Session::remove_connection (ARDOUR::Connection* connection)
3619 bool removed = false;
3622 Glib::Mutex::Lock guard (connection_lock);
3623 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3625 if (i != _connections.end()) {
3626 _connections.erase (i);
3632 ConnectionRemoved (connection); /* EMIT SIGNAL */
3638 ARDOUR::Connection *
3639 Session::connection_by_name (string name) const
3641 Glib::Mutex::Lock lm (connection_lock);
3643 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3644 if ((*i)->name() == name) {
3653 Session::tempo_map_changed (Change ignored)
3659 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3660 * the given count with the current block size.
3663 Session::ensure_buffers (ChanCount howmany)
3665 // FIXME: NASTY assumption (midi block size == audio block size)
3666 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3667 _send_buffers->ensure_buffers(howmany, current_block_size);
3668 _silent_buffers->ensure_buffers(howmany, current_block_size);
3670 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3674 Session::next_insert_id ()
3676 /* this doesn't really loop forever. just think about it */
3679 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3680 if (!insert_bitset[n]) {
3681 insert_bitset[n] = true;
3687 /* none available, so resize and try again */
3689 insert_bitset.resize (insert_bitset.size() + 16, false);
3694 Session::next_send_id ()
3696 /* this doesn't really loop forever. just think about it */
3699 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3700 if (!send_bitset[n]) {
3701 send_bitset[n] = true;
3707 /* none available, so resize and try again */
3709 send_bitset.resize (send_bitset.size() + 16, false);
3714 Session::mark_send_id (uint32_t id)
3716 if (id >= send_bitset.size()) {
3717 send_bitset.resize (id+16, false);
3719 if (send_bitset[id]) {
3720 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3722 send_bitset[id] = true;
3726 Session::mark_insert_id (uint32_t id)
3728 if (id >= insert_bitset.size()) {
3729 insert_bitset.resize (id+16, false);
3731 if (insert_bitset[id]) {
3732 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3734 insert_bitset[id] = true;
3737 /* Named Selection management */
3740 Session::named_selection_by_name (string name)
3742 Glib::Mutex::Lock lm (named_selection_lock);
3743 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3744 if ((*i)->name == name) {
3752 Session::add_named_selection (NamedSelection* named_selection)
3755 Glib::Mutex::Lock lm (named_selection_lock);
3756 named_selections.insert (named_selections.begin(), named_selection);
3759 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3765 NamedSelectionAdded (); /* EMIT SIGNAL */
3769 Session::remove_named_selection (NamedSelection* named_selection)
3771 bool removed = false;
3774 Glib::Mutex::Lock lm (named_selection_lock);
3776 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3778 if (i != named_selections.end()) {
3780 named_selections.erase (i);
3787 NamedSelectionRemoved (); /* EMIT SIGNAL */
3792 Session::reset_native_file_format ()
3794 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3796 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3797 (*i)->reset_write_sources (false);
3802 Session::route_name_unique (string n) const
3804 shared_ptr<RouteList> r = routes.reader ();
3806 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3807 if ((*i)->name() == n) {
3816 Session::n_playlists () const
3818 Glib::Mutex::Lock lm (playlist_lock);
3819 return playlists.size();
3823 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3825 if (!force && howmany <= _npan_buffers) {
3829 if (_pan_automation_buffer) {
3831 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3832 delete [] _pan_automation_buffer[i];
3835 delete [] _pan_automation_buffer;
3838 _pan_automation_buffer = new pan_t*[howmany];
3840 for (uint32_t i = 0; i < howmany; ++i) {
3841 _pan_automation_buffer[i] = new pan_t[nframes];
3844 _npan_buffers = howmany;
3848 Session::freeze (InterThreadInfo& itt)
3850 shared_ptr<RouteList> r = routes.reader ();
3852 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3856 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3857 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3868 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3869 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3872 boost::shared_ptr<Playlist> playlist;
3873 boost::shared_ptr<AudioFileSource> fsource;
3875 char buf[PATH_MAX+1];
3877 ChanCount nchans(track.audio_diskstream()->n_channels());
3879 nframes_t this_chunk;
3883 // any bigger than this seems to cause stack overflows in called functions
3884 const nframes_t chunk_size = (128 * 1024)/4;
3886 g_atomic_int_set (&processing_prohibited, 1);
3888 /* call tree *MUST* hold route_lock */
3890 if ((playlist = track.diskstream()->playlist()) == 0) {
3894 /* external redirects will be a problem */
3896 if (track.has_external_redirects()) {
3900 dir = discover_best_sound_dir ();
3902 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3904 for (x = 0; x < 99999; ++x) {
3905 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3906 if (access (buf, F_OK) != 0) {
3912 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3917 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3918 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3921 catch (failed_constructor& err) {
3922 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3926 srcs.push_back (fsource);
3929 /* XXX need to flush all redirects */
3934 /* create a set of reasonably-sized buffers */
3935 buffers.ensure_buffers(nchans, chunk_size);
3936 buffers.set_count(nchans);
3938 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3939 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3941 afs->prepare_for_peakfile_writes ();
3944 while (to_do && !itt.cancel) {
3946 this_chunk = min (to_do, chunk_size);
3948 if (track.export_stuff (buffers, start, this_chunk)) {
3953 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3954 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3957 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3963 start += this_chunk;
3964 to_do -= this_chunk;
3966 itt.progress = (float) (1.0 - ((double) to_do / len));
3975 xnow = localtime (&now);
3977 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3978 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3981 afs->update_header (position, *xnow, now);
3982 afs->flush_header ();
3986 /* construct a region to represent the bounced material */
3988 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3989 region_name_from_path (srcs.front()->name(), true));
3996 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3997 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4000 afs->mark_for_remove ();
4003 (*src)->drop_references ();
4007 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4008 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4011 afs->done_with_peakfile_writes ();
4015 g_atomic_int_set (&processing_prohibited, 0);
4021 Session::get_silent_buffers (ChanCount count)
4023 assert(_silent_buffers->available() >= count);
4024 _silent_buffers->set_count(count);
4026 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4027 for (size_t i=0; i < count.get(*t); ++i) {
4028 _silent_buffers->get(*t, i).clear();
4032 return *_silent_buffers;
4036 Session::get_scratch_buffers (ChanCount count)
4038 assert(_scratch_buffers->available() >= count);
4039 _scratch_buffers->set_count(count);
4040 return *_scratch_buffers;
4044 Session::get_send_buffers (ChanCount count)
4046 assert(_send_buffers->available() >= count);
4047 _send_buffers->set_count(count);
4048 return *_send_buffers;
4052 Session::ntracks () const
4055 shared_ptr<RouteList> r = routes.reader ();
4057 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4058 if (dynamic_cast<Track*> ((*i).get())) {
4067 Session::nbusses () const
4070 shared_ptr<RouteList> r = routes.reader ();
4072 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4073 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4082 Session::add_automation_list(AutomationList *al)
4084 automation_lists[al->id()] = al;
4088 Session::compute_initial_length ()
4090 return _engine.frame_rate() * 60 * 5;