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/return.h"
76 #include "ardour/route_group.h"
77 #include "ardour/send.h"
78 #include "ardour/session.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_directory.h"
81 #include "ardour/session_metadata.h"
82 #include "ardour/slave.h"
83 #include "ardour/smf_source.h"
84 #include "ardour/source_factory.h"
85 #include "ardour/tape_file_matcher.h"
86 #include "ardour/tempo.h"
87 #include "ardour/utils.h"
92 using namespace ARDOUR;
94 using boost::shared_ptr;
96 bool Session::_disable_all_loaded_plugins = false;
98 sigc::signal<void,std::string> Session::Dialog;
99 sigc::signal<int> Session::AskAboutPendingState;
100 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
101 sigc::signal<void> Session::SendFeedback;
103 sigc::signal<void> Session::SMPTEOffsetChanged;
104 sigc::signal<void> Session::StartTimeChanged;
105 sigc::signal<void> Session::EndTimeChanged;
106 sigc::signal<void> Session::AutoBindingOn;
107 sigc::signal<void> Session::AutoBindingOff;
108 sigc::signal<void, std::string, std::string> Session::Exported;
110 Session::Session (AudioEngine &eng,
111 const string& fullpath,
112 const string& snapshot_name,
116 _target_transport_speed (0.0),
117 _requested_return_frame (-1),
118 _scratch_buffers(new BufferSet()),
119 _silent_buffers(new BufferSet()),
120 _mix_buffers(new BufferSet()),
122 _mmc_port (default_mmc_port),
123 _mtc_port (default_mtc_port),
124 _midi_port (default_midi_port),
125 _midi_clock_port (default_midi_clock_port),
126 _session_dir (new SessionDirectory(fullpath)),
127 pending_events (2048),
129 butler_mixdown_buffer (0),
130 butler_gain_buffer (0),
131 post_transport_work((PostTransportWork)0),
132 _send_smpte_update (false),
133 midi_thread (pthread_t (0)),
134 midi_requests (128), // the size of this should match the midi request pool size
135 diskstreams (new DiskstreamList),
136 routes (new RouteList),
137 _total_free_4k_blocks (0),
138 _bundles (new BundleList),
139 _bundle_xml_node (0),
142 click_emphasis_data (0),
144 _metadata (new SessionMetadata()),
145 _have_rec_enabled_diskstream (false)
150 if (!eng.connected()) {
151 throw failed_constructor();
154 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
156 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
157 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
159 first_stage_init (fullpath, snapshot_name);
161 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
164 if (create (new_session, mix_template, compute_initial_length())) {
166 throw failed_constructor ();
170 if (second_stage_init (new_session)) {
172 throw failed_constructor ();
175 store_recent_sessions(_name, _path);
177 bool was_dirty = dirty();
179 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
181 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
182 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
185 DirtyChanged (); /* EMIT SIGNAL */
189 Session::Session (AudioEngine &eng,
191 string snapshot_name,
192 AutoConnectOption input_ac,
193 AutoConnectOption output_ac,
194 uint32_t control_out_channels,
195 uint32_t master_out_channels,
196 uint32_t requested_physical_in,
197 uint32_t requested_physical_out,
198 nframes_t initial_length)
201 _target_transport_speed (0.0),
202 _requested_return_frame (-1),
203 _scratch_buffers(new BufferSet()),
204 _silent_buffers(new BufferSet()),
205 _mix_buffers(new BufferSet()),
207 _mmc_port (default_mmc_port),
208 _mtc_port (default_mtc_port),
209 _midi_port (default_midi_port),
210 _midi_clock_port (default_midi_clock_port),
211 _session_dir ( new SessionDirectory(fullpath)),
212 pending_events (2048),
214 butler_mixdown_buffer (0),
215 butler_gain_buffer (0),
216 post_transport_work((PostTransportWork)0),
217 _send_smpte_update (false),
218 midi_thread (pthread_t (0)),
220 diskstreams (new DiskstreamList),
221 routes (new RouteList),
222 _total_free_4k_blocks (0),
223 _bundles (new BundleList),
224 _bundle_xml_node (0),
225 _click_io ((IO *) 0),
227 click_emphasis_data (0),
229 _metadata (new SessionMetadata()),
230 _have_rec_enabled_diskstream (false)
234 if (!eng.connected()) {
235 throw failed_constructor();
238 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
240 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
241 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
243 if (n_physical_inputs) {
244 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
247 if (n_physical_outputs) {
248 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
251 first_stage_init (fullpath, snapshot_name);
253 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
256 if (create (new_session, string(), initial_length)) {
258 throw failed_constructor ();
263 /* set up Master Out and Control Out if necessary */
268 if (control_out_channels) {
269 ChanCount count(DataType::AUDIO, control_out_channels);
270 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
271 r->input()->ensure_io (count, false, this);
272 r->output()->ensure_io (count, false, this);
273 r->set_remote_control_id (control_id++);
278 if (master_out_channels) {
279 ChanCount count(DataType::AUDIO, master_out_channels);
280 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
281 r->input()->ensure_io (count, false, this);
282 r->output()->ensure_io (count, false, this);
283 r->set_remote_control_id (control_id);
287 /* prohibit auto-connect to master, because there isn't one */
288 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
292 add_routes (rl, false);
297 if (no_auto_connect()) {
298 input_ac = AutoConnectOption (0);
299 output_ac = AutoConnectOption (0);
302 Config->set_input_auto_connect (input_ac);
303 Config->set_output_auto_connect (output_ac);
305 if (second_stage_init (new_session)) {
307 throw failed_constructor ();
310 store_recent_sessions (_name, _path);
312 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
314 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
325 /* if we got to here, leaving pending capture state around
329 remove_pending_capture_state ();
331 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
333 _engine.remove_session ();
335 GoingAway (); /* EMIT SIGNAL */
341 /* clear history so that no references to objects are held any more */
345 /* clear state tree so that no references to objects are held any more */
349 terminate_butler_thread ();
350 //terminate_midi_thread ();
352 if (click_data != default_click) {
353 delete [] click_data;
356 if (click_emphasis_data != default_click_emphasis) {
357 delete [] click_emphasis_data;
362 delete _scratch_buffers;
363 delete _silent_buffers;
366 AudioDiskstream::free_working_buffers();
368 Route::SyncOrderKeys.clear();
370 #undef TRACK_DESTRUCTION
371 #ifdef TRACK_DESTRUCTION
372 cerr << "delete named selections\n";
373 #endif /* TRACK_DESTRUCTION */
374 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
375 NamedSelectionList::iterator tmp;
384 #ifdef TRACK_DESTRUCTION
385 cerr << "delete playlists\n";
386 #endif /* TRACK_DESTRUCTION */
387 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
388 PlaylistList::iterator tmp;
393 (*i)->drop_references ();
398 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
399 PlaylistList::iterator tmp;
404 (*i)->drop_references ();
410 unused_playlists.clear ();
412 #ifdef TRACK_DESTRUCTION
413 cerr << "delete regions\n";
414 #endif /* TRACK_DESTRUCTION */
416 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
417 RegionList::iterator tmp;
422 i->second->drop_references ();
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete routes\n";
431 #endif /* TRACK_DESTRUCTION */
433 RCUWriter<RouteList> writer (routes);
434 boost::shared_ptr<RouteList> r = writer.get_copy ();
435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
436 (*i)->drop_references ();
439 /* writer goes out of scope and updates master */
444 #ifdef TRACK_DESTRUCTION
445 cerr << "delete diskstreams\n";
446 #endif /* TRACK_DESTRUCTION */
448 RCUWriter<DiskstreamList> dwriter (diskstreams);
449 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
450 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
451 (*i)->drop_references ();
455 diskstreams.flush ();
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete audio sources\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
461 SourceMap::iterator tmp;
466 i->second->drop_references ();
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete mix groups\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
476 list<RouteGroup*>::iterator tmp;
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete edit groups\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
490 list<RouteGroup*>::iterator tmp;
500 delete [] butler_mixdown_buffer;
501 delete [] butler_gain_buffer;
503 Crossfade::set_buffer_size (0);
509 Session::set_worst_io_latencies ()
511 _worst_output_latency = 0;
512 _worst_input_latency = 0;
514 if (!_engine.connected()) {
518 boost::shared_ptr<RouteList> r = routes.reader ();
520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
521 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
522 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
527 Session::when_engine_running ()
529 string first_physical_output;
531 BootMessage (_("Set block size and sample rate"));
533 set_block_size (_engine.frames_per_cycle());
534 set_frame_rate (_engine.frame_rate());
536 BootMessage (_("Using configuration"));
538 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
540 /* every time we reconnect, recompute worst case output latencies */
542 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
544 if (synced_to_jack()) {
545 _engine.transport_stop ();
548 if (config.get_jack_time_master()) {
549 _engine.transport_locate (_transport_frame);
557 _click_io.reset (new ClickIO (*this, "click"));
559 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
561 /* existing state for Click */
563 if (_click_io->set_state (*child->children().front()) == 0) {
565 _clicking = Config->get_clicking ();
569 error << _("could not setup Click I/O") << endmsg;
575 /* default state for Click: dual-mono to first 2 physical outputs */
577 for (int physport = 0; physport < 2; ++physport) {
578 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
580 if (physical_output.length()) {
581 if (_click_io->add_port (physical_output, this)) {
582 // relax, even though its an error
587 if (_click_io->n_ports () > ChanCount::ZERO) {
588 _clicking = Config->get_clicking ();
593 catch (failed_constructor& err) {
594 error << _("cannot setup Click I/O") << endmsg;
597 BootMessage (_("Compute I/O Latencies"));
599 set_worst_io_latencies ();
602 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
605 BootMessage (_("Set up standard connections"));
607 /* Create a set of Bundle objects that map
608 to the physical I/O currently available. We create both
609 mono and stereo bundles, so that the common cases of mono
610 and stereo tracks get bundles to put in their mixer strip
611 in / out menus. There may be a nicer way of achieving that;
612 it doesn't really scale that well to higher channel counts
615 /* mono output bundles */
617 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
619 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
621 shared_ptr<Bundle> c (new Bundle (buf, true));
622 c->add_channel (_("mono"));
623 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
628 /* stereo output bundles */
630 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
631 if (np + 1 < n_physical_outputs) {
633 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
634 shared_ptr<Bundle> c (new Bundle (buf, true));
635 c->add_channel (_("L"));
636 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
637 c->add_channel (_("R"));
638 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
644 /* mono input bundles */
646 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
648 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
650 shared_ptr<Bundle> c (new Bundle (buf, false));
651 c->add_channel (_("mono"));
652 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
657 /* stereo input bundles */
659 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
660 if (np + 1 < n_physical_inputs) {
662 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
664 shared_ptr<Bundle> c (new Bundle (buf, false));
665 c->add_channel (_("L"));
666 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
667 c->add_channel (_("R"));
668 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
674 if (Config->get_auto_connect_standard_busses() && !no_auto_connect()) {
678 /* if requested auto-connect the outputs to the first N physical ports.
681 uint32_t limit = _master_out->n_outputs().n_total();
683 for (uint32_t n = 0; n < limit; ++n) {
684 Port* p = _master_out->output()->nth (n);
685 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
687 if (!connect_to.empty()) {
688 if (_master_out->output()->connect (p, connect_to, this)) {
689 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
699 uint32_t limit = _control_out->n_outputs().n_total();
701 for (uint32_t n = 0; n < limit; ++n) {
702 Port* p = _control_out->output()->nth (n);
703 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
705 if (!connect_to.empty()) {
706 if (_control_out->output()->connect (p, connect_to, this)) {
707 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
716 BootMessage (_("Setup signal flow and plugins"));
720 /* catch up on send+insert cnts */
722 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
724 /* hook us up to the engine */
726 BootMessage (_("Connect to engine"));
728 _engine.set_session (this);
732 Session::hookup_io ()
734 /* stop graph reordering notifications from
735 causing resorts, etc.
738 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
743 /* we delay creating the auditioner till now because
744 it makes its own connections to ports.
745 the engine has to be running for this to work.
749 auditioner.reset (new Auditioner (*this));
752 catch (failed_constructor& err) {
753 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
757 /* load bundles, which we may have postponed earlier on */
758 if (_bundle_xml_node) {
759 load_bundles (*_bundle_xml_node);
760 delete _bundle_xml_node;
763 /* Tell all IO objects to connect themselves together */
765 IO::enable_connecting ();
767 /* Now reset all panners */
769 Delivery::reset_panners ();
771 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
775 boost::shared_ptr<RouteList> r = routes.reader ();
777 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
779 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
782 t->listen_via (_control_out, X_("listen"));
787 /* Anyone who cares about input state, wake up and do something */
789 IOConnectionsComplete (); /* EMIT SIGNAL */
791 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
793 /* now handle the whole enchilada as if it was one
799 /* update mixer solo state */
805 Session::playlist_length_changed ()
807 /* we can't just increase end_location->end() if pl->get_maximum_extent()
808 if larger. if the playlist used to be the longest playlist,
809 and its now shorter, we have to decrease end_location->end(). hence,
810 we have to iterate over all diskstreams and check the
811 playlists currently in use.
817 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
819 boost::shared_ptr<Playlist> playlist;
821 if ((playlist = dstream->playlist()) != 0) {
822 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
825 /* see comment in playlist_length_changed () */
830 Session::record_enabling_legal () const
832 /* this used to be in here, but survey says.... we don't need to restrict it */
833 // if (record_status() == Recording) {
837 if (Config->get_all_safe()) {
844 Session::reset_input_monitor_state ()
846 if (transport_rolling()) {
848 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
850 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
851 if ((*i)->record_enabled ()) {
852 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
853 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
857 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
859 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
860 if ((*i)->record_enabled ()) {
861 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
862 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
869 Session::auto_punch_start_changed (Location* location)
871 replace_event (Event::PunchIn, location->start());
873 if (get_record_enabled() && config.get_punch_in()) {
874 /* capture start has been changed, so save new pending state */
875 save_state ("", true);
880 Session::auto_punch_end_changed (Location* location)
882 nframes_t when_to_stop = location->end();
883 // when_to_stop += _worst_output_latency + _worst_input_latency;
884 replace_event (Event::PunchOut, when_to_stop);
888 Session::auto_punch_changed (Location* location)
890 nframes_t when_to_stop = location->end();
892 replace_event (Event::PunchIn, location->start());
893 //when_to_stop += _worst_output_latency + _worst_input_latency;
894 replace_event (Event::PunchOut, when_to_stop);
898 Session::auto_loop_changed (Location* location)
900 replace_event (Event::AutoLoop, location->end(), location->start());
902 if (transport_rolling() && play_loop) {
904 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
906 if (_transport_frame > location->end()) {
907 // relocate to beginning of loop
908 clear_events (Event::LocateRoll);
910 request_locate (location->start(), true);
913 else if (Config->get_seamless_loop() && !loop_changing) {
915 // schedule a locate-roll to refill the diskstreams at the
917 loop_changing = true;
919 if (location->end() > last_loopend) {
920 clear_events (Event::LocateRoll);
921 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
928 last_loopend = location->end();
932 Session::set_auto_punch_location (Location* location)
936 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
937 auto_punch_start_changed_connection.disconnect();
938 auto_punch_end_changed_connection.disconnect();
939 auto_punch_changed_connection.disconnect();
940 existing->set_auto_punch (false, this);
941 remove_event (existing->start(), Event::PunchIn);
942 clear_events (Event::PunchOut);
943 auto_punch_location_changed (0);
952 if (location->end() <= location->start()) {
953 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
957 auto_punch_start_changed_connection.disconnect();
958 auto_punch_end_changed_connection.disconnect();
959 auto_punch_changed_connection.disconnect();
961 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
962 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
963 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
965 location->set_auto_punch (true, this);
968 auto_punch_changed (location);
970 auto_punch_location_changed (location);
974 Session::set_auto_loop_location (Location* location)
978 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
979 auto_loop_start_changed_connection.disconnect();
980 auto_loop_end_changed_connection.disconnect();
981 auto_loop_changed_connection.disconnect();
982 existing->set_auto_loop (false, this);
983 remove_event (existing->end(), Event::AutoLoop);
984 auto_loop_location_changed (0);
993 if (location->end() <= location->start()) {
994 error << _("Session: you can't use a mark for auto loop") << endmsg;
998 last_loopend = location->end();
1000 auto_loop_start_changed_connection.disconnect();
1001 auto_loop_end_changed_connection.disconnect();
1002 auto_loop_changed_connection.disconnect();
1004 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1005 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1006 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1008 location->set_auto_loop (true, this);
1010 /* take care of our stuff first */
1012 auto_loop_changed (location);
1014 /* now tell everyone else */
1016 auto_loop_location_changed (location);
1020 Session::locations_added (Location* ignored)
1026 Session::locations_changed ()
1028 _locations.apply (*this, &Session::handle_locations_changed);
1032 Session::handle_locations_changed (Locations::LocationList& locations)
1034 Locations::LocationList::iterator i;
1036 bool set_loop = false;
1037 bool set_punch = false;
1039 for (i = locations.begin(); i != locations.end(); ++i) {
1043 if (location->is_auto_punch()) {
1044 set_auto_punch_location (location);
1047 if (location->is_auto_loop()) {
1048 set_auto_loop_location (location);
1052 if (location->is_start()) {
1053 start_location = location;
1055 if (location->is_end()) {
1056 end_location = location;
1061 set_auto_loop_location (0);
1064 set_auto_punch_location (0);
1071 Session::enable_record ()
1073 /* XXX really atomic compare+swap here */
1074 if (g_atomic_int_get (&_record_status) != Recording) {
1075 g_atomic_int_set (&_record_status, Recording);
1076 _last_record_location = _transport_frame;
1077 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1079 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1080 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1081 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1082 if ((*i)->record_enabled ()) {
1083 (*i)->monitor_input (true);
1088 RecordStateChanged ();
1093 Session::disable_record (bool rt_context, bool force)
1097 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1099 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1100 g_atomic_int_set (&_record_status, Disabled);
1102 if (rs == Recording) {
1103 g_atomic_int_set (&_record_status, Enabled);
1107 // FIXME: timestamp correct? [DR]
1108 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1109 // does this /need/ to be sent in all cases?
1111 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1113 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1114 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1116 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1117 if ((*i)->record_enabled ()) {
1118 (*i)->monitor_input (false);
1123 RecordStateChanged (); /* emit signal */
1126 remove_pending_capture_state ();
1132 Session::step_back_from_record ()
1134 /* XXX really atomic compare+swap here */
1135 if (g_atomic_int_get (&_record_status) == Recording) {
1136 g_atomic_int_set (&_record_status, Enabled);
1138 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1139 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1141 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1142 if ((*i)->record_enabled ()) {
1143 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1144 (*i)->monitor_input (false);
1152 Session::maybe_enable_record ()
1154 g_atomic_int_set (&_record_status, Enabled);
1156 /* this function is currently called from somewhere other than an RT thread.
1157 this save_state() call therefore doesn't impact anything.
1160 save_state ("", true);
1162 if (_transport_speed) {
1163 if (!config.get_punch_in()) {
1167 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1168 RecordStateChanged (); /* EMIT SIGNAL */
1175 Session::audible_frame () const
1181 /* the first of these two possible settings for "offset"
1182 mean that the audible frame is stationary until
1183 audio emerges from the latency compensation
1186 the second means that the audible frame is stationary
1187 until audio would emerge from a physical port
1188 in the absence of any plugin latency compensation
1191 offset = _worst_output_latency;
1193 if (offset > current_block_size) {
1194 offset -= current_block_size;
1196 /* XXX is this correct? if we have no external
1197 physical connections and everything is internal
1198 then surely this is zero? still, how
1199 likely is that anyway?
1201 offset = current_block_size;
1204 if (synced_to_jack()) {
1205 tf = _engine.transport_frame();
1207 tf = _transport_frame;
1212 if (!non_realtime_work_pending()) {
1216 /* check to see if we have passed the first guaranteed
1217 audible frame past our last start position. if not,
1218 return that last start point because in terms
1219 of audible frames, we have not moved yet.
1222 if (_transport_speed > 0.0f) {
1224 if (!play_loop || !have_looped) {
1225 if (tf < _last_roll_location + offset) {
1226 return _last_roll_location;
1234 } else if (_transport_speed < 0.0f) {
1236 /* XXX wot? no backward looping? */
1238 if (tf > _last_roll_location - offset) {
1239 return _last_roll_location;
1251 Session::set_frame_rate (nframes_t frames_per_second)
1253 /** \fn void Session::set_frame_size(nframes_t)
1254 the AudioEngine object that calls this guarantees
1255 that it will not be called while we are also in
1256 ::process(). Its fine to do things that block
1260 _base_frame_rate = frames_per_second;
1264 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1268 // XXX we need some equivalent to this, somehow
1269 // SndFileSource::setup_standard_crossfades (frames_per_second);
1273 /* XXX need to reset/reinstantiate all LADSPA plugins */
1277 Session::set_block_size (nframes_t nframes)
1279 /* the AudioEngine guarantees
1280 that it will not be called while we are also in
1281 ::process(). It is therefore fine to do things that block
1286 current_block_size = nframes;
1288 ensure_buffers(_scratch_buffers->available());
1290 delete [] _gain_automation_buffer;
1291 _gain_automation_buffer = new gain_t[nframes];
1293 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1295 boost::shared_ptr<RouteList> r = routes.reader ();
1297 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1298 (*i)->set_block_size (nframes);
1301 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1303 (*i)->set_block_size (nframes);
1306 set_worst_io_latencies ();
1311 Session::set_default_fade (float steepness, float fade_msecs)
1314 nframes_t fade_frames;
1316 /* Don't allow fade of less 1 frame */
1318 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1325 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1329 default_fade_msecs = fade_msecs;
1330 default_fade_steepness = steepness;
1333 // jlc, WTF is this!
1334 Glib::RWLock::ReaderLock lm (route_lock);
1335 AudioRegion::set_default_fade (steepness, fade_frames);
1340 /* XXX have to do this at some point */
1341 /* foreach region using default fade, reset, then
1342 refill_all_diskstream_buffers ();
1347 struct RouteSorter {
1348 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1349 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1351 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1354 if (r1->fed_by.empty()) {
1355 if (r2->fed_by.empty()) {
1356 /* no ardour-based connections inbound to either route. just use signal order */
1357 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1359 /* r2 has connections, r1 does not; run r1 early */
1363 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1370 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1372 shared_ptr<Route> r2;
1374 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1375 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1379 /* make a copy of the existing list of routes that feed r1 */
1381 set<shared_ptr<Route> > existing = r1->fed_by;
1383 /* for each route that feeds r1, recurse, marking it as feeding
1387 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1390 /* r2 is a route that feeds r1 which somehow feeds base. mark
1391 base as being fed by r2
1394 rbase->fed_by.insert (r2);
1398 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1402 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1406 /* now recurse, so that we can mark base as being fed by
1407 all routes that feed r2
1410 trace_terminal (r2, rbase);
1417 Session::resort_routes ()
1419 /* don't do anything here with signals emitted
1420 by Routes while we are being destroyed.
1423 if (_state_of_the_state & Deletion) {
1430 RCUWriter<RouteList> writer (routes);
1431 shared_ptr<RouteList> r = writer.get_copy ();
1432 resort_routes_using (r);
1433 /* writer goes out of scope and forces update */
1438 Session::resort_routes_using (shared_ptr<RouteList> r)
1440 RouteList::iterator i, j;
1442 for (i = r->begin(); i != r->end(); ++i) {
1444 (*i)->fed_by.clear ();
1446 for (j = r->begin(); j != r->end(); ++j) {
1448 /* although routes can feed themselves, it will
1449 cause an endless recursive descent if we
1450 detect it. so don't bother checking for
1458 if ((*j)->feeds (*i)) {
1459 (*i)->fed_by.insert (*j);
1464 for (i = r->begin(); i != r->end(); ++i) {
1465 trace_terminal (*i, *i);
1472 cerr << "finished route resort\n";
1474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1475 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1482 list<boost::shared_ptr<MidiTrack> >
1483 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1485 char track_name[32];
1486 uint32_t track_id = 0;
1489 RouteList new_routes;
1490 list<boost::shared_ptr<MidiTrack> > ret;
1491 //uint32_t control_id;
1493 // FIXME: need physical I/O and autoconnect stuff for MIDI
1495 /* count existing midi tracks */
1498 shared_ptr<RouteList> r = routes.reader ();
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1502 if (!(*i)->is_hidden()) {
1504 //channels_used += (*i)->n_inputs().n_midi();
1510 vector<string> physinputs;
1511 vector<string> physoutputs;
1513 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1514 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1516 // control_id = ntracks() + nbusses();
1520 /* check for duplicate route names, since we might have pre-existing
1521 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1522 save, close,restart,add new route - first named route is now
1530 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1532 if (route_by_name (track_name) == 0) {
1536 } while (track_id < (UINT_MAX-1));
1538 shared_ptr<MidiTrack> track;
1541 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1543 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1544 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1549 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1550 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1556 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1560 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1561 port = physinputs[(channels_used+x)%nphysical_in];
1564 if (port.length() && track->connect_input (track->input (x), port, this)) {
1570 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1574 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1575 port = physoutputs[(channels_used+x)%nphysical_out];
1576 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1578 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1582 if (port.length() && track->connect_output (track->output (x), port, this)) {
1587 channels_used += track->n_inputs ().n_midi();
1591 track->midi_diskstream()->non_realtime_input_change();
1593 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1594 //track->set_remote_control_id (control_id);
1596 new_routes.push_back (track);
1597 ret.push_back (track);
1600 catch (failed_constructor &err) {
1601 error << _("Session: could not create new midi track.") << endmsg;
1604 /* we need to get rid of this, since the track failed to be created */
1605 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1608 RCUWriter<DiskstreamList> writer (diskstreams);
1609 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1610 ds->remove (track->midi_diskstream());
1617 catch (AudioEngine::PortRegistrationFailure& pfe) {
1619 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;
1622 /* we need to get rid of this, since the track failed to be created */
1623 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1626 RCUWriter<DiskstreamList> writer (diskstreams);
1627 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1628 ds->remove (track->midi_diskstream());
1639 if (!new_routes.empty()) {
1640 add_routes (new_routes, false);
1641 save_state (_current_snapshot_name);
1647 list<boost::shared_ptr<AudioTrack> >
1648 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1650 char track_name[32];
1651 uint32_t track_id = 0;
1653 uint32_t channels_used = 0;
1655 RouteList new_routes;
1656 list<boost::shared_ptr<AudioTrack> > ret;
1657 uint32_t control_id;
1659 /* count existing audio tracks */
1662 shared_ptr<RouteList> r = routes.reader ();
1664 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1665 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1666 if (!(*i)->is_hidden()) {
1668 channels_used += (*i)->n_inputs().n_audio();
1674 vector<string> physinputs;
1675 vector<string> physoutputs;
1677 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1678 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1680 control_id = ntracks() + nbusses() + 1;
1684 /* check for duplicate route names, since we might have pre-existing
1685 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1686 save, close,restart,add new route - first named route is now
1694 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1696 if (route_by_name (track_name) == 0) {
1700 } while (track_id < (UINT_MAX-1));
1702 shared_ptr<AudioTrack> track;
1705 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1707 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1708 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1709 input_channels, output_channels)
1714 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1715 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1716 input_channels, output_channels)
1721 if (!physinputs.empty()) {
1722 uint32_t nphysical_in = physinputs.size();
1724 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1728 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1729 port = physinputs[(channels_used+x)%nphysical_in];
1732 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1738 if (!physoutputs.empty()) {
1739 uint32_t nphysical_out = physoutputs.size();
1741 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1744 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1745 port = physoutputs[(channels_used+x)%nphysical_out];
1746 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1747 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1748 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1752 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1758 channels_used += track->n_inputs ().n_audio();
1760 track->audio_diskstream()->non_realtime_input_change();
1762 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1763 track->set_remote_control_id (control_id);
1766 new_routes.push_back (track);
1767 ret.push_back (track);
1770 catch (failed_constructor &err) {
1771 error << _("Session: could not create new audio track.") << endmsg;
1774 /* we need to get rid of this, since the track failed to be created */
1775 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1778 RCUWriter<DiskstreamList> writer (diskstreams);
1779 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1780 ds->remove (track->audio_diskstream());
1787 catch (AudioEngine::PortRegistrationFailure& pfe) {
1789 error << pfe.what() << endmsg;
1792 /* we need to get rid of this, since the track failed to be created */
1793 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1796 RCUWriter<DiskstreamList> writer (diskstreams);
1797 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1798 ds->remove (track->audio_diskstream());
1809 if (!new_routes.empty()) {
1810 add_routes (new_routes, true);
1817 Session::set_remote_control_ids ()
1819 RemoteModel m = Config->get_remote_model();
1821 shared_ptr<RouteList> r = routes.reader ();
1823 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1824 if ( MixerOrdered == m) {
1825 long order = (*i)->order_key(N_("signal"));
1826 (*i)->set_remote_control_id( order+1 );
1827 } else if ( EditorOrdered == m) {
1828 long order = (*i)->order_key(N_("editor"));
1829 (*i)->set_remote_control_id( order+1 );
1830 } else if ( UserOrdered == m) {
1831 //do nothing ... only changes to remote id's are initiated by user
1838 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1841 uint32_t bus_id = 1;
1843 uint32_t channels_used = 0;
1846 uint32_t control_id;
1848 /* count existing audio busses */
1851 shared_ptr<RouteList> r = routes.reader ();
1853 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1854 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1856 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1859 channels_used += (*i)->n_inputs().n_audio();
1865 vector<string> physinputs;
1866 vector<string> physoutputs;
1868 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1869 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1871 n_physical_audio_outputs = physoutputs.size();
1872 n_physical_audio_inputs = physinputs.size();
1874 control_id = ntracks() + nbusses() + 1;
1879 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1883 if (route_by_name (bus_name) == 0) {
1887 } while (bus_id < (UINT_MAX-1));
1890 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1892 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1893 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1894 input_channels, output_channels)
1900 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1901 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1902 input_channels, output_channels)
1907 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1910 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1911 port = physinputs[((n+x)%n_physical_audio_inputs)];
1914 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1919 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1922 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1923 port = physoutputs[((n+x)%n_physical_outputs)];
1924 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1926 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1930 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1935 channels_used += bus->n_inputs ().n_audio();
1937 bus->set_remote_control_id (control_id);
1940 ret.push_back (bus);
1944 catch (failed_constructor &err) {
1945 error << _("Session: could not create new audio route.") << endmsg;
1949 catch (AudioEngine::PortRegistrationFailure& pfe) {
1950 error << pfe.what() << endmsg;
1960 add_routes (ret, true);
1968 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1972 uint32_t control_id;
1975 if (!tree.read (template_path.c_str())) {
1979 XMLNode* node = tree.root();
1981 control_id = ntracks() + nbusses() + 1;
1985 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1987 std::string node_name = IO::name_from_state (*node_copy.children().front());
1989 if (route_by_name (node_name) != 0) {
1991 /* generate a new name by adding a number to the end of the template name */
1993 uint32_t number = 1;
1996 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2000 if (route_by_name (name) == 0) {
2004 } while (number < UINT_MAX);
2006 if (number == UINT_MAX) {
2007 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2011 IO::set_name_in_state (*node_copy.children().front(), name);
2014 Track::zero_diskstream_id_in_xml (node_copy);
2017 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2020 error << _("Session: cannot create track/bus from template description") << endmsg;
2024 if (boost::dynamic_pointer_cast<Track>(route)) {
2025 /* force input/output change signals so that the new diskstream
2026 picks up the configuration of the route. During session
2027 loading this normally happens in a different way.
2029 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2030 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2033 route->set_remote_control_id (control_id);
2036 ret.push_back (route);
2039 catch (failed_constructor &err) {
2040 error << _("Session: could not create new route from template") << endmsg;
2044 catch (AudioEngine::PortRegistrationFailure& pfe) {
2045 error << pfe.what() << endmsg;
2054 add_routes (ret, true);
2061 Session::add_routes (RouteList& new_routes, bool save)
2064 RCUWriter<RouteList> writer (routes);
2065 shared_ptr<RouteList> r = writer.get_copy ();
2066 r->insert (r->end(), new_routes.begin(), new_routes.end());
2068 if (!_control_out && IO::connecting_legal) {
2069 resort_routes_using (r);
2073 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2075 boost::weak_ptr<Route> wpr (*x);
2077 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2078 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2079 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2080 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2081 (*x)->edit_group_changed.connect (hide (mem_fun (*this, &Session::route_edit_group_changed)));
2083 if ((*x)->is_master()) {
2087 if ((*x)->is_control()) {
2088 _control_out = (*x);
2092 if (_control_out && IO::connecting_legal) {
2094 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2095 (*x)->listen_via (_control_out, "control");
2104 save_state (_current_snapshot_name);
2107 RouteAdded (new_routes); /* EMIT SIGNAL */
2111 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2113 /* need to do this in case we're rolling at the time, to prevent false underruns */
2114 dstream->do_refill_with_alloc ();
2116 dstream->set_block_size (current_block_size);
2119 RCUWriter<DiskstreamList> writer (diskstreams);
2120 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2121 ds->push_back (dstream);
2122 /* writer goes out of scope, copies ds back to main */
2125 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2126 /* this will connect to future changes, and check the current length */
2127 diskstream_playlist_changed (dstream);
2129 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2131 dstream->prepare ();
2136 Session::remove_route (shared_ptr<Route> route)
2139 RCUWriter<RouteList> writer (routes);
2140 shared_ptr<RouteList> rs = writer.get_copy ();
2144 /* deleting the master out seems like a dumb
2145 idea, but its more of a UI policy issue
2149 if (route == _master_out) {
2150 _master_out = shared_ptr<Route> ();
2153 if (route == _control_out) {
2155 /* cancel control outs for all routes */
2157 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2158 (*r)->drop_listen (_control_out);
2161 _control_out.reset ();
2164 update_route_solo_state ();
2166 /* writer goes out of scope, forces route list update */
2169 boost::shared_ptr<Track> t;
2170 boost::shared_ptr<Diskstream> ds;
2172 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2173 ds = t->diskstream();
2179 RCUWriter<DiskstreamList> dsl (diskstreams);
2180 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2185 find_current_end ();
2187 // We need to disconnect the routes inputs and outputs
2189 route->input()->disconnect (0);
2190 route->output()->disconnect (0);
2192 update_latency_compensation (false, false);
2195 /* get rid of it from the dead wood collection in the route list manager */
2197 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2201 /* try to cause everyone to drop their references */
2203 route->drop_references ();
2205 sync_order_keys (N_("session"));
2207 /* save the new state of the world */
2209 if (save_state (_current_snapshot_name)) {
2210 save_history (_current_snapshot_name);
2215 Session::route_mute_changed (void* src)
2221 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2223 if (solo_update_disabled) {
2228 boost::shared_ptr<Route> route = wpr.lock ();
2231 /* should not happen */
2232 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2236 shared_ptr<RouteList> r = routes.reader ();
2239 if (route->soloed()) {
2245 solo_update_disabled = true;
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 if ((*i)->feeds (route)) {
2250 (*i)->mod_solo_level (delta);
2254 /* make sure master is never muted by solo */
2256 if (_master_out->solo_level() == 0) {
2257 _master_out->mod_solo_level (1);
2260 /* ditto for control outs make sure master is never muted by solo */
2262 if (_control_out && _control_out->solo_level() == 0) {
2263 _control_out->mod_solo_level (1);
2266 solo_update_disabled = false;
2267 update_route_solo_state (r);
2268 SoloChanged (); /* EMIT SIGNAL */
2273 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2275 /* now figure out if anything that matters is soloed */
2277 bool something_soloed = false;
2280 r = routes.reader();
2283 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2284 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2285 something_soloed = true;
2290 if (something_soloed != _non_soloed_outs_muted) {
2291 _non_soloed_outs_muted = something_soloed;
2292 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2297 Session::catch_up_on_solo ()
2299 /* this is called after set_state() to catch the full solo
2300 state, which can't be correctly determined on a per-route
2301 basis, but needs the global overview that only the session
2304 update_route_solo_state();
2308 Session::catch_up_on_solo_mute_override ()
2310 if (Config->get_solo_model() != SoloInPlace) {
2314 /* this is called whenever the param solo-mute-override is
2317 shared_ptr<RouteList> r = routes.reader ();
2319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2320 // (*i)->catch_up_on_solo_mute_override ();
2325 Session::route_by_name (string name)
2327 shared_ptr<RouteList> r = routes.reader ();
2329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2330 if ((*i)->name() == name) {
2335 return shared_ptr<Route> ((Route*) 0);
2339 Session::route_by_id (PBD::ID id)
2341 shared_ptr<RouteList> r = routes.reader ();
2343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2344 if ((*i)->id() == id) {
2349 return shared_ptr<Route> ((Route*) 0);
2353 Session::route_by_remote_id (uint32_t id)
2355 shared_ptr<RouteList> r = routes.reader ();
2357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358 if ((*i)->remote_control_id() == id) {
2363 return shared_ptr<Route> ((Route*) 0);
2367 Session::find_current_end ()
2369 if (_state_of_the_state & Loading) {
2373 nframes_t max = get_maximum_extent ();
2375 if (max > end_location->end()) {
2376 end_location->set_end (max);
2378 DurationChanged(); /* EMIT SIGNAL */
2383 Session::get_maximum_extent () const
2388 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2390 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2391 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2393 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2394 if ((me = pl->get_maximum_extent()) > max) {
2402 boost::shared_ptr<Diskstream>
2403 Session::diskstream_by_name (string name)
2405 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2407 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2408 if ((*i)->name() == name) {
2413 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2416 boost::shared_ptr<Diskstream>
2417 Session::diskstream_by_id (const PBD::ID& id)
2419 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2421 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2422 if ((*i)->id() == id) {
2427 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2430 /* Region management */
2433 Session::new_region_name (string old)
2435 string::size_type last_period;
2437 string::size_type len = old.length() + 64;
2440 if ((last_period = old.find_last_of ('.')) == string::npos) {
2442 /* no period present - add one explicitly */
2445 last_period = old.length() - 1;
2450 number = atoi (old.substr (last_period+1).c_str());
2454 while (number < (UINT_MAX-1)) {
2456 RegionList::const_iterator i;
2461 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2464 for (i = regions.begin(); i != regions.end(); ++i) {
2465 if (i->second->name() == sbuf) {
2470 if (i == regions.end()) {
2475 if (number != (UINT_MAX-1)) {
2479 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2484 Session::region_name (string& result, string base, bool newlevel)
2489 if (base.find("/") != string::npos) {
2490 base = base.substr(base.find_last_of("/") + 1);
2495 Glib::Mutex::Lock lm (region_lock);
2497 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2506 string::size_type pos;
2508 pos = base.find_last_of ('.');
2510 /* pos may be npos, but then we just use entire base */
2512 subbase = base.substr (0, pos);
2517 Glib::Mutex::Lock lm (region_lock);
2519 map<string,uint32_t>::iterator x;
2523 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2525 region_name_map[subbase] = 1;
2528 snprintf (buf, sizeof (buf), ".%d", x->second);
2539 Session::add_region (boost::shared_ptr<Region> region)
2541 vector<boost::shared_ptr<Region> > v;
2542 v.push_back (region);
2547 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2552 Glib::Mutex::Lock lm (region_lock);
2554 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2556 boost::shared_ptr<Region> region = *ii;
2560 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2564 RegionList::iterator x;
2566 for (x = regions.begin(); x != regions.end(); ++x) {
2568 if (region->region_list_equivalent (x->second)) {
2573 if (x == regions.end()) {
2575 pair<RegionList::key_type,RegionList::mapped_type> entry;
2577 entry.first = region->id();
2578 entry.second = region;
2580 pair<RegionList::iterator,bool> x = regions.insert (entry);
2592 /* mark dirty because something has changed even if we didn't
2593 add the region to the region list.
2600 vector<boost::weak_ptr<Region> > v;
2601 boost::shared_ptr<Region> first_r;
2603 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2605 boost::shared_ptr<Region> region = *ii;
2609 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2612 v.push_back (region);
2619 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2620 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2622 update_region_name_map (region);
2626 RegionsAdded (v); /* EMIT SIGNAL */
2632 Session::update_region_name_map (boost::shared_ptr<Region> region)
2634 string::size_type last_period = region->name().find_last_of ('.');
2636 if (last_period != string::npos && last_period < region->name().length() - 1) {
2638 string base = region->name().substr (0, last_period);
2639 string number = region->name().substr (last_period+1);
2640 map<string,uint32_t>::iterator x;
2642 /* note that if there is no number, we get zero from atoi,
2646 region_name_map[base] = atoi (number);
2651 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2653 boost::shared_ptr<Region> region (weak_region.lock ());
2659 if (what_changed & Region::HiddenChanged) {
2660 /* relay hidden changes */
2661 RegionHiddenChange (region);
2664 if (what_changed & NameChanged) {
2665 update_region_name_map (region);
2670 Session::remove_region (boost::weak_ptr<Region> weak_region)
2672 RegionList::iterator i;
2673 boost::shared_ptr<Region> region (weak_region.lock ());
2679 bool removed = false;
2682 Glib::Mutex::Lock lm (region_lock);
2684 if ((i = regions.find (region->id())) != regions.end()) {
2690 /* mark dirty because something has changed even if we didn't
2691 remove the region from the region list.
2697 RegionRemoved(region); /* EMIT SIGNAL */
2701 boost::shared_ptr<Region>
2702 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2704 RegionList::iterator i;
2705 boost::shared_ptr<Region> region;
2707 Glib::Mutex::Lock lm (region_lock);
2709 for (i = regions.begin(); i != regions.end(); ++i) {
2713 if (region->whole_file()) {
2715 if (child->source_equivalent (region)) {
2721 return boost::shared_ptr<Region> ();
2725 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2727 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2728 (*i)->get_region_list_equivalent_regions (region, result);
2732 Session::destroy_region (boost::shared_ptr<Region> region)
2734 vector<boost::shared_ptr<Source> > srcs;
2737 if (region->playlist()) {
2738 region->playlist()->destroy_region (region);
2741 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2742 srcs.push_back (region->source (n));
2746 region->drop_references ();
2748 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2750 (*i)->mark_for_remove ();
2751 (*i)->drop_references ();
2753 cerr << "source was not used by any playlist\n";
2760 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2762 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2763 destroy_region (*i);
2769 Session::remove_last_capture ()
2771 list<boost::shared_ptr<Region> > r;
2773 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2775 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2776 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2779 r.insert (r.end(), l.begin(), l.end());
2784 destroy_regions (r);
2786 save_state (_current_snapshot_name);
2792 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2798 /* Source Management */
2801 Session::add_source (boost::shared_ptr<Source> source)
2803 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2804 pair<SourceMap::iterator,bool> result;
2806 entry.first = source->id();
2807 entry.second = source;
2810 Glib::Mutex::Lock lm (source_lock);
2811 result = sources.insert (entry);
2814 if (result.second) {
2815 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2819 boost::shared_ptr<AudioFileSource> afs;
2821 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2822 if (Config->get_auto_analyse_audio()) {
2823 Analyser::queue_source_for_analysis (source, false);
2829 Session::remove_source (boost::weak_ptr<Source> src)
2831 SourceMap::iterator i;
2832 boost::shared_ptr<Source> source = src.lock();
2839 Glib::Mutex::Lock lm (source_lock);
2841 if ((i = sources.find (source->id())) != sources.end()) {
2846 if (!_state_of_the_state & InCleanup) {
2848 /* save state so we don't end up with a session file
2849 referring to non-existent sources.
2852 save_state (_current_snapshot_name);
2856 boost::shared_ptr<Source>
2857 Session::source_by_id (const PBD::ID& id)
2859 Glib::Mutex::Lock lm (source_lock);
2860 SourceMap::iterator i;
2861 boost::shared_ptr<Source> source;
2863 if ((i = sources.find (id)) != sources.end()) {
2870 boost::shared_ptr<Source>
2871 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2873 Glib::Mutex::Lock lm (source_lock);
2875 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2876 cerr << "comparing " << path << " with " << i->second->name() << endl;
2877 boost::shared_ptr<AudioFileSource> afs
2878 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2880 if (afs && afs->path() == path && chn == afs->channel()) {
2884 return boost::shared_ptr<Source>();
2889 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2892 string old_basename = PBD::basename_nosuffix (oldname);
2893 string new_legalized = legalize_for_path (newname);
2895 /* note: we know (or assume) the old path is already valid */
2899 /* destructive file sources have a name of the form:
2901 /path/to/Tnnnn-NAME(%[LR])?.wav
2903 the task here is to replace NAME with the new name.
2906 /* find last slash */
2910 string::size_type slash;
2911 string::size_type dash;
2913 if ((slash = path.find_last_of ('/')) == string::npos) {
2917 dir = path.substr (0, slash+1);
2919 /* '-' is not a legal character for the NAME part of the path */
2921 if ((dash = path.find_last_of ('-')) == string::npos) {
2925 prefix = path.substr (slash+1, dash-(slash+1));
2930 path += new_legalized;
2931 path += ".wav"; /* XXX gag me with a spoon */
2935 /* non-destructive file sources have a name of the form:
2937 /path/to/NAME-nnnnn(%[LR])?.ext
2939 the task here is to replace NAME with the new name.
2944 string::size_type slash;
2945 string::size_type dash;
2946 string::size_type postfix;
2948 /* find last slash */
2950 if ((slash = path.find_last_of ('/')) == string::npos) {
2954 dir = path.substr (0, slash+1);
2956 /* '-' is not a legal character for the NAME part of the path */
2958 if ((dash = path.find_last_of ('-')) == string::npos) {
2962 suffix = path.substr (dash+1);
2964 // Suffix is now everything after the dash. Now we need to eliminate
2965 // the nnnnn part, which is done by either finding a '%' or a '.'
2967 postfix = suffix.find_last_of ("%");
2968 if (postfix == string::npos) {
2969 postfix = suffix.find_last_of ('.');
2972 if (postfix != string::npos) {
2973 suffix = suffix.substr (postfix);
2975 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2979 const uint32_t limit = 10000;
2980 char buf[PATH_MAX+1];
2982 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2984 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2986 if (access (buf, F_OK) != 0) {
2994 error << "FATAL ERROR! Could not find a " << endl;
3002 /** Return the full path (in some session directory) for a new embedded source.
3003 * \a name must be a session-unique name that does not contain slashes
3004 * (e.g. as returned by new_*_source_name)
3007 Session::new_source_path_from_name (DataType type, const string& name)
3009 assert(name.find("/") == string::npos);
3011 SessionDirectory sdir(get_best_session_directory_for_new_source());
3014 if (type == DataType::AUDIO) {
3015 p = sdir.sound_path();
3016 } else if (type == DataType::MIDI) {
3017 p = sdir.midi_path();
3019 error << "Unknown source type, unable to create file path" << endmsg;
3024 return p.to_string();
3028 Session::peak_path (Glib::ustring base) const
3030 sys::path peakfile_path(_session_dir->peak_path());
3031 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3032 return peakfile_path.to_string();
3035 /** Return a unique name based on \a base for a new internal audio source */
3037 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3041 char buf[PATH_MAX+1];
3042 const uint32_t limit = 10000;
3046 legalized = legalize_for_path (base);
3048 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3049 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3051 vector<space_and_path>::iterator i;
3052 uint32_t existing = 0;
3054 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3056 SessionDirectory sdir((*i).path);
3058 spath = sdir.sound_path().to_string();
3063 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3064 spath.c_str(), cnt, legalized.c_str());
3065 } else if (nchan == 2) {
3067 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3068 spath.c_str(), cnt, legalized.c_str());
3070 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3071 spath.c_str(), cnt, legalized.c_str());
3073 } else if (nchan < 26) {
3074 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3075 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3077 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3078 spath.c_str(), cnt, legalized.c_str());
3087 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3088 } else if (nchan == 2) {
3090 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3092 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3094 } else if (nchan < 26) {
3095 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3097 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3101 if (sys::exists(buf)) {
3107 if (existing == 0) {
3112 error << string_compose(
3113 _("There are already %1 recordings for %2, which I consider too many."),
3114 limit, base) << endmsg;
3116 throw failed_constructor();
3120 return Glib::path_get_basename(buf);
3123 /** Create a new embedded audio source */
3124 boost::shared_ptr<AudioFileSource>
3125 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3127 const size_t n_chans = ds.n_channels().n_audio();
3128 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3129 const string path = new_source_path_from_name(DataType::AUDIO, name);
3130 return boost::dynamic_pointer_cast<AudioFileSource> (
3131 SourceFactory::createWritable (
3132 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3135 /** Return a unique name based on \a base for a new internal MIDI source */
3137 Session::new_midi_source_name (const string& base)
3140 char buf[PATH_MAX+1];
3141 const uint32_t limit = 10000;
3145 legalized = legalize_for_path (base);
3147 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3148 for (cnt = 1; cnt <= limit; ++cnt) {
3150 vector<space_and_path>::iterator i;
3151 uint32_t existing = 0;
3153 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3155 SessionDirectory sdir((*i).path);
3157 sys::path p = sdir.midi_path();
3160 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3162 if (sys::exists (buf)) {
3167 if (existing == 0) {
3172 error << string_compose(
3173 _("There are already %1 recordings for %2, which I consider too many."),
3174 limit, base) << endmsg;
3176 throw failed_constructor();
3180 return Glib::path_get_basename(buf);
3184 /** Create a new embedded MIDI source */
3185 boost::shared_ptr<MidiSource>
3186 Session::create_midi_source_for_session (MidiDiskstream& ds)
3188 const string name = new_midi_source_name (ds.name());
3189 const string path = new_source_path_from_name (DataType::MIDI, name);
3191 return boost::dynamic_pointer_cast<SMFSource> (
3192 SourceFactory::createWritable (
3193 DataType::MIDI, *this, path, true, false, frame_rate()));
3197 /* Playlist management */
3199 boost::shared_ptr<Playlist>
3200 Session::playlist_by_name (string name)
3202 Glib::Mutex::Lock lm (playlist_lock);
3203 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3204 if ((*i)->name() == name) {
3208 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3209 if ((*i)->name() == name) {
3214 return boost::shared_ptr<Playlist>();
3218 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3220 Glib::Mutex::Lock lm (playlist_lock);
3221 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3222 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3223 list.push_back (*i);
3226 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3227 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3228 list.push_back (*i);
3234 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3236 if (playlist->hidden()) {
3241 Glib::Mutex::Lock lm (playlist_lock);
3242 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3243 playlists.insert (playlists.begin(), playlist);
3244 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3245 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3250 playlist->release();
3255 PlaylistAdded (playlist); /* EMIT SIGNAL */
3259 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3262 Glib::Mutex::Lock lm (playlist_lock);
3263 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3266 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3273 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3275 boost::shared_ptr<Playlist> pl(wpl.lock());
3281 PlaylistList::iterator x;
3284 /* its not supposed to be visible */
3289 Glib::Mutex::Lock lm (playlist_lock);
3293 unused_playlists.insert (pl);
3295 if ((x = playlists.find (pl)) != playlists.end()) {
3296 playlists.erase (x);
3302 playlists.insert (pl);
3304 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3305 unused_playlists.erase (x);
3312 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3314 if (_state_of_the_state & Deletion) {
3318 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3325 Glib::Mutex::Lock lm (playlist_lock);
3327 PlaylistList::iterator i;
3329 i = find (playlists.begin(), playlists.end(), playlist);
3330 if (i != playlists.end()) {
3331 playlists.erase (i);
3334 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3335 if (i != unused_playlists.end()) {
3336 unused_playlists.erase (i);
3343 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3347 Session::set_audition (boost::shared_ptr<Region> r)
3349 pending_audition_region = r;
3350 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3351 schedule_butler_transport_work ();
3355 Session::audition_playlist ()
3357 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3358 ev->region.reset ();
3363 Session::non_realtime_set_audition ()
3365 if (!pending_audition_region) {
3366 auditioner->audition_current_playlist ();
3368 auditioner->audition_region (pending_audition_region);
3369 pending_audition_region.reset ();
3371 AuditionActive (true); /* EMIT SIGNAL */
3375 Session::audition_region (boost::shared_ptr<Region> r)
3377 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3383 Session::cancel_audition ()
3385 if (auditioner->active()) {
3386 auditioner->cancel_audition ();
3387 AuditionActive (false); /* EMIT SIGNAL */
3392 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3394 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3398 Session::remove_empty_sounds ()
3400 vector<string> audio_filenames;
3402 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3404 Glib::Mutex::Lock lm (source_lock);
3406 TapeFileMatcher tape_file_matcher;
3408 remove_if (audio_filenames.begin(), audio_filenames.end(),
3409 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3411 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3413 sys::path audio_file_path (_session_dir->sound_path());
3415 audio_file_path /= *i;
3417 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3421 sys::remove (audio_file_path);
3422 const string peakfile = peak_path (audio_file_path.to_string());
3423 sys::remove (peakfile);
3425 catch (const sys::filesystem_error& err)
3427 error << err.what() << endmsg;
3434 Session::is_auditioning () const
3436 /* can be called before we have an auditioner object */
3438 return auditioner->active();
3445 Session::set_all_solo (bool yn)
3447 shared_ptr<RouteList> r = routes.reader ();
3449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3450 if (!(*i)->is_hidden()) {
3451 (*i)->set_solo (yn, this);
3459 Session::set_all_mute (bool yn)
3461 shared_ptr<RouteList> r = routes.reader ();
3463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3464 if (!(*i)->is_hidden()) {
3465 (*i)->set_mute (yn, this);
3473 Session::n_diskstreams () const
3477 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3479 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3480 if (!(*i)->hidden()) {
3488 Session::graph_reordered ()
3490 /* don't do this stuff if we are setting up connections
3491 from a set_state() call or creating new tracks.
3494 if (_state_of_the_state & InitialConnecting) {
3498 /* every track/bus asked for this to be handled but it was deferred because
3499 we were connecting. do it now.
3502 request_input_change_handling ();
3506 /* force all diskstreams to update their capture offset values to
3507 reflect any changes in latencies within the graph.
3510 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3512 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3513 (*i)->set_capture_offset ();
3518 Session::record_disenable_all ()
3520 record_enable_change_all (false);
3524 Session::record_enable_all ()
3526 record_enable_change_all (true);
3530 Session::record_enable_change_all (bool yn)
3532 shared_ptr<RouteList> r = routes.reader ();
3534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3535 boost::shared_ptr<Track> t;
3537 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3538 t->set_record_enable (yn, this);
3542 /* since we don't keep rec-enable state, don't mark session dirty */
3546 Session::add_processor (Processor* processor)
3548 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3553 Session::remove_processor (Processor* processor)
3557 PortInsert* port_insert;
3559 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3560 insert_bitset[port_insert->bit_slot()] = false;
3561 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3562 send_bitset[send->bit_slot()] = false;
3563 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3564 return_bitset[send->bit_slot()] = false;
3571 Session::available_capture_duration ()
3573 float sample_bytes_on_disk = 4.0; // keep gcc happy
3575 switch (config.get_native_file_data_format()) {
3577 sample_bytes_on_disk = 4.0;
3581 sample_bytes_on_disk = 3.0;
3585 sample_bytes_on_disk = 2.0;
3589 /* impossible, but keep some gcc versions happy */
3590 fatal << string_compose (_("programming error: %1"),
3591 X_("illegal native file data format"))
3596 double scale = 4096.0 / sample_bytes_on_disk;
3598 if (_total_free_4k_blocks * scale > (double) max_frames) {
3602 return (nframes_t) floor (_total_free_4k_blocks * scale);
3606 Session::add_bundle (shared_ptr<Bundle> bundle)
3609 RCUWriter<BundleList> writer (_bundles);
3610 boost::shared_ptr<BundleList> b = writer.get_copy ();
3611 b->push_back (bundle);
3614 BundleAdded (bundle); /* EMIT SIGNAL */
3620 Session::remove_bundle (shared_ptr<Bundle> bundle)
3622 bool removed = false;
3625 RCUWriter<BundleList> writer (_bundles);
3626 boost::shared_ptr<BundleList> b = writer.get_copy ();
3627 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3629 if (i != b->end()) {
3636 BundleRemoved (bundle); /* EMIT SIGNAL */
3643 Session::bundle_by_name (string name) const
3645 boost::shared_ptr<BundleList> b = _bundles.reader ();
3647 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3648 if ((*i)->name() == name) {
3653 return boost::shared_ptr<Bundle> ();
3657 Session::tempo_map_changed (Change ignored)
3661 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3662 (*i)->update_after_tempo_map_change ();
3665 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3666 (*i)->update_after_tempo_map_change ();
3672 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3673 * the given count with the current block size.
3676 Session::ensure_buffers (ChanCount howmany)
3678 if (current_block_size == 0) {
3679 return; // too early? (is this ok?)
3682 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3683 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3684 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3685 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3686 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3689 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3693 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3695 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3696 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3701 Session::next_insert_id ()
3703 /* this doesn't really loop forever. just think about it */
3706 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3707 if (!insert_bitset[n]) {
3708 insert_bitset[n] = true;
3714 /* none available, so resize and try again */
3716 insert_bitset.resize (insert_bitset.size() + 16, false);
3721 Session::next_send_id ()
3723 /* this doesn't really loop forever. just think about it */
3726 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3727 if (!send_bitset[n]) {
3728 send_bitset[n] = true;
3734 /* none available, so resize and try again */
3736 send_bitset.resize (send_bitset.size() + 16, false);
3741 Session::next_return_id ()
3743 /* this doesn't really loop forever. just think about it */
3746 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3747 if (!return_bitset[n]) {
3748 return_bitset[n] = true;
3754 /* none available, so resize and try again */
3756 return_bitset.resize (return_bitset.size() + 16, false);
3761 Session::mark_send_id (uint32_t id)
3763 if (id >= send_bitset.size()) {
3764 send_bitset.resize (id+16, false);
3766 if (send_bitset[id]) {
3767 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3769 send_bitset[id] = true;
3773 Session::mark_return_id (uint32_t id)
3775 if (id >= return_bitset.size()) {
3776 return_bitset.resize (id+16, false);
3778 if (return_bitset[id]) {
3779 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3781 return_bitset[id] = true;
3785 Session::mark_insert_id (uint32_t id)
3787 if (id >= insert_bitset.size()) {
3788 insert_bitset.resize (id+16, false);
3790 if (insert_bitset[id]) {
3791 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3793 insert_bitset[id] = true;
3796 /* Named Selection management */
3799 Session::named_selection_by_name (string name)
3801 Glib::Mutex::Lock lm (named_selection_lock);
3802 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3803 if ((*i)->name == name) {
3811 Session::add_named_selection (NamedSelection* named_selection)
3814 Glib::Mutex::Lock lm (named_selection_lock);
3815 named_selections.insert (named_selections.begin(), named_selection);
3818 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3824 NamedSelectionAdded (); /* EMIT SIGNAL */
3828 Session::remove_named_selection (NamedSelection* named_selection)
3830 bool removed = false;
3833 Glib::Mutex::Lock lm (named_selection_lock);
3835 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3837 if (i != named_selections.end()) {
3839 named_selections.erase (i);
3846 NamedSelectionRemoved (); /* EMIT SIGNAL */
3851 Session::reset_native_file_format ()
3853 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3855 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3856 (*i)->reset_write_sources (false);
3861 Session::route_name_unique (string n) const
3863 shared_ptr<RouteList> r = routes.reader ();
3865 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3866 if ((*i)->name() == n) {
3875 Session::route_name_internal (string n) const
3877 if (auditioner && auditioner->name() == n) {
3881 if (_click_io && _click_io->name() == n) {
3889 Session::n_playlists () const
3891 Glib::Mutex::Lock lm (playlist_lock);
3892 return playlists.size();
3896 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3898 if (!force && howmany <= _npan_buffers) {
3902 if (_pan_automation_buffer) {
3904 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3905 delete [] _pan_automation_buffer[i];
3908 delete [] _pan_automation_buffer;
3911 _pan_automation_buffer = new pan_t*[howmany];
3913 for (uint32_t i = 0; i < howmany; ++i) {
3914 _pan_automation_buffer[i] = new pan_t[nframes];
3917 _npan_buffers = howmany;
3921 Session::freeze (InterThreadInfo& itt)
3923 shared_ptr<RouteList> r = routes.reader ();
3925 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3927 boost::shared_ptr<Track> t;
3929 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3930 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3940 boost::shared_ptr<Region>
3941 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3942 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
3943 InterThreadInfo& itt, bool enable_processing)
3945 boost::shared_ptr<Region> result;
3946 boost::shared_ptr<Playlist> playlist;
3947 boost::shared_ptr<AudioFileSource> fsource;
3949 char buf[PATH_MAX+1];
3950 ChanCount nchans(track.audio_diskstream()->n_channels());
3952 nframes_t this_chunk;
3955 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3956 const string sound_dir = sdir.sound_path().to_string();
3957 nframes_t len = end - start;
3960 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3961 end, start) << endmsg;
3965 // any bigger than this seems to cause stack overflows in called functions
3966 const nframes_t chunk_size = (128 * 1024)/4;
3968 // block all process callback handling
3970 block_processing ();
3972 /* call tree *MUST* hold route_lock */
3974 if ((playlist = track.diskstream()->playlist()) == 0) {
3978 /* external redirects will be a problem */
3980 if (track.has_external_redirects()) {
3984 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3986 for (x = 0; x < 99999; ++x) {
3987 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3988 if (access (buf, F_OK) != 0) {
3994 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3999 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4000 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4003 catch (failed_constructor& err) {
4004 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4008 srcs.push_back (fsource);
4011 /* XXX need to flush all redirects */
4016 /* create a set of reasonably-sized buffers */
4017 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4018 buffers.set_count(nchans);
4020 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4021 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4023 afs->prepare_for_peakfile_writes ();
4026 while (to_do && !itt.cancel) {
4028 this_chunk = min (to_do, chunk_size);
4030 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4035 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4036 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4039 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4045 start += this_chunk;
4046 to_do -= this_chunk;
4048 itt.progress = (float) (1.0 - ((double) to_do / len));
4057 xnow = localtime (&now);
4059 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4060 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4063 afs->update_header (position, *xnow, now);
4064 afs->flush_header ();
4068 /* construct a region to represent the bounced material */
4070 result = RegionFactory::create (srcs, 0,
4071 srcs.front()->length(srcs.front()->timeline_position()),
4072 region_name_from_path (srcs.front()->name(), true));
4077 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4078 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4081 afs->mark_for_remove ();
4084 (*src)->drop_references ();
4088 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4089 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4092 afs->done_with_peakfile_writes ();
4096 unblock_processing ();
4102 Session::get_silent_buffers (ChanCount count)
4104 assert(_silent_buffers->available() >= count);
4105 _silent_buffers->set_count(count);
4107 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4108 for (size_t i= 0; i < count.get(*t); ++i) {
4109 _silent_buffers->get(*t, i).clear();
4113 return *_silent_buffers;
4117 Session::get_scratch_buffers (ChanCount count)
4119 if (count != ChanCount::ZERO) {
4120 assert(_scratch_buffers->available() >= count);
4121 _scratch_buffers->set_count(count);
4123 _scratch_buffers->set_count (_scratch_buffers->available());
4126 return *_scratch_buffers;
4130 Session::get_mix_buffers (ChanCount count)
4132 assert(_mix_buffers->available() >= count);
4133 _mix_buffers->set_count(count);
4134 return *_mix_buffers;
4138 Session::ntracks () const
4141 shared_ptr<RouteList> r = routes.reader ();
4143 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4144 if (boost::dynamic_pointer_cast<Track> (*i)) {
4153 Session::nbusses () const
4156 shared_ptr<RouteList> r = routes.reader ();
4158 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4159 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4168 Session::add_automation_list(AutomationList *al)
4170 automation_lists[al->id()] = al;
4174 Session::compute_initial_length ()
4176 return _engine.frame_rate() * 60 * 5;
4180 Session::sync_order_keys (const char* base)
4182 if (!Config->get_sync_all_route_ordering()) {
4183 /* leave order keys as they are */
4187 boost::shared_ptr<RouteList> r = routes.reader ();
4189 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4190 (*i)->sync_order_keys (base);
4193 Route::SyncOrderKeys (base); // EMIT SIGNAL
4197 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4199 Session::have_rec_enabled_diskstream () const
4201 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4204 /** Update the state of our rec-enabled diskstreams flag */
4206 Session::update_have_rec_enabled_diskstream ()
4208 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4209 DiskstreamList::iterator i = dsl->begin ();
4210 while (i != dsl->end () && (*i)->record_enabled () == false) {
4214 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4216 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4218 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4219 RecordStateChanged (); /* EMIT SIGNAL */
4224 Session::solo_model_changed ()
4228 switch (Config->get_solo_model()) {
4241 boost::shared_ptr<RouteList> r = routes.reader ();
4243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4244 (*i)->put_control_outs_at (p);
4249 Session::route_edit_group_changed ()
4251 RouteEditGroupChanged (); /* EMIT SIGNAL */