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, RouteGroup* edit_group, 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();
1592 track->set_edit_group (edit_group, 0);
1594 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1595 //track->set_remote_control_id (control_id);
1597 new_routes.push_back (track);
1598 ret.push_back (track);
1601 catch (failed_constructor &err) {
1602 error << _("Session: could not create new midi track.") << endmsg;
1605 /* we need to get rid of this, since the track failed to be created */
1606 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1609 RCUWriter<DiskstreamList> writer (diskstreams);
1610 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1611 ds->remove (track->midi_diskstream());
1618 catch (AudioEngine::PortRegistrationFailure& pfe) {
1620 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;
1623 /* we need to get rid of this, since the track failed to be created */
1624 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1627 RCUWriter<DiskstreamList> writer (diskstreams);
1628 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1629 ds->remove (track->midi_diskstream());
1640 if (!new_routes.empty()) {
1641 add_routes (new_routes, false);
1642 save_state (_current_snapshot_name);
1648 list<boost::shared_ptr<AudioTrack> >
1649 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* edit_group, uint32_t how_many)
1651 char track_name[32];
1652 uint32_t track_id = 0;
1654 uint32_t channels_used = 0;
1656 RouteList new_routes;
1657 list<boost::shared_ptr<AudioTrack> > ret;
1658 uint32_t control_id;
1660 /* count existing audio tracks */
1663 shared_ptr<RouteList> r = routes.reader ();
1665 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1666 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1667 if (!(*i)->is_hidden()) {
1669 channels_used += (*i)->n_inputs().n_audio();
1675 vector<string> physinputs;
1676 vector<string> physoutputs;
1678 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1679 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1681 control_id = ntracks() + nbusses() + 1;
1685 /* check for duplicate route names, since we might have pre-existing
1686 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1687 save, close,restart,add new route - first named route is now
1695 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1697 if (route_by_name (track_name) == 0) {
1701 } while (track_id < (UINT_MAX-1));
1703 shared_ptr<AudioTrack> track;
1706 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1708 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1709 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1710 input_channels, output_channels)
1715 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1716 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1717 input_channels, output_channels)
1722 if (!physinputs.empty()) {
1723 uint32_t nphysical_in = physinputs.size();
1725 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1729 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1730 port = physinputs[(channels_used+x)%nphysical_in];
1733 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1739 if (!physoutputs.empty()) {
1740 uint32_t nphysical_out = physoutputs.size();
1742 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1745 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1746 port = physoutputs[(channels_used+x)%nphysical_out];
1747 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1748 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1749 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1753 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1759 channels_used += track->n_inputs ().n_audio();
1761 track->set_edit_group (edit_group, 0);
1763 track->audio_diskstream()->non_realtime_input_change();
1765 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1766 track->set_remote_control_id (control_id);
1769 new_routes.push_back (track);
1770 ret.push_back (track);
1773 catch (failed_constructor &err) {
1774 error << _("Session: could not create new audio track.") << endmsg;
1777 /* we need to get rid of this, since the track failed to be created */
1778 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1781 RCUWriter<DiskstreamList> writer (diskstreams);
1782 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1783 ds->remove (track->audio_diskstream());
1790 catch (AudioEngine::PortRegistrationFailure& pfe) {
1792 error << pfe.what() << endmsg;
1795 /* we need to get rid of this, since the track failed to be created */
1796 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1799 RCUWriter<DiskstreamList> writer (diskstreams);
1800 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1801 ds->remove (track->audio_diskstream());
1812 if (!new_routes.empty()) {
1813 add_routes (new_routes, true);
1820 Session::set_remote_control_ids ()
1822 RemoteModel m = Config->get_remote_model();
1824 shared_ptr<RouteList> r = routes.reader ();
1826 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1827 if ( MixerOrdered == m) {
1828 long order = (*i)->order_key(N_("signal"));
1829 (*i)->set_remote_control_id( order+1 );
1830 } else if ( EditorOrdered == m) {
1831 long order = (*i)->order_key(N_("editor"));
1832 (*i)->set_remote_control_id( order+1 );
1833 } else if ( UserOrdered == m) {
1834 //do nothing ... only changes to remote id's are initiated by user
1841 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* edit_group, uint32_t how_many)
1844 uint32_t bus_id = 1;
1846 uint32_t channels_used = 0;
1849 uint32_t control_id;
1851 /* count existing audio busses */
1854 shared_ptr<RouteList> r = routes.reader ();
1856 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1857 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1859 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1862 channels_used += (*i)->n_inputs().n_audio();
1868 vector<string> physinputs;
1869 vector<string> physoutputs;
1871 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1872 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1874 n_physical_audio_outputs = physoutputs.size();
1875 n_physical_audio_inputs = physinputs.size();
1877 control_id = ntracks() + nbusses() + 1;
1882 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1886 if (route_by_name (bus_name) == 0) {
1890 } while (bus_id < (UINT_MAX-1));
1893 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1895 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1896 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1897 input_channels, output_channels)
1903 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1904 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1905 input_channels, output_channels)
1910 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1913 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1914 port = physinputs[((n+x)%n_physical_audio_inputs)];
1917 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1922 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1925 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1926 port = physoutputs[((n+x)%n_physical_outputs)];
1927 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1929 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1933 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1938 channels_used += bus->n_inputs ().n_audio();
1940 bus->set_edit_group (edit_group, 0);
1941 bus->set_remote_control_id (control_id);
1944 ret.push_back (bus);
1948 catch (failed_constructor &err) {
1949 error << _("Session: could not create new audio route.") << endmsg;
1953 catch (AudioEngine::PortRegistrationFailure& pfe) {
1954 error << pfe.what() << endmsg;
1964 add_routes (ret, true);
1972 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1976 uint32_t control_id;
1979 if (!tree.read (template_path.c_str())) {
1983 XMLNode* node = tree.root();
1985 control_id = ntracks() + nbusses() + 1;
1989 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1991 std::string node_name = IO::name_from_state (*node_copy.children().front());
1993 if (route_by_name (node_name) != 0) {
1995 /* generate a new name by adding a number to the end of the template name */
1997 uint32_t number = 1;
2000 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2004 if (route_by_name (name) == 0) {
2008 } while (number < UINT_MAX);
2010 if (number == UINT_MAX) {
2011 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2015 IO::set_name_in_state (*node_copy.children().front(), name);
2018 Track::zero_diskstream_id_in_xml (node_copy);
2021 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2024 error << _("Session: cannot create track/bus from template description") << endmsg;
2028 if (boost::dynamic_pointer_cast<Track>(route)) {
2029 /* force input/output change signals so that the new diskstream
2030 picks up the configuration of the route. During session
2031 loading this normally happens in a different way.
2033 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2034 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2037 route->set_remote_control_id (control_id);
2040 ret.push_back (route);
2043 catch (failed_constructor &err) {
2044 error << _("Session: could not create new route from template") << endmsg;
2048 catch (AudioEngine::PortRegistrationFailure& pfe) {
2049 error << pfe.what() << endmsg;
2058 add_routes (ret, true);
2065 Session::add_routes (RouteList& new_routes, bool save)
2068 RCUWriter<RouteList> writer (routes);
2069 shared_ptr<RouteList> r = writer.get_copy ();
2070 r->insert (r->end(), new_routes.begin(), new_routes.end());
2072 if (!_control_out && IO::connecting_legal) {
2073 resort_routes_using (r);
2077 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2079 boost::weak_ptr<Route> wpr (*x);
2081 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2082 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2083 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2084 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2085 (*x)->edit_group_changed.connect (hide (mem_fun (*this, &Session::route_edit_group_changed)));
2087 if ((*x)->is_master()) {
2091 if ((*x)->is_control()) {
2092 _control_out = (*x);
2096 if (_control_out && IO::connecting_legal) {
2098 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2099 (*x)->listen_via (_control_out, "control");
2108 save_state (_current_snapshot_name);
2111 RouteAdded (new_routes); /* EMIT SIGNAL */
2115 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2117 /* need to do this in case we're rolling at the time, to prevent false underruns */
2118 dstream->do_refill_with_alloc ();
2120 dstream->set_block_size (current_block_size);
2123 RCUWriter<DiskstreamList> writer (diskstreams);
2124 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2125 ds->push_back (dstream);
2126 /* writer goes out of scope, copies ds back to main */
2129 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2130 /* this will connect to future changes, and check the current length */
2131 diskstream_playlist_changed (dstream);
2133 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2135 dstream->prepare ();
2140 Session::remove_route (shared_ptr<Route> route)
2143 RCUWriter<RouteList> writer (routes);
2144 shared_ptr<RouteList> rs = writer.get_copy ();
2148 /* deleting the master out seems like a dumb
2149 idea, but its more of a UI policy issue
2153 if (route == _master_out) {
2154 _master_out = shared_ptr<Route> ();
2157 if (route == _control_out) {
2159 /* cancel control outs for all routes */
2161 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2162 (*r)->drop_listen (_control_out);
2165 _control_out.reset ();
2168 update_route_solo_state ();
2170 /* writer goes out of scope, forces route list update */
2173 boost::shared_ptr<Track> t;
2174 boost::shared_ptr<Diskstream> ds;
2176 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2177 ds = t->diskstream();
2183 RCUWriter<DiskstreamList> dsl (diskstreams);
2184 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2189 find_current_end ();
2191 // We need to disconnect the routes inputs and outputs
2193 route->input()->disconnect (0);
2194 route->output()->disconnect (0);
2196 update_latency_compensation (false, false);
2199 /* get rid of it from the dead wood collection in the route list manager */
2201 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2205 /* try to cause everyone to drop their references */
2207 route->drop_references ();
2209 sync_order_keys (N_("session"));
2211 /* save the new state of the world */
2213 if (save_state (_current_snapshot_name)) {
2214 save_history (_current_snapshot_name);
2219 Session::route_mute_changed (void* src)
2225 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2227 if (solo_update_disabled) {
2232 boost::shared_ptr<Route> route = wpr.lock ();
2235 /* should not happen */
2236 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2240 shared_ptr<RouteList> r = routes.reader ();
2243 if (route->soloed()) {
2249 solo_update_disabled = true;
2250 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2252 if ((*i)->feeds (route)) {
2254 (*i)->mod_solo_level (delta);
2258 /* make sure master is never muted by solo */
2260 if (_master_out->solo_level() == 0) {
2261 _master_out->mod_solo_level (1);
2264 /* ditto for control outs make sure master is never muted by solo */
2266 if (_control_out && _control_out->solo_level() == 0) {
2267 _control_out->mod_solo_level (1);
2270 solo_update_disabled = false;
2271 update_route_solo_state (r);
2272 SoloChanged (); /* EMIT SIGNAL */
2277 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2279 /* now figure out if anything that matters is soloed */
2281 bool something_soloed = false;
2284 r = routes.reader();
2287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2288 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2289 something_soloed = true;
2294 if (something_soloed != _non_soloed_outs_muted) {
2295 _non_soloed_outs_muted = something_soloed;
2296 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2301 Session::catch_up_on_solo ()
2303 /* this is called after set_state() to catch the full solo
2304 state, which can't be correctly determined on a per-route
2305 basis, but needs the global overview that only the session
2308 update_route_solo_state();
2312 Session::catch_up_on_solo_mute_override ()
2314 if (Config->get_solo_model() != SoloInPlace) {
2318 /* this is called whenever the param solo-mute-override is
2321 shared_ptr<RouteList> r = routes.reader ();
2323 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2324 // (*i)->catch_up_on_solo_mute_override ();
2329 Session::route_by_name (string name)
2331 shared_ptr<RouteList> r = routes.reader ();
2333 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2334 if ((*i)->name() == name) {
2339 return shared_ptr<Route> ((Route*) 0);
2343 Session::route_by_id (PBD::ID id)
2345 shared_ptr<RouteList> r = routes.reader ();
2347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2348 if ((*i)->id() == id) {
2353 return shared_ptr<Route> ((Route*) 0);
2357 Session::route_by_remote_id (uint32_t id)
2359 shared_ptr<RouteList> r = routes.reader ();
2361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2362 if ((*i)->remote_control_id() == id) {
2367 return shared_ptr<Route> ((Route*) 0);
2371 Session::find_current_end ()
2373 if (_state_of_the_state & Loading) {
2377 nframes_t max = get_maximum_extent ();
2379 if (max > end_location->end()) {
2380 end_location->set_end (max);
2382 DurationChanged(); /* EMIT SIGNAL */
2387 Session::get_maximum_extent () const
2392 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2394 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2395 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2397 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2398 if ((me = pl->get_maximum_extent()) > max) {
2406 boost::shared_ptr<Diskstream>
2407 Session::diskstream_by_name (string name)
2409 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2411 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2412 if ((*i)->name() == name) {
2417 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2420 boost::shared_ptr<Diskstream>
2421 Session::diskstream_by_id (const PBD::ID& id)
2423 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2425 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2426 if ((*i)->id() == id) {
2431 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2434 /* Region management */
2437 Session::new_region_name (string old)
2439 string::size_type last_period;
2441 string::size_type len = old.length() + 64;
2444 if ((last_period = old.find_last_of ('.')) == string::npos) {
2446 /* no period present - add one explicitly */
2449 last_period = old.length() - 1;
2454 number = atoi (old.substr (last_period+1).c_str());
2458 while (number < (UINT_MAX-1)) {
2460 RegionList::const_iterator i;
2465 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2468 for (i = regions.begin(); i != regions.end(); ++i) {
2469 if (i->second->name() == sbuf) {
2474 if (i == regions.end()) {
2479 if (number != (UINT_MAX-1)) {
2483 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2488 Session::region_name (string& result, string base, bool newlevel)
2493 if (base.find("/") != string::npos) {
2494 base = base.substr(base.find_last_of("/") + 1);
2499 Glib::Mutex::Lock lm (region_lock);
2501 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2510 string::size_type pos;
2512 pos = base.find_last_of ('.');
2514 /* pos may be npos, but then we just use entire base */
2516 subbase = base.substr (0, pos);
2521 Glib::Mutex::Lock lm (region_lock);
2523 map<string,uint32_t>::iterator x;
2527 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2529 region_name_map[subbase] = 1;
2532 snprintf (buf, sizeof (buf), ".%d", x->second);
2543 Session::add_region (boost::shared_ptr<Region> region)
2545 vector<boost::shared_ptr<Region> > v;
2546 v.push_back (region);
2551 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2556 Glib::Mutex::Lock lm (region_lock);
2558 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2560 boost::shared_ptr<Region> region = *ii;
2564 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2568 RegionList::iterator x;
2570 for (x = regions.begin(); x != regions.end(); ++x) {
2572 if (region->region_list_equivalent (x->second)) {
2577 if (x == regions.end()) {
2579 pair<RegionList::key_type,RegionList::mapped_type> entry;
2581 entry.first = region->id();
2582 entry.second = region;
2584 pair<RegionList::iterator,bool> x = regions.insert (entry);
2596 /* mark dirty because something has changed even if we didn't
2597 add the region to the region list.
2604 vector<boost::weak_ptr<Region> > v;
2605 boost::shared_ptr<Region> first_r;
2607 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2609 boost::shared_ptr<Region> region = *ii;
2613 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2616 v.push_back (region);
2623 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2624 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2626 update_region_name_map (region);
2630 RegionsAdded (v); /* EMIT SIGNAL */
2636 Session::update_region_name_map (boost::shared_ptr<Region> region)
2638 string::size_type last_period = region->name().find_last_of ('.');
2640 if (last_period != string::npos && last_period < region->name().length() - 1) {
2642 string base = region->name().substr (0, last_period);
2643 string number = region->name().substr (last_period+1);
2644 map<string,uint32_t>::iterator x;
2646 /* note that if there is no number, we get zero from atoi,
2650 region_name_map[base] = atoi (number);
2655 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2657 boost::shared_ptr<Region> region (weak_region.lock ());
2663 if (what_changed & Region::HiddenChanged) {
2664 /* relay hidden changes */
2665 RegionHiddenChange (region);
2668 if (what_changed & NameChanged) {
2669 update_region_name_map (region);
2674 Session::remove_region (boost::weak_ptr<Region> weak_region)
2676 RegionList::iterator i;
2677 boost::shared_ptr<Region> region (weak_region.lock ());
2683 bool removed = false;
2686 Glib::Mutex::Lock lm (region_lock);
2688 if ((i = regions.find (region->id())) != regions.end()) {
2694 /* mark dirty because something has changed even if we didn't
2695 remove the region from the region list.
2701 RegionRemoved(region); /* EMIT SIGNAL */
2705 boost::shared_ptr<Region>
2706 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2708 RegionList::iterator i;
2709 boost::shared_ptr<Region> region;
2711 Glib::Mutex::Lock lm (region_lock);
2713 for (i = regions.begin(); i != regions.end(); ++i) {
2717 if (region->whole_file()) {
2719 if (child->source_equivalent (region)) {
2725 return boost::shared_ptr<Region> ();
2729 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2731 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2732 (*i)->get_region_list_equivalent_regions (region, result);
2736 Session::destroy_region (boost::shared_ptr<Region> region)
2738 vector<boost::shared_ptr<Source> > srcs;
2741 if (region->playlist()) {
2742 region->playlist()->destroy_region (region);
2745 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2746 srcs.push_back (region->source (n));
2750 region->drop_references ();
2752 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2754 (*i)->mark_for_remove ();
2755 (*i)->drop_references ();
2757 cerr << "source was not used by any playlist\n";
2764 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2766 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2767 destroy_region (*i);
2773 Session::remove_last_capture ()
2775 list<boost::shared_ptr<Region> > r;
2777 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2779 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2780 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2783 r.insert (r.end(), l.begin(), l.end());
2788 destroy_regions (r);
2790 save_state (_current_snapshot_name);
2796 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2802 /* Source Management */
2805 Session::add_source (boost::shared_ptr<Source> source)
2807 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2808 pair<SourceMap::iterator,bool> result;
2810 entry.first = source->id();
2811 entry.second = source;
2814 Glib::Mutex::Lock lm (source_lock);
2815 result = sources.insert (entry);
2818 if (result.second) {
2819 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2823 boost::shared_ptr<AudioFileSource> afs;
2825 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2826 if (Config->get_auto_analyse_audio()) {
2827 Analyser::queue_source_for_analysis (source, false);
2833 Session::remove_source (boost::weak_ptr<Source> src)
2835 SourceMap::iterator i;
2836 boost::shared_ptr<Source> source = src.lock();
2843 Glib::Mutex::Lock lm (source_lock);
2845 if ((i = sources.find (source->id())) != sources.end()) {
2850 if (!_state_of_the_state & InCleanup) {
2852 /* save state so we don't end up with a session file
2853 referring to non-existent sources.
2856 save_state (_current_snapshot_name);
2860 boost::shared_ptr<Source>
2861 Session::source_by_id (const PBD::ID& id)
2863 Glib::Mutex::Lock lm (source_lock);
2864 SourceMap::iterator i;
2865 boost::shared_ptr<Source> source;
2867 if ((i = sources.find (id)) != sources.end()) {
2874 boost::shared_ptr<Source>
2875 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2877 Glib::Mutex::Lock lm (source_lock);
2879 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2880 cerr << "comparing " << path << " with " << i->second->name() << endl;
2881 boost::shared_ptr<AudioFileSource> afs
2882 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2884 if (afs && afs->path() == path && chn == afs->channel()) {
2888 return boost::shared_ptr<Source>();
2893 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2896 string old_basename = PBD::basename_nosuffix (oldname);
2897 string new_legalized = legalize_for_path (newname);
2899 /* note: we know (or assume) the old path is already valid */
2903 /* destructive file sources have a name of the form:
2905 /path/to/Tnnnn-NAME(%[LR])?.wav
2907 the task here is to replace NAME with the new name.
2910 /* find last slash */
2914 string::size_type slash;
2915 string::size_type dash;
2917 if ((slash = path.find_last_of ('/')) == string::npos) {
2921 dir = path.substr (0, slash+1);
2923 /* '-' is not a legal character for the NAME part of the path */
2925 if ((dash = path.find_last_of ('-')) == string::npos) {
2929 prefix = path.substr (slash+1, dash-(slash+1));
2934 path += new_legalized;
2935 path += ".wav"; /* XXX gag me with a spoon */
2939 /* non-destructive file sources have a name of the form:
2941 /path/to/NAME-nnnnn(%[LR])?.ext
2943 the task here is to replace NAME with the new name.
2948 string::size_type slash;
2949 string::size_type dash;
2950 string::size_type postfix;
2952 /* find last slash */
2954 if ((slash = path.find_last_of ('/')) == string::npos) {
2958 dir = path.substr (0, slash+1);
2960 /* '-' is not a legal character for the NAME part of the path */
2962 if ((dash = path.find_last_of ('-')) == string::npos) {
2966 suffix = path.substr (dash+1);
2968 // Suffix is now everything after the dash. Now we need to eliminate
2969 // the nnnnn part, which is done by either finding a '%' or a '.'
2971 postfix = suffix.find_last_of ("%");
2972 if (postfix == string::npos) {
2973 postfix = suffix.find_last_of ('.');
2976 if (postfix != string::npos) {
2977 suffix = suffix.substr (postfix);
2979 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2983 const uint32_t limit = 10000;
2984 char buf[PATH_MAX+1];
2986 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2988 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2990 if (access (buf, F_OK) != 0) {
2998 error << "FATAL ERROR! Could not find a " << endl;
3006 /** Return the full path (in some session directory) for a new embedded source.
3007 * \a name must be a session-unique name that does not contain slashes
3008 * (e.g. as returned by new_*_source_name)
3011 Session::new_source_path_from_name (DataType type, const string& name)
3013 assert(name.find("/") == string::npos);
3015 SessionDirectory sdir(get_best_session_directory_for_new_source());
3018 if (type == DataType::AUDIO) {
3019 p = sdir.sound_path();
3020 } else if (type == DataType::MIDI) {
3021 p = sdir.midi_path();
3023 error << "Unknown source type, unable to create file path" << endmsg;
3028 return p.to_string();
3032 Session::peak_path (Glib::ustring base) const
3034 sys::path peakfile_path(_session_dir->peak_path());
3035 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3036 return peakfile_path.to_string();
3039 /** Return a unique name based on \a base for a new internal audio source */
3041 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3045 char buf[PATH_MAX+1];
3046 const uint32_t limit = 10000;
3050 legalized = legalize_for_path (base);
3052 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3053 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3055 vector<space_and_path>::iterator i;
3056 uint32_t existing = 0;
3058 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3060 SessionDirectory sdir((*i).path);
3062 spath = sdir.sound_path().to_string();
3067 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3068 spath.c_str(), cnt, legalized.c_str());
3069 } else if (nchan == 2) {
3071 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3072 spath.c_str(), cnt, legalized.c_str());
3074 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3075 spath.c_str(), cnt, legalized.c_str());
3077 } else if (nchan < 26) {
3078 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3079 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3081 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3082 spath.c_str(), cnt, legalized.c_str());
3091 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3092 } else if (nchan == 2) {
3094 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3096 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3098 } else if (nchan < 26) {
3099 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3101 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3105 if (sys::exists(buf)) {
3111 if (existing == 0) {
3116 error << string_compose(
3117 _("There are already %1 recordings for %2, which I consider too many."),
3118 limit, base) << endmsg;
3120 throw failed_constructor();
3124 return Glib::path_get_basename(buf);
3127 /** Create a new embedded audio source */
3128 boost::shared_ptr<AudioFileSource>
3129 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3131 const size_t n_chans = ds.n_channels().n_audio();
3132 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3133 const string path = new_source_path_from_name(DataType::AUDIO, name);
3134 return boost::dynamic_pointer_cast<AudioFileSource> (
3135 SourceFactory::createWritable (
3136 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3139 /** Return a unique name based on \a base for a new internal MIDI source */
3141 Session::new_midi_source_name (const string& base)
3144 char buf[PATH_MAX+1];
3145 const uint32_t limit = 10000;
3149 legalized = legalize_for_path (base);
3151 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3152 for (cnt = 1; cnt <= limit; ++cnt) {
3154 vector<space_and_path>::iterator i;
3155 uint32_t existing = 0;
3157 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3159 SessionDirectory sdir((*i).path);
3161 sys::path p = sdir.midi_path();
3164 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3166 if (sys::exists (buf)) {
3171 if (existing == 0) {
3176 error << string_compose(
3177 _("There are already %1 recordings for %2, which I consider too many."),
3178 limit, base) << endmsg;
3180 throw failed_constructor();
3184 return Glib::path_get_basename(buf);
3188 /** Create a new embedded MIDI source */
3189 boost::shared_ptr<MidiSource>
3190 Session::create_midi_source_for_session (MidiDiskstream& ds)
3192 const string name = new_midi_source_name (ds.name());
3193 const string path = new_source_path_from_name (DataType::MIDI, name);
3195 return boost::dynamic_pointer_cast<SMFSource> (
3196 SourceFactory::createWritable (
3197 DataType::MIDI, *this, path, true, false, frame_rate()));
3201 /* Playlist management */
3203 boost::shared_ptr<Playlist>
3204 Session::playlist_by_name (string name)
3206 Glib::Mutex::Lock lm (playlist_lock);
3207 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3208 if ((*i)->name() == name) {
3212 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3213 if ((*i)->name() == name) {
3218 return boost::shared_ptr<Playlist>();
3222 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3224 Glib::Mutex::Lock lm (playlist_lock);
3225 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3226 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3227 list.push_back (*i);
3230 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3231 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3232 list.push_back (*i);
3238 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3240 if (playlist->hidden()) {
3245 Glib::Mutex::Lock lm (playlist_lock);
3246 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3247 playlists.insert (playlists.begin(), playlist);
3248 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3249 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3254 playlist->release();
3259 PlaylistAdded (playlist); /* EMIT SIGNAL */
3263 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3266 Glib::Mutex::Lock lm (playlist_lock);
3267 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3270 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3277 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3279 boost::shared_ptr<Playlist> pl(wpl.lock());
3285 PlaylistList::iterator x;
3288 /* its not supposed to be visible */
3293 Glib::Mutex::Lock lm (playlist_lock);
3297 unused_playlists.insert (pl);
3299 if ((x = playlists.find (pl)) != playlists.end()) {
3300 playlists.erase (x);
3306 playlists.insert (pl);
3308 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3309 unused_playlists.erase (x);
3316 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3318 if (_state_of_the_state & Deletion) {
3322 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3329 Glib::Mutex::Lock lm (playlist_lock);
3331 PlaylistList::iterator i;
3333 i = find (playlists.begin(), playlists.end(), playlist);
3334 if (i != playlists.end()) {
3335 playlists.erase (i);
3338 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3339 if (i != unused_playlists.end()) {
3340 unused_playlists.erase (i);
3347 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3351 Session::set_audition (boost::shared_ptr<Region> r)
3353 pending_audition_region = r;
3354 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3355 schedule_butler_transport_work ();
3359 Session::audition_playlist ()
3361 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3362 ev->region.reset ();
3367 Session::non_realtime_set_audition ()
3369 if (!pending_audition_region) {
3370 auditioner->audition_current_playlist ();
3372 auditioner->audition_region (pending_audition_region);
3373 pending_audition_region.reset ();
3375 AuditionActive (true); /* EMIT SIGNAL */
3379 Session::audition_region (boost::shared_ptr<Region> r)
3381 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3387 Session::cancel_audition ()
3389 if (auditioner->active()) {
3390 auditioner->cancel_audition ();
3391 AuditionActive (false); /* EMIT SIGNAL */
3396 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3398 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3402 Session::remove_empty_sounds ()
3404 vector<string> audio_filenames;
3406 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3408 Glib::Mutex::Lock lm (source_lock);
3410 TapeFileMatcher tape_file_matcher;
3412 remove_if (audio_filenames.begin(), audio_filenames.end(),
3413 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3415 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3417 sys::path audio_file_path (_session_dir->sound_path());
3419 audio_file_path /= *i;
3421 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3425 sys::remove (audio_file_path);
3426 const string peakfile = peak_path (audio_file_path.to_string());
3427 sys::remove (peakfile);
3429 catch (const sys::filesystem_error& err)
3431 error << err.what() << endmsg;
3438 Session::is_auditioning () const
3440 /* can be called before we have an auditioner object */
3442 return auditioner->active();
3449 Session::set_all_solo (bool yn)
3451 shared_ptr<RouteList> r = routes.reader ();
3453 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3454 if (!(*i)->is_hidden()) {
3455 (*i)->set_solo (yn, this);
3463 Session::set_all_mute (bool yn)
3465 shared_ptr<RouteList> r = routes.reader ();
3467 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3468 if (!(*i)->is_hidden()) {
3469 (*i)->set_mute (yn, this);
3477 Session::n_diskstreams () const
3481 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3483 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3484 if (!(*i)->hidden()) {
3492 Session::graph_reordered ()
3494 /* don't do this stuff if we are setting up connections
3495 from a set_state() call or creating new tracks.
3498 if (_state_of_the_state & InitialConnecting) {
3502 /* every track/bus asked for this to be handled but it was deferred because
3503 we were connecting. do it now.
3506 request_input_change_handling ();
3510 /* force all diskstreams to update their capture offset values to
3511 reflect any changes in latencies within the graph.
3514 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3516 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3517 (*i)->set_capture_offset ();
3522 Session::record_disenable_all ()
3524 record_enable_change_all (false);
3528 Session::record_enable_all ()
3530 record_enable_change_all (true);
3534 Session::record_enable_change_all (bool yn)
3536 shared_ptr<RouteList> r = routes.reader ();
3538 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3539 boost::shared_ptr<Track> t;
3541 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3542 t->set_record_enable (yn, this);
3546 /* since we don't keep rec-enable state, don't mark session dirty */
3550 Session::add_processor (Processor* processor)
3552 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3557 Session::remove_processor (Processor* processor)
3561 PortInsert* port_insert;
3563 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3564 insert_bitset[port_insert->bit_slot()] = false;
3565 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3566 send_bitset[send->bit_slot()] = false;
3567 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3568 return_bitset[send->bit_slot()] = false;
3575 Session::available_capture_duration ()
3577 float sample_bytes_on_disk = 4.0; // keep gcc happy
3579 switch (config.get_native_file_data_format()) {
3581 sample_bytes_on_disk = 4.0;
3585 sample_bytes_on_disk = 3.0;
3589 sample_bytes_on_disk = 2.0;
3593 /* impossible, but keep some gcc versions happy */
3594 fatal << string_compose (_("programming error: %1"),
3595 X_("illegal native file data format"))
3600 double scale = 4096.0 / sample_bytes_on_disk;
3602 if (_total_free_4k_blocks * scale > (double) max_frames) {
3606 return (nframes_t) floor (_total_free_4k_blocks * scale);
3610 Session::add_bundle (shared_ptr<Bundle> bundle)
3613 RCUWriter<BundleList> writer (_bundles);
3614 boost::shared_ptr<BundleList> b = writer.get_copy ();
3615 b->push_back (bundle);
3618 BundleAdded (bundle); /* EMIT SIGNAL */
3624 Session::remove_bundle (shared_ptr<Bundle> bundle)
3626 bool removed = false;
3629 RCUWriter<BundleList> writer (_bundles);
3630 boost::shared_ptr<BundleList> b = writer.get_copy ();
3631 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3633 if (i != b->end()) {
3640 BundleRemoved (bundle); /* EMIT SIGNAL */
3647 Session::bundle_by_name (string name) const
3649 boost::shared_ptr<BundleList> b = _bundles.reader ();
3651 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3652 if ((*i)->name() == name) {
3657 return boost::shared_ptr<Bundle> ();
3661 Session::tempo_map_changed (Change ignored)
3665 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3666 (*i)->update_after_tempo_map_change ();
3669 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3670 (*i)->update_after_tempo_map_change ();
3676 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3677 * the given count with the current block size.
3680 Session::ensure_buffers (ChanCount howmany)
3682 if (current_block_size == 0) {
3683 return; // too early? (is this ok?)
3686 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3687 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3688 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3689 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3690 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3693 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3697 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3699 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3700 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3705 Session::next_insert_id ()
3707 /* this doesn't really loop forever. just think about it */
3710 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3711 if (!insert_bitset[n]) {
3712 insert_bitset[n] = true;
3718 /* none available, so resize and try again */
3720 insert_bitset.resize (insert_bitset.size() + 16, false);
3725 Session::next_send_id ()
3727 /* this doesn't really loop forever. just think about it */
3730 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3731 if (!send_bitset[n]) {
3732 send_bitset[n] = true;
3738 /* none available, so resize and try again */
3740 send_bitset.resize (send_bitset.size() + 16, false);
3745 Session::next_return_id ()
3747 /* this doesn't really loop forever. just think about it */
3750 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3751 if (!return_bitset[n]) {
3752 return_bitset[n] = true;
3758 /* none available, so resize and try again */
3760 return_bitset.resize (return_bitset.size() + 16, false);
3765 Session::mark_send_id (uint32_t id)
3767 if (id >= send_bitset.size()) {
3768 send_bitset.resize (id+16, false);
3770 if (send_bitset[id]) {
3771 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3773 send_bitset[id] = true;
3777 Session::mark_return_id (uint32_t id)
3779 if (id >= return_bitset.size()) {
3780 return_bitset.resize (id+16, false);
3782 if (return_bitset[id]) {
3783 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3785 return_bitset[id] = true;
3789 Session::mark_insert_id (uint32_t id)
3791 if (id >= insert_bitset.size()) {
3792 insert_bitset.resize (id+16, false);
3794 if (insert_bitset[id]) {
3795 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3797 insert_bitset[id] = true;
3800 /* Named Selection management */
3803 Session::named_selection_by_name (string name)
3805 Glib::Mutex::Lock lm (named_selection_lock);
3806 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3807 if ((*i)->name == name) {
3815 Session::add_named_selection (NamedSelection* named_selection)
3818 Glib::Mutex::Lock lm (named_selection_lock);
3819 named_selections.insert (named_selections.begin(), named_selection);
3822 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3828 NamedSelectionAdded (); /* EMIT SIGNAL */
3832 Session::remove_named_selection (NamedSelection* named_selection)
3834 bool removed = false;
3837 Glib::Mutex::Lock lm (named_selection_lock);
3839 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3841 if (i != named_selections.end()) {
3843 named_selections.erase (i);
3850 NamedSelectionRemoved (); /* EMIT SIGNAL */
3855 Session::reset_native_file_format ()
3857 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3859 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3860 (*i)->reset_write_sources (false);
3865 Session::route_name_unique (string n) const
3867 shared_ptr<RouteList> r = routes.reader ();
3869 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3870 if ((*i)->name() == n) {
3879 Session::route_name_internal (string n) const
3881 if (auditioner && auditioner->name() == n) {
3885 if (_click_io && _click_io->name() == n) {
3893 Session::n_playlists () const
3895 Glib::Mutex::Lock lm (playlist_lock);
3896 return playlists.size();
3900 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3902 if (!force && howmany <= _npan_buffers) {
3906 if (_pan_automation_buffer) {
3908 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3909 delete [] _pan_automation_buffer[i];
3912 delete [] _pan_automation_buffer;
3915 _pan_automation_buffer = new pan_t*[howmany];
3917 for (uint32_t i = 0; i < howmany; ++i) {
3918 _pan_automation_buffer[i] = new pan_t[nframes];
3921 _npan_buffers = howmany;
3925 Session::freeze (InterThreadInfo& itt)
3927 shared_ptr<RouteList> r = routes.reader ();
3929 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3931 boost::shared_ptr<Track> t;
3933 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3934 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3944 boost::shared_ptr<Region>
3945 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3946 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
3947 InterThreadInfo& itt, bool enable_processing)
3949 boost::shared_ptr<Region> result;
3950 boost::shared_ptr<Playlist> playlist;
3951 boost::shared_ptr<AudioFileSource> fsource;
3953 char buf[PATH_MAX+1];
3954 ChanCount nchans(track.audio_diskstream()->n_channels());
3956 nframes_t this_chunk;
3959 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3960 const string sound_dir = sdir.sound_path().to_string();
3961 nframes_t len = end - start;
3964 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3965 end, start) << endmsg;
3969 // any bigger than this seems to cause stack overflows in called functions
3970 const nframes_t chunk_size = (128 * 1024)/4;
3972 // block all process callback handling
3974 block_processing ();
3976 /* call tree *MUST* hold route_lock */
3978 if ((playlist = track.diskstream()->playlist()) == 0) {
3982 /* external redirects will be a problem */
3984 if (track.has_external_redirects()) {
3988 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3990 for (x = 0; x < 99999; ++x) {
3991 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3992 if (access (buf, F_OK) != 0) {
3998 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4003 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4004 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4007 catch (failed_constructor& err) {
4008 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4012 srcs.push_back (fsource);
4015 /* XXX need to flush all redirects */
4020 /* create a set of reasonably-sized buffers */
4021 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4022 buffers.set_count(nchans);
4024 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4025 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4027 afs->prepare_for_peakfile_writes ();
4030 while (to_do && !itt.cancel) {
4032 this_chunk = min (to_do, chunk_size);
4034 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4039 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4040 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4043 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4049 start += this_chunk;
4050 to_do -= this_chunk;
4052 itt.progress = (float) (1.0 - ((double) to_do / len));
4061 xnow = localtime (&now);
4063 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4064 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4067 afs->update_header (position, *xnow, now);
4068 afs->flush_header ();
4072 /* construct a region to represent the bounced material */
4074 result = RegionFactory::create (srcs, 0,
4075 srcs.front()->length(srcs.front()->timeline_position()),
4076 region_name_from_path (srcs.front()->name(), true));
4081 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4082 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4085 afs->mark_for_remove ();
4088 (*src)->drop_references ();
4092 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4093 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4096 afs->done_with_peakfile_writes ();
4100 unblock_processing ();
4106 Session::get_silent_buffers (ChanCount count)
4108 assert(_silent_buffers->available() >= count);
4109 _silent_buffers->set_count(count);
4111 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4112 for (size_t i= 0; i < count.get(*t); ++i) {
4113 _silent_buffers->get(*t, i).clear();
4117 return *_silent_buffers;
4121 Session::get_scratch_buffers (ChanCount count)
4123 if (count != ChanCount::ZERO) {
4124 assert(_scratch_buffers->available() >= count);
4125 _scratch_buffers->set_count(count);
4127 _scratch_buffers->set_count (_scratch_buffers->available());
4130 return *_scratch_buffers;
4134 Session::get_mix_buffers (ChanCount count)
4136 assert(_mix_buffers->available() >= count);
4137 _mix_buffers->set_count(count);
4138 return *_mix_buffers;
4142 Session::ntracks () const
4145 shared_ptr<RouteList> r = routes.reader ();
4147 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4148 if (boost::dynamic_pointer_cast<Track> (*i)) {
4157 Session::nbusses () const
4160 shared_ptr<RouteList> r = routes.reader ();
4162 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4163 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4172 Session::add_automation_list(AutomationList *al)
4174 automation_lists[al->id()] = al;
4178 Session::compute_initial_length ()
4180 return _engine.frame_rate() * 60 * 5;
4184 Session::sync_order_keys (const char* base)
4186 if (!Config->get_sync_all_route_ordering()) {
4187 /* leave order keys as they are */
4191 boost::shared_ptr<RouteList> r = routes.reader ();
4193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4194 (*i)->sync_order_keys (base);
4197 Route::SyncOrderKeys (base); // EMIT SIGNAL
4201 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4203 Session::have_rec_enabled_diskstream () const
4205 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4208 /** Update the state of our rec-enabled diskstreams flag */
4210 Session::update_have_rec_enabled_diskstream ()
4212 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4213 DiskstreamList::iterator i = dsl->begin ();
4214 while (i != dsl->end () && (*i)->record_enabled () == false) {
4218 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4220 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4222 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4223 RecordStateChanged (); /* EMIT SIGNAL */
4228 Session::solo_model_changed ()
4232 switch (Config->get_solo_model()) {
4245 boost::shared_ptr<RouteList> r = routes.reader ();
4247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4248 (*i)->put_control_outs_at (p);
4253 Session::route_edit_group_changed ()
4255 RouteEditGroupChanged (); /* EMIT SIGNAL */