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>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_track.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/audioplaylist.h"
53 #include "ardour/audioregion.h"
54 #include "ardour/auditioner.h"
55 #include "ardour/buffer_set.h"
56 #include "ardour/bundle.h"
57 #include "ardour/click.h"
58 #include "ardour/configuration.h"
59 #include "ardour/crossfade.h"
60 #include "ardour/cycle_timer.h"
61 #include "ardour/data_type.h"
62 #include "ardour/filename_extensions.h"
63 #include "ardour/io_processor.h"
64 #include "ardour/midi_diskstream.h"
65 #include "ardour/midi_playlist.h"
66 #include "ardour/midi_region.h"
67 #include "ardour/midi_track.h"
68 #include "ardour/named_selection.h"
69 #include "ardour/playlist.h"
70 #include "ardour/plugin_insert.h"
71 #include "ardour/port_insert.h"
72 #include "ardour/processor.h"
73 #include "ardour/recent_sessions.h"
74 #include "ardour/region_factory.h"
75 #include "ardour/route_group.h"
76 #include "ardour/send.h"
77 #include "ardour/session.h"
78 #include "ardour/session_directory.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_metadata.h"
81 #include "ardour/slave.h"
82 #include "ardour/smf_source.h"
83 #include "ardour/source_factory.h"
84 #include "ardour/tape_file_matcher.h"
85 #include "ardour/tempo.h"
86 #include "ardour/utils.h"
91 using namespace ARDOUR;
93 using boost::shared_ptr;
95 bool Session::_disable_all_loaded_plugins = false;
97 sigc::signal<void,std::string> Session::Dialog;
98 sigc::signal<int> Session::AskAboutPendingState;
99 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
100 sigc::signal<void> Session::SendFeedback;
102 sigc::signal<void> Session::SMPTEOffsetChanged;
103 sigc::signal<void> Session::StartTimeChanged;
104 sigc::signal<void> Session::EndTimeChanged;
105 sigc::signal<void> Session::AutoBindingOn;
106 sigc::signal<void> Session::AutoBindingOff;
107 sigc::signal<void, std::string, std::string> Session::Exported;
109 Session::Session (AudioEngine &eng,
110 const string& fullpath,
111 const string& snapshot_name,
115 _requested_return_frame (-1),
116 _scratch_buffers(new BufferSet()),
117 _silent_buffers(new BufferSet()),
118 _mix_buffers(new BufferSet()),
120 _mmc_port (default_mmc_port),
121 _mtc_port (default_mtc_port),
122 _midi_port (default_midi_port),
123 _midi_clock_port (default_midi_clock_port),
124 _session_dir (new SessionDirectory(fullpath)),
125 pending_events (2048),
127 butler_mixdown_buffer (0),
128 butler_gain_buffer (0),
129 post_transport_work((PostTransportWork)0),
130 _send_smpte_update (false),
131 midi_thread (pthread_t (0)),
132 midi_requests (128), // the size of this should match the midi request pool size
133 diskstreams (new DiskstreamList),
134 routes (new RouteList),
135 auditioner ((Auditioner*) 0),
136 _total_free_4k_blocks (0),
137 _bundles (new BundleList),
138 _bundle_xml_node (0),
141 click_emphasis_data (0),
143 _metadata (new SessionMetadata())
148 if (!eng.connected()) {
149 throw failed_constructor();
152 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
154 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
155 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
157 first_stage_init (fullpath, snapshot_name);
159 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
162 if (create (new_session, mix_template, compute_initial_length())) {
164 throw failed_constructor ();
168 if (second_stage_init (new_session)) {
170 throw failed_constructor ();
173 store_recent_sessions(_name, _path);
175 bool was_dirty = dirty();
177 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
179 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
182 DirtyChanged (); /* EMIT SIGNAL */
186 Session::Session (AudioEngine &eng,
188 string snapshot_name,
189 AutoConnectOption input_ac,
190 AutoConnectOption output_ac,
191 uint32_t control_out_channels,
192 uint32_t master_out_channels,
193 uint32_t requested_physical_in,
194 uint32_t requested_physical_out,
195 nframes_t initial_length)
198 _requested_return_frame (-1),
199 _scratch_buffers(new BufferSet()),
200 _silent_buffers(new BufferSet()),
201 _mix_buffers(new BufferSet()),
203 _mmc_port (default_mmc_port),
204 _mtc_port (default_mtc_port),
205 _midi_port (default_midi_port),
206 _midi_clock_port (default_midi_clock_port),
207 _session_dir ( new SessionDirectory(fullpath)),
208 pending_events (2048),
210 butler_mixdown_buffer (0),
211 butler_gain_buffer (0),
212 post_transport_work((PostTransportWork)0),
213 _send_smpte_update (false),
214 midi_thread (pthread_t (0)),
216 diskstreams (new DiskstreamList),
217 routes (new RouteList),
218 auditioner ((Auditioner *) 0),
219 _total_free_4k_blocks (0),
220 _bundles (new BundleList),
221 _bundle_xml_node (0),
222 _click_io ((IO *) 0),
224 click_emphasis_data (0),
226 _metadata (new SessionMetadata())
230 if (!eng.connected()) {
231 throw failed_constructor();
234 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
236 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
237 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
239 if (n_physical_inputs) {
240 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
243 if (n_physical_outputs) {
244 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
247 first_stage_init (fullpath, snapshot_name);
249 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
252 if (create (new_session, string(), initial_length)) {
254 throw failed_constructor ();
259 /* set up Master Out and Control Out if necessary */
264 if (control_out_channels) {
265 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
266 r->set_remote_control_id (control_id++);
271 if (master_out_channels) {
272 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
273 r->set_remote_control_id (control_id);
277 /* prohibit auto-connect to master, because there isn't one */
278 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
282 add_routes (rl, false);
287 Config->set_input_auto_connect (input_ac);
288 Config->set_output_auto_connect (output_ac);
290 if (second_stage_init (new_session)) {
292 throw failed_constructor ();
295 store_recent_sessions (_name, _path);
297 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
299 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
310 /* if we got to here, leaving pending capture state around
314 remove_pending_capture_state ();
316 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
318 _engine.remove_session ();
320 GoingAway (); /* EMIT SIGNAL */
326 /* clear history so that no references to objects are held any more */
330 /* clear state tree so that no references to objects are held any more */
334 terminate_butler_thread ();
335 //terminate_midi_thread ();
337 if (click_data != default_click) {
338 delete [] click_data;
341 if (click_emphasis_data != default_click_emphasis) {
342 delete [] click_emphasis_data;
347 delete _scratch_buffers;
348 delete _silent_buffers;
351 AudioDiskstream::free_working_buffers();
353 Route::SyncOrderKeys.clear();
355 #undef TRACK_DESTRUCTION
356 #ifdef TRACK_DESTRUCTION
357 cerr << "delete named selections\n";
358 #endif /* TRACK_DESTRUCTION */
359 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
360 NamedSelectionList::iterator tmp;
369 #ifdef TRACK_DESTRUCTION
370 cerr << "delete playlists\n";
371 #endif /* TRACK_DESTRUCTION */
372 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
373 PlaylistList::iterator tmp;
378 (*i)->drop_references ();
383 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
384 PlaylistList::iterator tmp;
389 (*i)->drop_references ();
395 unused_playlists.clear ();
397 #ifdef TRACK_DESTRUCTION
398 cerr << "delete regions\n";
399 #endif /* TRACK_DESTRUCTION */
401 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
402 RegionList::iterator tmp;
407 i->second->drop_references ();
414 #ifdef TRACK_DESTRUCTION
415 cerr << "delete routes\n";
416 #endif /* TRACK_DESTRUCTION */
418 RCUWriter<RouteList> writer (routes);
419 boost::shared_ptr<RouteList> r = writer.get_copy ();
420 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
421 (*i)->drop_references ();
424 /* writer goes out of scope and updates master */
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete diskstreams\n";
431 #endif /* TRACK_DESTRUCTION */
433 RCUWriter<DiskstreamList> dwriter (diskstreams);
434 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
435 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
436 (*i)->drop_references ();
440 diskstreams.flush ();
442 #ifdef TRACK_DESTRUCTION
443 cerr << "delete audio sources\n";
444 #endif /* TRACK_DESTRUCTION */
445 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
446 SourceMap::iterator tmp;
451 i->second->drop_references ();
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete mix groups\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
461 list<RouteGroup*>::iterator tmp;
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete edit groups\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
475 list<RouteGroup*>::iterator tmp;
485 delete [] butler_mixdown_buffer;
486 delete [] butler_gain_buffer;
488 Crossfade::set_buffer_size (0);
494 Session::set_worst_io_latencies ()
496 _worst_output_latency = 0;
497 _worst_input_latency = 0;
499 if (!_engine.connected()) {
503 boost::shared_ptr<RouteList> r = routes.reader ();
505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
506 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
507 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
512 Session::when_engine_running ()
514 string first_physical_output;
516 /* we don't want to run execute this again */
518 BootMessage (_("Set block size and sample rate"));
520 set_block_size (_engine.frames_per_cycle());
521 set_frame_rate (_engine.frame_rate());
523 BootMessage (_("Using configuration"));
525 Config->map_parameters (mem_fun (*this, &Session::config_changed));
527 /* every time we reconnect, recompute worst case output latencies */
529 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
531 if (synced_to_jack()) {
532 _engine.transport_stop ();
535 if (Config->get_jack_time_master()) {
536 _engine.transport_locate (_transport_frame);
544 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
546 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
548 /* existing state for Click */
550 if (_click_io->set_state (*child->children().front()) == 0) {
552 _clicking = Config->get_clicking ();
556 error << _("could not setup Click I/O") << endmsg;
562 /* default state for Click: dual-mono to first 2 physical outputs */
564 for (int physport = 0; physport < 2; ++physport) {
565 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
567 if (physical_output.length()) {
568 if (_click_io->add_output_port (physical_output, this)) {
569 // relax, even though its an error
574 if (_click_io->n_outputs () > ChanCount::ZERO) {
575 _clicking = Config->get_clicking ();
580 catch (failed_constructor& err) {
581 error << _("cannot setup Click I/O") << endmsg;
584 BootMessage (_("Compute I/O Latencies"));
586 set_worst_io_latencies ();
589 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
592 BootMessage (_("Set up standard connections"));
594 /* Create a set of Bundle objects that map
595 to the physical I/O currently available. We create both
596 mono and stereo bundles, so that the common cases of mono
597 and stereo tracks get bundles to put in their mixer strip
598 in / out menus. There may be a nicer way of achieving that;
599 it doesn't really scale that well to higher channel counts */
601 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
603 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
605 shared_ptr<Bundle> c (new Bundle (buf, true));
606 c->add_channel (_("mono"));
607 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
612 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
613 if (np + 1 < n_physical_outputs) {
615 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
616 shared_ptr<Bundle> c (new Bundle (buf, true));
617 c->add_channel (_("L"));
618 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
619 c->add_channel (_("R"));
620 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
626 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
628 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
630 shared_ptr<Bundle> c (new Bundle (buf, false));
631 c->add_channel (_("mono"));
632 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
637 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
638 if (np + 1 < n_physical_inputs) {
640 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
642 shared_ptr<Bundle> c (new Bundle (buf, false));
643 c->add_channel (_("L"));
644 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
645 c->add_channel (_("R"));
646 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
654 /* create master/control ports */
659 /* force the master to ignore any later call to this */
661 if (_master_out->pending_state_node) {
662 _master_out->ports_became_legal();
665 /* no panner resets till we are through */
667 _master_out->defer_pan_reset ();
669 while (_master_out->n_inputs().n_audio()
670 < _master_out->input_maximum().n_audio()) {
671 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
672 error << _("cannot setup master inputs")
678 while (_master_out->n_outputs().n_audio()
679 < _master_out->output_maximum().n_audio()) {
680 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
681 error << _("cannot setup master outputs")
688 _master_out->allow_pan_reset ();
693 BootMessage (_("Setup signal flow and plugins"));
697 /* catch up on send+insert cnts */
699 BootMessage (_("Catch up with send/insert state"));
703 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
706 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
707 if (id > insert_cnt) {
715 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
718 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
726 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
728 /* hook us up to the engine */
730 BootMessage (_("Connect to engine"));
732 _engine.set_session (this);
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);
745 if (auditioner == 0) {
747 /* we delay creating the auditioner till now because
748 it makes its own connections to ports.
749 the engine has to be running for this to work.
753 auditioner.reset (new Auditioner (*this));
756 catch (failed_constructor& err) {
757 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
761 /* Tell all IO objects to create their ports */
767 vector<string> cports;
769 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
770 if (_control_out->add_input_port ("", this)) {
771 error << _("cannot setup control inputs")
777 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
778 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
779 error << _("cannot set up master outputs")
787 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
789 for (n = 0; n < ni; ++n) {
790 cports.push_back (_control_out->input(n)->name());
793 boost::shared_ptr<RouteList> r = routes.reader ();
795 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
796 (*x)->set_control_outs (cports);
800 /* load bundles, which we may have postponed earlier on */
801 if (_bundle_xml_node) {
802 load_bundles (*_bundle_xml_node);
803 delete _bundle_xml_node;
806 /* Tell all IO objects to connect themselves together */
808 IO::enable_connecting ();
810 /* Now reset all panners */
812 IO::reset_panners ();
814 /* Anyone who cares about input state, wake up and do something */
816 IOConnectionsComplete (); /* EMIT SIGNAL */
818 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
821 /* now handle the whole enchilada as if it was one
827 /* update mixer solo state */
833 Session::playlist_length_changed ()
835 /* we can't just increase end_location->end() if pl->get_maximum_extent()
836 if larger. if the playlist used to be the longest playlist,
837 and its now shorter, we have to decrease end_location->end(). hence,
838 we have to iterate over all diskstreams and check the
839 playlists currently in use.
845 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
847 boost::shared_ptr<Playlist> playlist;
849 if ((playlist = dstream->playlist()) != 0) {
850 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
853 /* see comment in playlist_length_changed () */
858 Session::record_enabling_legal () const
860 /* this used to be in here, but survey says.... we don't need to restrict it */
861 // if (record_status() == Recording) {
865 if (Config->get_all_safe()) {
872 Session::reset_input_monitor_state ()
874 if (transport_rolling()) {
876 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
878 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
879 if ((*i)->record_enabled ()) {
880 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
881 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
885 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
887 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
888 if ((*i)->record_enabled ()) {
889 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
890 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
897 Session::auto_punch_start_changed (Location* location)
899 replace_event (Event::PunchIn, location->start());
901 if (get_record_enabled() && Config->get_punch_in()) {
902 /* capture start has been changed, so save new pending state */
903 save_state ("", true);
908 Session::auto_punch_end_changed (Location* location)
910 nframes_t when_to_stop = location->end();
911 // when_to_stop += _worst_output_latency + _worst_input_latency;
912 replace_event (Event::PunchOut, when_to_stop);
916 Session::auto_punch_changed (Location* location)
918 nframes_t when_to_stop = location->end();
920 replace_event (Event::PunchIn, location->start());
921 //when_to_stop += _worst_output_latency + _worst_input_latency;
922 replace_event (Event::PunchOut, when_to_stop);
926 Session::auto_loop_changed (Location* location)
928 replace_event (Event::AutoLoop, location->end(), location->start());
930 if (transport_rolling() && play_loop) {
932 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
934 if (_transport_frame > location->end()) {
935 // relocate to beginning of loop
936 clear_events (Event::LocateRoll);
938 request_locate (location->start(), true);
941 else if (Config->get_seamless_loop() && !loop_changing) {
943 // schedule a locate-roll to refill the diskstreams at the
945 loop_changing = true;
947 if (location->end() > last_loopend) {
948 clear_events (Event::LocateRoll);
949 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
956 last_loopend = location->end();
960 Session::set_auto_punch_location (Location* location)
964 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
965 auto_punch_start_changed_connection.disconnect();
966 auto_punch_end_changed_connection.disconnect();
967 auto_punch_changed_connection.disconnect();
968 existing->set_auto_punch (false, this);
969 remove_event (existing->start(), Event::PunchIn);
970 clear_events (Event::PunchOut);
971 auto_punch_location_changed (0);
980 if (location->end() <= location->start()) {
981 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
985 auto_punch_start_changed_connection.disconnect();
986 auto_punch_end_changed_connection.disconnect();
987 auto_punch_changed_connection.disconnect();
989 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
990 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
991 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
993 location->set_auto_punch (true, this);
996 auto_punch_changed (location);
998 auto_punch_location_changed (location);
1002 Session::set_auto_loop_location (Location* location)
1006 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1007 auto_loop_start_changed_connection.disconnect();
1008 auto_loop_end_changed_connection.disconnect();
1009 auto_loop_changed_connection.disconnect();
1010 existing->set_auto_loop (false, this);
1011 remove_event (existing->end(), Event::AutoLoop);
1012 auto_loop_location_changed (0);
1017 if (location == 0) {
1021 if (location->end() <= location->start()) {
1022 error << _("Session: you can't use a mark for auto loop") << endmsg;
1026 last_loopend = location->end();
1028 auto_loop_start_changed_connection.disconnect();
1029 auto_loop_end_changed_connection.disconnect();
1030 auto_loop_changed_connection.disconnect();
1032 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1033 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1034 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1036 location->set_auto_loop (true, this);
1038 /* take care of our stuff first */
1040 auto_loop_changed (location);
1042 /* now tell everyone else */
1044 auto_loop_location_changed (location);
1048 Session::locations_added (Location* ignored)
1054 Session::locations_changed ()
1056 _locations.apply (*this, &Session::handle_locations_changed);
1060 Session::handle_locations_changed (Locations::LocationList& locations)
1062 Locations::LocationList::iterator i;
1064 bool set_loop = false;
1065 bool set_punch = false;
1067 for (i = locations.begin(); i != locations.end(); ++i) {
1071 if (location->is_auto_punch()) {
1072 set_auto_punch_location (location);
1075 if (location->is_auto_loop()) {
1076 set_auto_loop_location (location);
1080 if (location->is_start()) {
1081 start_location = location;
1083 if (location->is_end()) {
1084 end_location = location;
1089 set_auto_loop_location (0);
1092 set_auto_punch_location (0);
1099 Session::enable_record ()
1101 /* XXX really atomic compare+swap here */
1102 if (g_atomic_int_get (&_record_status) != Recording) {
1103 g_atomic_int_set (&_record_status, Recording);
1104 _last_record_location = _transport_frame;
1105 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1107 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1108 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1109 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1110 if ((*i)->record_enabled ()) {
1111 (*i)->monitor_input (true);
1116 RecordStateChanged ();
1121 Session::disable_record (bool rt_context, bool force)
1125 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1127 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1128 g_atomic_int_set (&_record_status, Disabled);
1130 if (rs == Recording) {
1131 g_atomic_int_set (&_record_status, Enabled);
1135 // FIXME: timestamp correct? [DR]
1136 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1137 // does this /need/ to be sent in all cases?
1139 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1141 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1142 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1144 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1145 if ((*i)->record_enabled ()) {
1146 (*i)->monitor_input (false);
1151 RecordStateChanged (); /* emit signal */
1154 remove_pending_capture_state ();
1160 Session::step_back_from_record ()
1162 /* XXX really atomic compare+swap here */
1163 if (g_atomic_int_get (&_record_status) == Recording) {
1164 g_atomic_int_set (&_record_status, Enabled);
1166 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1167 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1169 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1170 if ((*i)->record_enabled ()) {
1171 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1172 (*i)->monitor_input (false);
1180 Session::maybe_enable_record ()
1182 g_atomic_int_set (&_record_status, Enabled);
1184 /* this function is currently called from somewhere other than an RT thread.
1185 this save_state() call therefore doesn't impact anything.
1188 save_state ("", true);
1190 if (_transport_speed) {
1191 if (!Config->get_punch_in()) {
1195 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1196 RecordStateChanged (); /* EMIT SIGNAL */
1203 Session::audible_frame () const
1209 /* the first of these two possible settings for "offset"
1210 mean that the audible frame is stationary until
1211 audio emerges from the latency compensation
1214 the second means that the audible frame is stationary
1215 until audio would emerge from a physical port
1216 in the absence of any plugin latency compensation
1219 offset = _worst_output_latency;
1221 if (offset > current_block_size) {
1222 offset -= current_block_size;
1224 /* XXX is this correct? if we have no external
1225 physical connections and everything is internal
1226 then surely this is zero? still, how
1227 likely is that anyway?
1229 offset = current_block_size;
1232 if (synced_to_jack()) {
1233 tf = _engine.transport_frame();
1235 tf = _transport_frame;
1240 if (!non_realtime_work_pending()) {
1244 /* check to see if we have passed the first guaranteed
1245 audible frame past our last start position. if not,
1246 return that last start point because in terms
1247 of audible frames, we have not moved yet.
1250 if (_transport_speed > 0.0f) {
1252 if (!play_loop || !have_looped) {
1253 if (tf < _last_roll_location + offset) {
1254 return _last_roll_location;
1262 } else if (_transport_speed < 0.0f) {
1264 /* XXX wot? no backward looping? */
1266 if (tf > _last_roll_location - offset) {
1267 return _last_roll_location;
1279 Session::set_frame_rate (nframes_t frames_per_second)
1281 /** \fn void Session::set_frame_size(nframes_t)
1282 the AudioEngine object that calls this guarantees
1283 that it will not be called while we are also in
1284 ::process(). Its fine to do things that block
1288 _base_frame_rate = frames_per_second;
1292 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1296 // XXX we need some equivalent to this, somehow
1297 // SndFileSource::setup_standard_crossfades (frames_per_second);
1301 /* XXX need to reset/reinstantiate all LADSPA plugins */
1305 Session::set_block_size (nframes_t nframes)
1307 /* the AudioEngine guarantees
1308 that it will not be called while we are also in
1309 ::process(). It is therefore fine to do things that block
1315 current_block_size = nframes;
1317 ensure_buffers(_scratch_buffers->available());
1319 delete [] _gain_automation_buffer;
1320 _gain_automation_buffer = new gain_t[nframes];
1322 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1324 boost::shared_ptr<RouteList> r = routes.reader ();
1326 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1327 (*i)->set_block_size (nframes);
1330 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1331 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1332 (*i)->set_block_size (nframes);
1335 set_worst_io_latencies ();
1340 Session::set_default_fade (float steepness, float fade_msecs)
1343 nframes_t fade_frames;
1345 /* Don't allow fade of less 1 frame */
1347 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1354 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1358 default_fade_msecs = fade_msecs;
1359 default_fade_steepness = steepness;
1362 // jlc, WTF is this!
1363 Glib::RWLock::ReaderLock lm (route_lock);
1364 AudioRegion::set_default_fade (steepness, fade_frames);
1369 /* XXX have to do this at some point */
1370 /* foreach region using default fade, reset, then
1371 refill_all_diskstream_buffers ();
1376 struct RouteSorter {
1377 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1378 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1380 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1383 if (r1->fed_by.empty()) {
1384 if (r2->fed_by.empty()) {
1385 /* no ardour-based connections inbound to either route. just use signal order */
1386 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1388 /* r2 has connections, r1 does not; run r1 early */
1392 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1399 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1401 shared_ptr<Route> r2;
1403 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1404 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1408 /* make a copy of the existing list of routes that feed r1 */
1410 set<shared_ptr<Route> > existing = r1->fed_by;
1412 /* for each route that feeds r1, recurse, marking it as feeding
1416 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1419 /* r2 is a route that feeds r1 which somehow feeds base. mark
1420 base as being fed by r2
1423 rbase->fed_by.insert (r2);
1427 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1431 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1435 /* now recurse, so that we can mark base as being fed by
1436 all routes that feed r2
1439 trace_terminal (r2, rbase);
1446 Session::resort_routes ()
1448 /* don't do anything here with signals emitted
1449 by Routes while we are being destroyed.
1452 if (_state_of_the_state & Deletion) {
1459 RCUWriter<RouteList> writer (routes);
1460 shared_ptr<RouteList> r = writer.get_copy ();
1461 resort_routes_using (r);
1462 /* writer goes out of scope and forces update */
1467 Session::resort_routes_using (shared_ptr<RouteList> r)
1469 RouteList::iterator i, j;
1471 for (i = r->begin(); i != r->end(); ++i) {
1473 (*i)->fed_by.clear ();
1475 for (j = r->begin(); j != r->end(); ++j) {
1477 /* although routes can feed themselves, it will
1478 cause an endless recursive descent if we
1479 detect it. so don't bother checking for
1487 if ((*j)->feeds (*i)) {
1488 (*i)->fed_by.insert (*j);
1493 for (i = r->begin(); i != r->end(); ++i) {
1494 trace_terminal (*i, *i);
1501 cerr << "finished route resort\n";
1503 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1504 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1511 list<boost::shared_ptr<MidiTrack> >
1512 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1514 char track_name[32];
1515 uint32_t track_id = 0;
1518 RouteList new_routes;
1519 list<boost::shared_ptr<MidiTrack> > ret;
1520 //uint32_t control_id;
1522 // FIXME: need physical I/O and autoconnect stuff for MIDI
1524 /* count existing midi tracks */
1527 shared_ptr<RouteList> r = routes.reader ();
1529 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1530 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1531 if (!(*i)->is_hidden()) {
1533 //channels_used += (*i)->n_inputs().n_midi();
1539 vector<string> physinputs;
1540 vector<string> physoutputs;
1542 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1543 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1545 // control_id = ntracks() + nbusses();
1549 /* check for duplicate route names, since we might have pre-existing
1550 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1551 save, close,restart,add new route - first named route is now
1559 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1561 if (route_by_name (track_name) == 0) {
1565 } while (track_id < (UINT_MAX-1));
1567 shared_ptr<MidiTrack> track;
1570 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1572 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1573 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1579 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1583 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1584 port = physinputs[(channels_used+x)%nphysical_in];
1587 if (port.length() && track->connect_input (track->input (x), port, this)) {
1593 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1597 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1598 port = physoutputs[(channels_used+x)%nphysical_out];
1599 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1601 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1605 if (port.length() && track->connect_output (track->output (x), port, this)) {
1610 channels_used += track->n_inputs ().n_midi();
1614 track->midi_diskstream()->non_realtime_input_change();
1616 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1617 //track->set_remote_control_id (control_id);
1619 new_routes.push_back (track);
1620 ret.push_back (track);
1623 catch (failed_constructor &err) {
1624 error << _("Session: could not create new midi track.") << endmsg;
1627 /* we need to get rid of this, since the track failed to be created */
1628 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1631 RCUWriter<DiskstreamList> writer (diskstreams);
1632 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1633 ds->remove (track->midi_diskstream());
1640 catch (AudioEngine::PortRegistrationFailure& pfe) {
1642 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;
1645 /* we need to get rid of this, since the track failed to be created */
1646 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1649 RCUWriter<DiskstreamList> writer (diskstreams);
1650 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1651 ds->remove (track->midi_diskstream());
1662 if (!new_routes.empty()) {
1663 add_routes (new_routes, false);
1664 save_state (_current_snapshot_name);
1670 list<boost::shared_ptr<AudioTrack> >
1671 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1673 char track_name[32];
1674 uint32_t track_id = 0;
1676 uint32_t channels_used = 0;
1678 RouteList new_routes;
1679 list<boost::shared_ptr<AudioTrack> > ret;
1680 uint32_t control_id;
1682 /* count existing audio tracks */
1685 shared_ptr<RouteList> r = routes.reader ();
1687 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1688 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1689 if (!(*i)->is_hidden()) {
1691 channels_used += (*i)->n_inputs().n_audio();
1697 vector<string> physinputs;
1698 vector<string> physoutputs;
1700 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1701 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1703 control_id = ntracks() + nbusses() + 1;
1707 /* check for duplicate route names, since we might have pre-existing
1708 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1709 save, close,restart,add new route - first named route is now
1717 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1719 if (route_by_name (track_name) == 0) {
1723 } while (track_id < (UINT_MAX-1));
1725 shared_ptr<AudioTrack> track;
1728 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1730 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1731 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1732 input_channels, output_channels)
1737 if (!physinputs.empty()) {
1738 uint32_t nphysical_in = physinputs.size();
1740 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1744 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1745 port = physinputs[(channels_used+x)%nphysical_in];
1748 if (port.length() && track->connect_input (track->input (x), port, this)) {
1754 if (!physoutputs.empty()) {
1755 uint32_t nphysical_out = physoutputs.size();
1757 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1761 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1762 port = physoutputs[(channels_used+x)%nphysical_out];
1763 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1765 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1769 if (port.length() && track->connect_output (track->output (x), port, this)) {
1775 channels_used += track->n_inputs ().n_audio();
1777 track->audio_diskstream()->non_realtime_input_change();
1779 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1780 track->set_remote_control_id (control_id);
1783 new_routes.push_back (track);
1784 ret.push_back (track);
1787 catch (failed_constructor &err) {
1788 error << _("Session: could not create new audio track.") << endmsg;
1791 /* we need to get rid of this, since the track failed to be created */
1792 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1795 RCUWriter<DiskstreamList> writer (diskstreams);
1796 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1797 ds->remove (track->audio_diskstream());
1804 catch (AudioEngine::PortRegistrationFailure& pfe) {
1806 error << pfe.what() << endmsg;
1809 /* we need to get rid of this, since the track failed to be created */
1810 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1813 RCUWriter<DiskstreamList> writer (diskstreams);
1814 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1815 ds->remove (track->audio_diskstream());
1826 if (!new_routes.empty()) {
1827 add_routes (new_routes, true);
1834 Session::set_remote_control_ids ()
1836 RemoteModel m = Config->get_remote_model();
1838 shared_ptr<RouteList> r = routes.reader ();
1840 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1841 if ( MixerOrdered == m) {
1842 long order = (*i)->order_key(N_("signal"));
1843 (*i)->set_remote_control_id( order+1 );
1844 } else if ( EditorOrdered == m) {
1845 long order = (*i)->order_key(N_("editor"));
1846 (*i)->set_remote_control_id( order+1 );
1847 } else if ( UserOrdered == m) {
1848 //do nothing ... only changes to remote id's are initiated by user
1855 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1858 uint32_t bus_id = 1;
1860 uint32_t channels_used = 0;
1863 uint32_t control_id;
1865 /* count existing audio busses */
1868 shared_ptr<RouteList> r = routes.reader ();
1870 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1871 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1873 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1876 channels_used += (*i)->n_inputs().n_audio();
1882 vector<string> physinputs;
1883 vector<string> physoutputs;
1885 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1886 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1888 n_physical_audio_outputs = physoutputs.size();
1889 n_physical_audio_inputs = physinputs.size();
1891 control_id = ntracks() + nbusses() + 1;
1896 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1900 if (route_by_name (bus_name) == 0) {
1904 } while (bus_id < (UINT_MAX-1));
1907 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1909 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1910 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1911 input_channels, output_channels)
1919 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1923 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1924 port = physinputs[((n+x)%n_physical_audio_inputs)];
1927 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1933 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1936 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1937 port = physoutputs[((n+x)%n_physical_outputs)];
1938 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1940 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1944 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1949 channels_used += bus->n_inputs ().n_audio();
1951 bus->set_remote_control_id (control_id);
1954 ret.push_back (bus);
1958 catch (failed_constructor &err) {
1959 error << _("Session: could not create new audio route.") << endmsg;
1963 catch (AudioEngine::PortRegistrationFailure& pfe) {
1964 error << pfe.what() << endmsg;
1974 add_routes (ret, true);
1982 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1986 uint32_t control_id;
1989 if (!tree.read (template_path.c_str())) {
1993 XMLNode* node = tree.root();
1995 control_id = ntracks() + nbusses() + 1;
1999 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2001 std::string node_name = IO::name_from_state (*node_copy.children().front());
2003 if (route_by_name (node_name) != 0) {
2005 /* generate a new name by adding a number to the end of the template name */
2007 uint32_t number = 1;
2010 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2014 if (route_by_name (name) == 0) {
2018 } while (number < UINT_MAX);
2020 if (number == UINT_MAX) {
2021 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2025 IO::set_name_in_state (*node_copy.children().front(), name);
2028 Track::zero_diskstream_id_in_xml (node_copy);
2031 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2034 error << _("Session: cannot create track/bus from template description") << endmsg;
2038 if (boost::dynamic_pointer_cast<Track>(route)) {
2039 /* force input/output change signals so that the new diskstream
2040 picks up the configuration of the route. During session
2041 loading this normally happens in a different way.
2043 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2044 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2047 route->set_remote_control_id (control_id);
2050 ret.push_back (route);
2053 catch (failed_constructor &err) {
2054 error << _("Session: could not create new route from template") << endmsg;
2058 catch (AudioEngine::PortRegistrationFailure& pfe) {
2059 error << pfe.what() << endmsg;
2068 add_routes (ret, true);
2075 Session::add_routes (RouteList& new_routes, bool save)
2078 RCUWriter<RouteList> writer (routes);
2079 shared_ptr<RouteList> r = writer.get_copy ();
2080 r->insert (r->end(), new_routes.begin(), new_routes.end());
2081 resort_routes_using (r);
2084 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2086 boost::weak_ptr<Route> wpr (*x);
2088 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2089 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2090 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2091 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2093 if ((*x)->is_master()) {
2097 if ((*x)->is_control()) {
2098 _control_out = (*x);
2102 if (_control_out && IO::connecting_legal) {
2104 vector<string> cports;
2105 uint32_t ni = _control_out->n_inputs().n_audio();
2107 for (uint32_t n = 0; n < ni; ++n) {
2108 cports.push_back (_control_out->input(n)->name());
2111 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2112 (*x)->set_control_outs (cports);
2119 save_state (_current_snapshot_name);
2122 RouteAdded (new_routes); /* EMIT SIGNAL */
2126 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2128 /* need to do this in case we're rolling at the time, to prevent false underruns */
2129 dstream->do_refill_with_alloc ();
2131 dstream->set_block_size (current_block_size);
2134 RCUWriter<DiskstreamList> writer (diskstreams);
2135 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2136 ds->push_back (dstream);
2137 /* writer goes out of scope, copies ds back to main */
2140 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2141 /* this will connect to future changes, and check the current length */
2142 diskstream_playlist_changed (dstream);
2144 dstream->prepare ();
2149 Session::remove_route (shared_ptr<Route> route)
2152 RCUWriter<RouteList> writer (routes);
2153 shared_ptr<RouteList> rs = writer.get_copy ();
2157 /* deleting the master out seems like a dumb
2158 idea, but its more of a UI policy issue
2162 if (route == _master_out) {
2163 _master_out = shared_ptr<Route> ();
2166 if (route == _control_out) {
2167 _control_out = shared_ptr<Route> ();
2169 /* cancel control outs for all routes */
2171 vector<string> empty;
2173 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2174 (*r)->set_control_outs (empty);
2178 update_route_solo_state ();
2180 /* writer goes out of scope, forces route list update */
2183 boost::shared_ptr<Track> t;
2184 boost::shared_ptr<Diskstream> ds;
2186 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2187 ds = t->diskstream();
2193 RCUWriter<DiskstreamList> dsl (diskstreams);
2194 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2199 find_current_end ();
2201 // We need to disconnect the routes inputs and outputs
2203 route->disconnect_inputs (0);
2204 route->disconnect_outputs (0);
2206 update_latency_compensation (false, false);
2209 /* get rid of it from the dead wood collection in the route list manager */
2211 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2215 /* try to cause everyone to drop their references */
2217 route->drop_references ();
2219 sync_order_keys (N_("session"));
2221 /* save the new state of the world */
2223 if (save_state (_current_snapshot_name)) {
2224 save_history (_current_snapshot_name);
2229 Session::route_mute_changed (void* src)
2235 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2237 if (solo_update_disabled) {
2243 boost::shared_ptr<Route> route = wpr.lock ();
2246 /* should not happen */
2247 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2251 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2253 shared_ptr<RouteList> r = routes.reader ();
2255 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2257 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2261 /* don't mess with busses */
2263 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
2269 /* don't mess with tracks */
2271 if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
2276 if ((*i) != route &&
2277 ((*i)->mix_group () == 0 ||
2278 (*i)->mix_group () != route->mix_group () ||
2279 !route->mix_group ()->is_active())) {
2281 if ((*i)->soloed()) {
2283 /* if its already soloed, and solo latching is enabled,
2284 then leave it as it is.
2287 if (Config->get_solo_latched()) {
2294 solo_update_disabled = true;
2295 (*i)->set_solo (false, src);
2296 solo_update_disabled = false;
2300 bool something_soloed = false;
2301 bool same_thing_soloed = false;
2302 bool signal = false;
2304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2305 if ((*i)->soloed()) {
2306 something_soloed = true;
2307 if (boost::dynamic_pointer_cast<Track>(*i)) {
2309 same_thing_soloed = true;
2314 same_thing_soloed = true;
2322 if (something_soloed != currently_soloing) {
2324 currently_soloing = something_soloed;
2327 modify_solo_mute (is_track, same_thing_soloed);
2330 SoloActive (currently_soloing); /* EMIT SIGNAL */
2333 SoloChanged (); /* EMIT SIGNAL */
2339 Session::update_route_solo_state ()
2342 bool is_track = false;
2343 bool signal = false;
2345 /* this is where we actually implement solo by changing
2346 the solo mute setting of each track.
2349 shared_ptr<RouteList> r = routes.reader ();
2351 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2352 if ((*i)->soloed()) {
2354 if (boost::dynamic_pointer_cast<Track>(*i)) {
2361 if (mute != currently_soloing) {
2363 currently_soloing = mute;
2366 if (!is_track && !mute) {
2368 /* nothing is soloed */
2370 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2371 (*i)->set_solo_mute (false);
2381 modify_solo_mute (is_track, mute);
2384 SoloActive (currently_soloing);
2389 Session::modify_solo_mute (bool is_track, bool mute)
2391 shared_ptr<RouteList> r = routes.reader ();
2393 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2397 /* only alter track solo mute */
2399 if (boost::dynamic_pointer_cast<Track>(*i)) {
2400 if ((*i)->soloed()) {
2401 (*i)->set_solo_mute (!mute);
2403 (*i)->set_solo_mute (mute);
2409 /* only alter bus solo mute */
2411 if (!boost::dynamic_pointer_cast<Track>(*i)) {
2413 if ((*i)->soloed()) {
2415 (*i)->set_solo_mute (false);
2419 /* don't mute master or control outs
2420 in response to another bus solo
2423 if ((*i) != _master_out &&
2424 (*i) != _control_out) {
2425 (*i)->set_solo_mute (mute);
2436 Session::catch_up_on_solo ()
2438 /* this is called after set_state() to catch the full solo
2439 state, which can't be correctly determined on a per-route
2440 basis, but needs the global overview that only the session
2443 update_route_solo_state();
2447 Session::catch_up_on_solo_mute_override ()
2449 if (Config->get_solo_model() != InverseMute) {
2453 /* this is called whenever the param solo-mute-override is
2456 shared_ptr<RouteList> r = routes.reader ();
2458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2459 (*i)->catch_up_on_solo_mute_override ();
2464 Session::route_by_name (string name)
2466 shared_ptr<RouteList> r = routes.reader ();
2468 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2469 if ((*i)->name() == name) {
2474 return shared_ptr<Route> ((Route*) 0);
2478 Session::route_by_id (PBD::ID id)
2480 shared_ptr<RouteList> r = routes.reader ();
2482 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2483 if ((*i)->id() == id) {
2488 return shared_ptr<Route> ((Route*) 0);
2492 Session::route_by_remote_id (uint32_t id)
2494 shared_ptr<RouteList> r = routes.reader ();
2496 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2497 if ((*i)->remote_control_id() == id) {
2502 return shared_ptr<Route> ((Route*) 0);
2506 Session::find_current_end ()
2508 if (_state_of_the_state & Loading) {
2512 nframes_t max = get_maximum_extent ();
2514 if (max > end_location->end()) {
2515 end_location->set_end (max);
2517 DurationChanged(); /* EMIT SIGNAL */
2522 Session::get_maximum_extent () const
2527 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2529 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2530 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2532 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2533 if ((me = pl->get_maximum_extent()) > max) {
2541 boost::shared_ptr<Diskstream>
2542 Session::diskstream_by_name (string name)
2544 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2546 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2547 if ((*i)->name() == name) {
2552 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2555 boost::shared_ptr<Diskstream>
2556 Session::diskstream_by_id (const PBD::ID& id)
2558 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2560 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2561 if ((*i)->id() == id) {
2566 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2569 /* Region management */
2572 Session::new_region_name (string old)
2574 string::size_type last_period;
2576 string::size_type len = old.length() + 64;
2579 if ((last_period = old.find_last_of ('.')) == string::npos) {
2581 /* no period present - add one explicitly */
2584 last_period = old.length() - 1;
2589 number = atoi (old.substr (last_period+1).c_str());
2593 while (number < (UINT_MAX-1)) {
2595 RegionList::const_iterator i;
2600 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2603 for (i = regions.begin(); i != regions.end(); ++i) {
2604 if (i->second->name() == sbuf) {
2609 if (i == regions.end()) {
2614 if (number != (UINT_MAX-1)) {
2618 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2623 Session::region_name (string& result, string base, bool newlevel)
2628 if (base.find("/") != string::npos) {
2629 base = base.substr(base.find_last_of("/") + 1);
2634 Glib::Mutex::Lock lm (region_lock);
2636 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2645 string::size_type pos;
2647 pos = base.find_last_of ('.');
2649 /* pos may be npos, but then we just use entire base */
2651 subbase = base.substr (0, pos);
2656 Glib::Mutex::Lock lm (region_lock);
2658 map<string,uint32_t>::iterator x;
2662 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2664 region_name_map[subbase] = 1;
2667 snprintf (buf, sizeof (buf), ".%d", x->second);
2678 Session::add_region (boost::shared_ptr<Region> region)
2680 vector<boost::shared_ptr<Region> > v;
2681 v.push_back (region);
2686 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2691 Glib::Mutex::Lock lm (region_lock);
2693 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2695 boost::shared_ptr<Region> region = *ii;
2699 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2703 RegionList::iterator x;
2705 for (x = regions.begin(); x != regions.end(); ++x) {
2707 if (region->region_list_equivalent (x->second)) {
2712 if (x == regions.end()) {
2714 pair<RegionList::key_type,RegionList::mapped_type> entry;
2716 entry.first = region->id();
2717 entry.second = region;
2719 pair<RegionList::iterator,bool> x = regions.insert (entry);
2731 /* mark dirty because something has changed even if we didn't
2732 add the region to the region list.
2739 vector<boost::weak_ptr<Region> > v;
2740 boost::shared_ptr<Region> first_r;
2742 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2744 boost::shared_ptr<Region> region = *ii;
2748 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2751 v.push_back (region);
2758 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2759 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2761 update_region_name_map (region);
2765 RegionsAdded (v); /* EMIT SIGNAL */
2771 Session::update_region_name_map (boost::shared_ptr<Region> region)
2773 string::size_type last_period = region->name().find_last_of ('.');
2775 if (last_period != string::npos && last_period < region->name().length() - 1) {
2777 string base = region->name().substr (0, last_period);
2778 string number = region->name().substr (last_period+1);
2779 map<string,uint32_t>::iterator x;
2781 /* note that if there is no number, we get zero from atoi,
2785 region_name_map[base] = atoi (number);
2790 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2792 boost::shared_ptr<Region> region (weak_region.lock ());
2798 if (what_changed & Region::HiddenChanged) {
2799 /* relay hidden changes */
2800 RegionHiddenChange (region);
2803 if (what_changed & NameChanged) {
2804 update_region_name_map (region);
2809 Session::remove_region (boost::weak_ptr<Region> weak_region)
2811 RegionList::iterator i;
2812 boost::shared_ptr<Region> region (weak_region.lock ());
2818 bool removed = false;
2821 Glib::Mutex::Lock lm (region_lock);
2823 if ((i = regions.find (region->id())) != regions.end()) {
2829 /* mark dirty because something has changed even if we didn't
2830 remove the region from the region list.
2836 RegionRemoved(region); /* EMIT SIGNAL */
2840 boost::shared_ptr<Region>
2841 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2843 RegionList::iterator i;
2844 boost::shared_ptr<Region> region;
2846 Glib::Mutex::Lock lm (region_lock);
2848 for (i = regions.begin(); i != regions.end(); ++i) {
2852 if (region->whole_file()) {
2854 if (child->source_equivalent (region)) {
2860 return boost::shared_ptr<Region> ();
2864 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2866 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2867 (*i)->get_region_list_equivalent_regions (region, result);
2871 Session::destroy_region (boost::shared_ptr<Region> region)
2873 vector<boost::shared_ptr<Source> > srcs;
2876 if (region->playlist()) {
2877 region->playlist()->destroy_region (region);
2880 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2881 srcs.push_back (region->source (n));
2885 region->drop_references ();
2887 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2889 (*i)->mark_for_remove ();
2890 (*i)->drop_references ();
2892 cerr << "source was not used by any playlist\n";
2899 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2901 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2902 destroy_region (*i);
2908 Session::remove_last_capture ()
2910 list<boost::shared_ptr<Region> > r;
2912 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2914 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2915 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2918 r.insert (r.end(), l.begin(), l.end());
2923 destroy_regions (r);
2925 save_state (_current_snapshot_name);
2931 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2937 /* Source Management */
2940 Session::add_source (boost::shared_ptr<Source> source)
2942 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2943 pair<SourceMap::iterator,bool> result;
2945 entry.first = source->id();
2946 entry.second = source;
2949 Glib::Mutex::Lock lm (source_lock);
2950 result = sources.insert (entry);
2953 if (result.second) {
2954 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2958 boost::shared_ptr<AudioFileSource> afs;
2960 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2961 if (Config->get_auto_analyse_audio()) {
2962 Analyser::queue_source_for_analysis (source, false);
2968 Session::remove_source (boost::weak_ptr<Source> src)
2970 SourceMap::iterator i;
2971 boost::shared_ptr<Source> source = src.lock();
2978 Glib::Mutex::Lock lm (source_lock);
2980 if ((i = sources.find (source->id())) != sources.end()) {
2985 if (!_state_of_the_state & InCleanup) {
2987 /* save state so we don't end up with a session file
2988 referring to non-existent sources.
2991 save_state (_current_snapshot_name);
2995 boost::shared_ptr<Source>
2996 Session::source_by_id (const PBD::ID& id)
2998 Glib::Mutex::Lock lm (source_lock);
2999 SourceMap::iterator i;
3000 boost::shared_ptr<Source> source;
3002 if ((i = sources.find (id)) != sources.end()) {
3009 boost::shared_ptr<Source>
3010 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3012 Glib::Mutex::Lock lm (source_lock);
3014 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3015 cerr << "comparing " << path << " with " << i->second->name() << endl;
3016 boost::shared_ptr<AudioFileSource> afs
3017 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3019 if (afs && afs->path() == path && chn == afs->channel()) {
3023 return boost::shared_ptr<Source>();
3028 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3031 string old_basename = PBD::basename_nosuffix (oldname);
3032 string new_legalized = legalize_for_path (newname);
3034 /* note: we know (or assume) the old path is already valid */
3038 /* destructive file sources have a name of the form:
3040 /path/to/Tnnnn-NAME(%[LR])?.wav
3042 the task here is to replace NAME with the new name.
3045 /* find last slash */
3049 string::size_type slash;
3050 string::size_type dash;
3052 if ((slash = path.find_last_of ('/')) == string::npos) {
3056 dir = path.substr (0, slash+1);
3058 /* '-' is not a legal character for the NAME part of the path */
3060 if ((dash = path.find_last_of ('-')) == string::npos) {
3064 prefix = path.substr (slash+1, dash-(slash+1));
3069 path += new_legalized;
3070 path += ".wav"; /* XXX gag me with a spoon */
3074 /* non-destructive file sources have a name of the form:
3076 /path/to/NAME-nnnnn(%[LR])?.ext
3078 the task here is to replace NAME with the new name.
3083 string::size_type slash;
3084 string::size_type dash;
3085 string::size_type postfix;
3087 /* find last slash */
3089 if ((slash = path.find_last_of ('/')) == string::npos) {
3093 dir = path.substr (0, slash+1);
3095 /* '-' is not a legal character for the NAME part of the path */
3097 if ((dash = path.find_last_of ('-')) == string::npos) {
3101 suffix = path.substr (dash+1);
3103 // Suffix is now everything after the dash. Now we need to eliminate
3104 // the nnnnn part, which is done by either finding a '%' or a '.'
3106 postfix = suffix.find_last_of ("%");
3107 if (postfix == string::npos) {
3108 postfix = suffix.find_last_of ('.');
3111 if (postfix != string::npos) {
3112 suffix = suffix.substr (postfix);
3114 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3118 const uint32_t limit = 10000;
3119 char buf[PATH_MAX+1];
3121 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3123 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3125 if (access (buf, F_OK) != 0) {
3133 error << "FATAL ERROR! Could not find a " << endl;
3141 /** Return the full path (in some session directory) for a new embedded source.
3142 * \a name must be a session-unique name that does not contain slashes
3143 * (e.g. as returned by new_*_source_name)
3146 Session::new_source_path_from_name (DataType type, const string& name)
3148 assert(name.find("/") == string::npos);
3150 SessionDirectory sdir(get_best_session_directory_for_new_source());
3153 if (type == DataType::AUDIO) {
3154 p = sdir.sound_path();
3155 } else if (type == DataType::MIDI) {
3156 p = sdir.midi_path();
3158 error << "Unknown source type, unable to create file path" << endmsg;
3163 return p.to_string();
3167 Session::peak_path (Glib::ustring base) const
3169 sys::path peakfile_path(_session_dir->peak_path());
3170 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3171 return peakfile_path.to_string();
3174 /** Return a unique name based on \a base for a new internal audio source */
3176 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3180 char buf[PATH_MAX+1];
3181 const uint32_t limit = 10000;
3185 legalized = legalize_for_path (base);
3187 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3188 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3190 vector<space_and_path>::iterator i;
3191 uint32_t existing = 0;
3193 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3195 SessionDirectory sdir((*i).path);
3197 spath = sdir.sound_path().to_string();
3202 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3203 spath.c_str(), cnt, legalized.c_str());
3204 } else if (nchan == 2) {
3206 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3207 spath.c_str(), cnt, legalized.c_str());
3209 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3210 spath.c_str(), cnt, legalized.c_str());
3212 } else if (nchan < 26) {
3213 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3214 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3216 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3217 spath.c_str(), cnt, legalized.c_str());
3226 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3227 } else if (nchan == 2) {
3229 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3231 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3233 } else if (nchan < 26) {
3234 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3236 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3240 if (sys::exists(buf)) {
3246 if (existing == 0) {
3251 error << string_compose(
3252 _("There are already %1 recordings for %2, which I consider too many."),
3253 limit, base) << endmsg;
3255 throw failed_constructor();
3259 return Glib::path_get_basename(buf);
3262 /** Create a new embedded audio source */
3263 boost::shared_ptr<AudioFileSource>
3264 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3266 const size_t n_chans = ds.n_channels().n_audio();
3267 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3268 const string path = new_source_path_from_name(DataType::AUDIO, name);
3269 return boost::dynamic_pointer_cast<AudioFileSource> (
3270 SourceFactory::createWritable (
3271 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3274 /** Return a unique name based on \a base for a new internal MIDI source */
3276 Session::new_midi_source_name (const string& base)
3279 char buf[PATH_MAX+1];
3280 const uint32_t limit = 10000;
3284 legalized = legalize_for_path (base);
3286 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3287 for (cnt = 1; cnt <= limit; ++cnt) {
3289 vector<space_and_path>::iterator i;
3290 uint32_t existing = 0;
3292 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3294 SessionDirectory sdir((*i).path);
3296 sys::path p = sdir.midi_path();
3299 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3301 if (sys::exists (buf)) {
3306 if (existing == 0) {
3311 error << string_compose(
3312 _("There are already %1 recordings for %2, which I consider too many."),
3313 limit, base) << endmsg;
3315 throw failed_constructor();
3319 return Glib::path_get_basename(buf);
3323 /** Create a new embedded MIDI source */
3324 boost::shared_ptr<MidiSource>
3325 Session::create_midi_source_for_session (MidiDiskstream& ds)
3327 const string name = new_midi_source_name (ds.name());
3328 const string path = new_source_path_from_name (DataType::MIDI, name);
3330 return boost::dynamic_pointer_cast<SMFSource> (
3331 SourceFactory::createWritable (
3332 DataType::MIDI, *this, path, true, false, frame_rate()));
3336 /* Playlist management */
3338 boost::shared_ptr<Playlist>
3339 Session::playlist_by_name (string name)
3341 Glib::Mutex::Lock lm (playlist_lock);
3342 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3343 if ((*i)->name() == name) {
3347 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3348 if ((*i)->name() == name) {
3353 return boost::shared_ptr<Playlist>();
3357 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3359 Glib::Mutex::Lock lm (playlist_lock);
3360 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3361 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3362 list.push_back (*i);
3365 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3366 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3367 list.push_back (*i);
3373 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3375 if (playlist->hidden()) {
3380 Glib::Mutex::Lock lm (playlist_lock);
3381 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3382 playlists.insert (playlists.begin(), playlist);
3383 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3384 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3389 playlist->release();
3394 PlaylistAdded (playlist); /* EMIT SIGNAL */
3398 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3401 Glib::Mutex::Lock lm (playlist_lock);
3402 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3405 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3412 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3414 boost::shared_ptr<Playlist> pl(wpl.lock());
3420 PlaylistList::iterator x;
3423 /* its not supposed to be visible */
3428 Glib::Mutex::Lock lm (playlist_lock);
3432 unused_playlists.insert (pl);
3434 if ((x = playlists.find (pl)) != playlists.end()) {
3435 playlists.erase (x);
3441 playlists.insert (pl);
3443 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3444 unused_playlists.erase (x);
3451 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3453 if (_state_of_the_state & Deletion) {
3457 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3464 Glib::Mutex::Lock lm (playlist_lock);
3466 PlaylistList::iterator i;
3468 i = find (playlists.begin(), playlists.end(), playlist);
3469 if (i != playlists.end()) {
3470 playlists.erase (i);
3473 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3474 if (i != unused_playlists.end()) {
3475 unused_playlists.erase (i);
3482 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3486 Session::set_audition (boost::shared_ptr<Region> r)
3488 pending_audition_region = r;
3489 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3490 schedule_butler_transport_work ();
3494 Session::audition_playlist ()
3496 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3497 ev->region.reset ();
3502 Session::non_realtime_set_audition ()
3504 if (!pending_audition_region) {
3505 auditioner->audition_current_playlist ();
3507 auditioner->audition_region (pending_audition_region);
3508 pending_audition_region.reset ();
3510 AuditionActive (true); /* EMIT SIGNAL */
3514 Session::audition_region (boost::shared_ptr<Region> r)
3516 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3522 Session::cancel_audition ()
3524 if (auditioner->active()) {
3525 auditioner->cancel_audition ();
3526 AuditionActive (false); /* EMIT SIGNAL */
3531 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3533 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3537 Session::remove_empty_sounds ()
3539 vector<string> audio_filenames;
3541 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3543 Glib::Mutex::Lock lm (source_lock);
3545 TapeFileMatcher tape_file_matcher;
3547 remove_if (audio_filenames.begin(), audio_filenames.end(),
3548 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3550 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3552 sys::path audio_file_path (_session_dir->sound_path());
3554 audio_file_path /= *i;
3556 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3560 sys::remove (audio_file_path);
3561 const string peakfile = peak_path (audio_file_path.to_string());
3562 sys::remove (peakfile);
3564 catch (const sys::filesystem_error& err)
3566 error << err.what() << endmsg;
3573 Session::is_auditioning () const
3575 /* can be called before we have an auditioner object */
3577 return auditioner->active();
3584 Session::set_all_solo (bool yn)
3586 shared_ptr<RouteList> r = routes.reader ();
3588 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3589 if (!(*i)->is_hidden()) {
3590 (*i)->set_solo (yn, this);
3598 Session::set_all_mute (bool yn)
3600 shared_ptr<RouteList> r = routes.reader ();
3602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3603 if (!(*i)->is_hidden()) {
3604 (*i)->set_mute (yn, this);
3612 Session::n_diskstreams () const
3616 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3618 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3619 if (!(*i)->hidden()) {
3627 Session::graph_reordered ()
3629 /* don't do this stuff if we are setting up connections
3630 from a set_state() call or creating new tracks.
3633 if (_state_of_the_state & InitialConnecting) {
3637 /* every track/bus asked for this to be handled but it was deferred because
3638 we were connecting. do it now.
3641 request_input_change_handling ();
3645 /* force all diskstreams to update their capture offset values to
3646 reflect any changes in latencies within the graph.
3649 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3651 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3652 (*i)->set_capture_offset ();
3657 Session::record_disenable_all ()
3659 record_enable_change_all (false);
3663 Session::record_enable_all ()
3665 record_enable_change_all (true);
3669 Session::record_enable_change_all (bool yn)
3671 shared_ptr<RouteList> r = routes.reader ();
3673 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3674 boost::shared_ptr<Track> t;
3676 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3677 t->set_record_enable (yn, this);
3681 /* since we don't keep rec-enable state, don't mark session dirty */
3685 Session::add_processor (Processor* processor)
3688 PortInsert* port_insert;
3689 PluginInsert* plugin_insert;
3691 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3692 _port_inserts.insert (_port_inserts.begin(), port_insert);
3693 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3694 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3695 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3696 _sends.insert (_sends.begin(), send);
3698 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3702 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3708 Session::remove_processor (Processor* processor)
3711 PortInsert* port_insert;
3712 PluginInsert* plugin_insert;
3714 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3715 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3716 if (x != _port_inserts.end()) {
3717 insert_bitset[port_insert->bit_slot()] = false;
3718 _port_inserts.erase (x);
3720 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3721 _plugin_inserts.remove (plugin_insert);
3722 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3723 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3724 if (x != _sends.end()) {
3725 send_bitset[send->bit_slot()] = false;
3729 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3737 Session::available_capture_duration ()
3739 float sample_bytes_on_disk = 4.0; // keep gcc happy
3741 switch (Config->get_native_file_data_format()) {
3743 sample_bytes_on_disk = 4.0;
3747 sample_bytes_on_disk = 3.0;
3751 sample_bytes_on_disk = 2.0;
3755 /* impossible, but keep some gcc versions happy */
3756 fatal << string_compose (_("programming error: %1"),
3757 X_("illegal native file data format"))
3762 double scale = 4096.0 / sample_bytes_on_disk;
3764 if (_total_free_4k_blocks * scale > (double) max_frames) {
3768 return (nframes_t) floor (_total_free_4k_blocks * scale);
3772 Session::add_bundle (shared_ptr<Bundle> bundle)
3775 RCUWriter<BundleList> writer (_bundles);
3776 boost::shared_ptr<BundleList> b = writer.get_copy ();
3777 b->push_back (bundle);
3780 BundleAdded (bundle); /* EMIT SIGNAL */
3786 Session::remove_bundle (shared_ptr<Bundle> bundle)
3788 bool removed = false;
3791 RCUWriter<BundleList> writer (_bundles);
3792 boost::shared_ptr<BundleList> b = writer.get_copy ();
3793 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3795 if (i != b->end()) {
3802 BundleRemoved (bundle); /* EMIT SIGNAL */
3809 Session::bundle_by_name (string name) const
3811 boost::shared_ptr<BundleList> b = _bundles.reader ();
3813 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3814 if ((*i)->name() == name) {
3819 return boost::shared_ptr<Bundle> ();
3823 Session::tempo_map_changed (Change ignored)
3827 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3828 (*i)->update_after_tempo_map_change ();
3831 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3832 (*i)->update_after_tempo_map_change ();
3838 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3839 * the given count with the current block size.
3842 Session::ensure_buffers (ChanCount howmany)
3844 if (current_block_size == 0) {
3845 return; // too early? (is this ok?)
3848 // We need at least 2 MIDI scratch buffers to mix/merge
3849 if (howmany.n_midi() < 2) {
3850 howmany.set_midi(2);
3853 // FIXME: JACK needs to tell us maximum MIDI buffer size
3854 // Using nasty assumption (max # events == nframes) for now
3856 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3857 _mix_buffers->ensure_buffers(howmany, current_block_size);
3858 _silent_buffers->ensure_buffers(howmany, current_block_size);
3860 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3864 Session::next_insert_id ()
3866 /* this doesn't really loop forever. just think about it */
3869 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3870 if (!insert_bitset[n]) {
3871 insert_bitset[n] = true;
3877 /* none available, so resize and try again */
3879 insert_bitset.resize (insert_bitset.size() + 16, false);
3884 Session::next_send_id ()
3886 /* this doesn't really loop forever. just think about it */
3889 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3890 if (!send_bitset[n]) {
3891 send_bitset[n] = true;
3897 /* none available, so resize and try again */
3899 send_bitset.resize (send_bitset.size() + 16, false);
3904 Session::mark_send_id (uint32_t id)
3906 if (id >= send_bitset.size()) {
3907 send_bitset.resize (id+16, false);
3909 if (send_bitset[id]) {
3910 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3912 send_bitset[id] = true;
3916 Session::mark_insert_id (uint32_t id)
3918 if (id >= insert_bitset.size()) {
3919 insert_bitset.resize (id+16, false);
3921 if (insert_bitset[id]) {
3922 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3924 insert_bitset[id] = true;
3927 /* Named Selection management */
3930 Session::named_selection_by_name (string name)
3932 Glib::Mutex::Lock lm (named_selection_lock);
3933 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3934 if ((*i)->name == name) {
3942 Session::add_named_selection (NamedSelection* named_selection)
3945 Glib::Mutex::Lock lm (named_selection_lock);
3946 named_selections.insert (named_selections.begin(), named_selection);
3949 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3955 NamedSelectionAdded (); /* EMIT SIGNAL */
3959 Session::remove_named_selection (NamedSelection* named_selection)
3961 bool removed = false;
3964 Glib::Mutex::Lock lm (named_selection_lock);
3966 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3968 if (i != named_selections.end()) {
3970 named_selections.erase (i);
3977 NamedSelectionRemoved (); /* EMIT SIGNAL */
3982 Session::reset_native_file_format ()
3984 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3986 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3987 (*i)->reset_write_sources (false);
3992 Session::route_name_unique (string n) const
3994 shared_ptr<RouteList> r = routes.reader ();
3996 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3997 if ((*i)->name() == n) {
4006 Session::route_name_internal (string n) const
4008 if (auditioner && auditioner->name() == n) {
4012 if (_click_io && _click_io->name() == n) {
4020 Session::n_playlists () const
4022 Glib::Mutex::Lock lm (playlist_lock);
4023 return playlists.size();
4027 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4029 if (!force && howmany <= _npan_buffers) {
4033 if (_pan_automation_buffer) {
4035 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4036 delete [] _pan_automation_buffer[i];
4039 delete [] _pan_automation_buffer;
4042 _pan_automation_buffer = new pan_t*[howmany];
4044 for (uint32_t i = 0; i < howmany; ++i) {
4045 _pan_automation_buffer[i] = new pan_t[nframes];
4048 _npan_buffers = howmany;
4052 Session::freeze (InterThreadInfo& itt)
4054 shared_ptr<RouteList> r = routes.reader ();
4056 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4058 boost::shared_ptr<Track> t;
4060 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4061 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4071 boost::shared_ptr<Region>
4072 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4073 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4074 InterThreadInfo& itt, bool enable_processing)
4076 boost::shared_ptr<Region> result;
4077 boost::shared_ptr<Playlist> playlist;
4078 boost::shared_ptr<AudioFileSource> fsource;
4080 char buf[PATH_MAX+1];
4081 ChanCount nchans(track.audio_diskstream()->n_channels());
4083 nframes_t this_chunk;
4086 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4087 const string sound_dir = sdir.sound_path().to_string();
4088 nframes_t len = end - start;
4091 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4092 end, start) << endmsg;
4096 // any bigger than this seems to cause stack overflows in called functions
4097 const nframes_t chunk_size = (128 * 1024)/4;
4099 // block all process callback handling
4101 block_processing ();
4103 /* call tree *MUST* hold route_lock */
4105 if ((playlist = track.diskstream()->playlist()) == 0) {
4109 /* external redirects will be a problem */
4111 if (track.has_external_redirects()) {
4115 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4117 for (x = 0; x < 99999; ++x) {
4118 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4119 if (access (buf, F_OK) != 0) {
4125 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4130 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4131 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4134 catch (failed_constructor& err) {
4135 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4139 srcs.push_back (fsource);
4142 /* XXX need to flush all redirects */
4147 /* create a set of reasonably-sized buffers */
4148 buffers.ensure_buffers(nchans, chunk_size);
4149 buffers.set_count(nchans);
4151 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4152 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4154 afs->prepare_for_peakfile_writes ();
4157 while (to_do && !itt.cancel) {
4159 this_chunk = min (to_do, chunk_size);
4161 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4166 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4167 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4170 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4176 start += this_chunk;
4177 to_do -= this_chunk;
4179 itt.progress = (float) (1.0 - ((double) to_do / len));
4188 xnow = localtime (&now);
4190 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4191 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4194 afs->update_header (position, *xnow, now);
4195 afs->flush_header ();
4199 /* construct a region to represent the bounced material */
4201 result = RegionFactory::create (srcs, 0,
4202 srcs.front()->length(srcs.front()->timeline_position()),
4203 region_name_from_path (srcs.front()->name(), true));
4208 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4209 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4212 afs->mark_for_remove ();
4215 (*src)->drop_references ();
4219 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4220 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4223 afs->done_with_peakfile_writes ();
4227 unblock_processing ();
4233 Session::get_silent_buffers (ChanCount count)
4235 assert(_silent_buffers->available() >= count);
4236 _silent_buffers->set_count(count);
4238 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4239 for (size_t i= 0; i < count.get(*t); ++i) {
4240 _silent_buffers->get(*t, i).clear();
4244 return *_silent_buffers;
4248 Session::get_scratch_buffers (ChanCount count)
4250 if (count != ChanCount::ZERO) {
4251 assert(_scratch_buffers->available() >= count);
4252 _scratch_buffers->set_count(count);
4254 _scratch_buffers->set_count (_scratch_buffers->available());
4257 return *_scratch_buffers;
4261 Session::get_mix_buffers (ChanCount count)
4263 assert(_mix_buffers->available() >= count);
4264 _mix_buffers->set_count(count);
4265 return *_mix_buffers;
4269 Session::ntracks () const
4272 shared_ptr<RouteList> r = routes.reader ();
4274 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4275 if (boost::dynamic_pointer_cast<Track> (*i)) {
4284 Session::nbusses () const
4287 shared_ptr<RouteList> r = routes.reader ();
4289 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4290 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4299 Session::add_automation_list(AutomationList *al)
4301 automation_lists[al->id()] = al;
4305 Session::compute_initial_length ()
4307 return _engine.frame_rate() * 60 * 5;
4311 Session::sync_order_keys (const char* base)
4313 if (!Config->get_sync_all_route_ordering()) {
4314 /* leave order keys as they are */
4318 boost::shared_ptr<RouteList> r = routes.reader ();
4320 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4321 (*i)->sync_order_keys (base);
4324 Route::SyncOrderKeys (base); // EMIT SIGNAL