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,
119 _requested_return_frame (-1),
120 _scratch_buffers(new BufferSet()),
121 _silent_buffers(new BufferSet()),
122 _mix_buffers(new BufferSet()),
124 _mmc_port (default_mmc_port),
125 _mtc_port (default_mtc_port),
126 _midi_port (default_midi_port),
127 _midi_clock_port (default_midi_clock_port),
128 _session_dir (new SessionDirectory(fullpath)),
129 pending_events (2048),
131 butler_mixdown_buffer (0),
132 butler_gain_buffer (0),
133 post_transport_work((PostTransportWork)0),
134 _send_smpte_update (false),
135 midi_thread (pthread_t (0)),
136 midi_requests (128), // the size of this should match the midi request pool size
137 diskstreams (new DiskstreamList),
138 routes (new RouteList),
139 _total_free_4k_blocks (0),
140 _bundles (new BundleList),
141 _bundle_xml_node (0),
144 click_emphasis_data (0),
146 _metadata (new SessionMetadata()),
147 _have_rec_enabled_diskstream (false)
152 if (!eng.connected()) {
153 throw failed_constructor();
156 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
158 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
159 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
161 first_stage_init (fullpath, snapshot_name);
163 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
166 if (create (new_session, mix_template, compute_initial_length())) {
168 throw failed_constructor ();
172 if (second_stage_init (new_session)) {
174 throw failed_constructor ();
177 store_recent_sessions(_name, _path);
179 bool was_dirty = dirty();
181 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
183 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
184 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
187 DirtyChanged (); /* EMIT SIGNAL */
191 Session::Session (AudioEngine &eng,
193 string snapshot_name,
194 AutoConnectOption input_ac,
195 AutoConnectOption output_ac,
196 uint32_t control_out_channels,
197 uint32_t master_out_channels,
198 uint32_t requested_physical_in,
199 uint32_t requested_physical_out,
200 nframes_t initial_length)
206 _requested_return_frame (-1),
207 _scratch_buffers(new BufferSet()),
208 _silent_buffers(new BufferSet()),
209 _mix_buffers(new BufferSet()),
211 _mmc_port (default_mmc_port),
212 _mtc_port (default_mtc_port),
213 _midi_port (default_midi_port),
214 _midi_clock_port (default_midi_clock_port),
215 _session_dir ( new SessionDirectory(fullpath)),
216 pending_events (2048),
218 butler_mixdown_buffer (0),
219 butler_gain_buffer (0),
220 post_transport_work((PostTransportWork)0),
221 _send_smpte_update (false),
222 midi_thread (pthread_t (0)),
224 diskstreams (new DiskstreamList),
225 routes (new RouteList),
226 _total_free_4k_blocks (0),
227 _bundles (new BundleList),
228 _bundle_xml_node (0),
229 _click_io ((IO *) 0),
231 click_emphasis_data (0),
233 _metadata (new SessionMetadata()),
234 _have_rec_enabled_diskstream (false)
238 if (!eng.connected()) {
239 throw failed_constructor();
242 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
244 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
245 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
247 if (n_physical_inputs) {
248 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
251 if (n_physical_outputs) {
252 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
255 first_stage_init (fullpath, snapshot_name);
257 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
260 if (create (new_session, string(), initial_length)) {
262 throw failed_constructor ();
267 /* set up Master Out and Control Out if necessary */
272 if (control_out_channels) {
273 ChanCount count(DataType::AUDIO, control_out_channels);
274 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
275 r->input()->ensure_io (count, false, this);
276 r->output()->ensure_io (count, false, this);
277 r->set_remote_control_id (control_id++);
282 if (master_out_channels) {
283 ChanCount count(DataType::AUDIO, master_out_channels);
284 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
285 r->input()->ensure_io (count, false, this);
286 r->output()->ensure_io (count, false, this);
287 r->set_remote_control_id (control_id);
291 /* prohibit auto-connect to master, because there isn't one */
292 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
296 add_routes (rl, false);
301 Config->set_input_auto_connect (input_ac);
302 Config->set_output_auto_connect (output_ac);
304 if (second_stage_init (new_session)) {
306 throw failed_constructor ();
309 store_recent_sessions (_name, _path);
311 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
313 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
324 /* if we got to here, leaving pending capture state around
328 remove_pending_capture_state ();
330 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
332 _engine.remove_session ();
334 GoingAway (); /* EMIT SIGNAL */
340 /* clear history so that no references to objects are held any more */
344 /* clear state tree so that no references to objects are held any more */
348 terminate_butler_thread ();
349 //terminate_midi_thread ();
351 if (click_data != default_click) {
352 delete [] click_data;
355 if (click_emphasis_data != default_click_emphasis) {
356 delete [] click_emphasis_data;
361 delete _scratch_buffers;
362 delete _silent_buffers;
365 AudioDiskstream::free_working_buffers();
367 Route::SyncOrderKeys.clear();
369 #undef TRACK_DESTRUCTION
370 #ifdef TRACK_DESTRUCTION
371 cerr << "delete named selections\n";
372 #endif /* TRACK_DESTRUCTION */
373 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
374 NamedSelectionList::iterator tmp;
383 #ifdef TRACK_DESTRUCTION
384 cerr << "delete playlists\n";
385 #endif /* TRACK_DESTRUCTION */
386 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
387 PlaylistList::iterator tmp;
392 (*i)->drop_references ();
397 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
398 PlaylistList::iterator tmp;
403 (*i)->drop_references ();
409 unused_playlists.clear ();
411 #ifdef TRACK_DESTRUCTION
412 cerr << "delete regions\n";
413 #endif /* TRACK_DESTRUCTION */
415 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
416 RegionList::iterator tmp;
421 i->second->drop_references ();
428 #ifdef TRACK_DESTRUCTION
429 cerr << "delete routes\n";
430 #endif /* TRACK_DESTRUCTION */
432 RCUWriter<RouteList> writer (routes);
433 boost::shared_ptr<RouteList> r = writer.get_copy ();
434 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
435 (*i)->drop_references ();
438 /* writer goes out of scope and updates master */
443 #ifdef TRACK_DESTRUCTION
444 cerr << "delete diskstreams\n";
445 #endif /* TRACK_DESTRUCTION */
447 RCUWriter<DiskstreamList> dwriter (diskstreams);
448 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
449 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
450 (*i)->drop_references ();
454 diskstreams.flush ();
456 #ifdef TRACK_DESTRUCTION
457 cerr << "delete audio sources\n";
458 #endif /* TRACK_DESTRUCTION */
459 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
460 SourceMap::iterator tmp;
465 i->second->drop_references ();
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete mix groups\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
475 list<RouteGroup*>::iterator tmp;
485 #ifdef TRACK_DESTRUCTION
486 cerr << "delete edit groups\n";
487 #endif /* TRACK_DESTRUCTION */
488 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
489 list<RouteGroup*>::iterator tmp;
499 delete [] butler_mixdown_buffer;
500 delete [] butler_gain_buffer;
502 Crossfade::set_buffer_size (0);
508 Session::set_worst_io_latencies ()
510 _worst_output_latency = 0;
511 _worst_input_latency = 0;
513 if (!_engine.connected()) {
517 boost::shared_ptr<RouteList> r = routes.reader ();
519 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
520 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
521 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
526 Session::when_engine_running ()
528 string first_physical_output;
530 BootMessage (_("Set block size and sample rate"));
532 set_block_size (_engine.frames_per_cycle());
533 set_frame_rate (_engine.frame_rate());
535 BootMessage (_("Using configuration"));
537 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
539 /* every time we reconnect, recompute worst case output latencies */
541 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
543 if (synced_to_jack()) {
544 _engine.transport_stop ();
547 if (config.get_jack_time_master()) {
548 _engine.transport_locate (_transport_frame);
556 _click_io.reset (new ClickIO (*this, "click"));
558 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
560 /* existing state for Click */
562 if (_click_io->set_state (*child->children().front()) == 0) {
564 _clicking = Config->get_clicking ();
568 error << _("could not setup Click I/O") << endmsg;
574 /* default state for Click: dual-mono to first 2 physical outputs */
576 for (int physport = 0; physport < 2; ++physport) {
577 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
579 if (physical_output.length()) {
580 if (_click_io->add_port (physical_output, this)) {
581 // relax, even though its an error
586 if (_click_io->n_ports () > ChanCount::ZERO) {
587 _clicking = Config->get_clicking ();
592 catch (failed_constructor& err) {
593 error << _("cannot setup Click I/O") << endmsg;
596 BootMessage (_("Compute I/O Latencies"));
598 set_worst_io_latencies ();
601 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
604 BootMessage (_("Set up standard connections"));
606 /* Create a set of Bundle objects that map
607 to the physical I/O currently available. We create both
608 mono and stereo bundles, so that the common cases of mono
609 and stereo tracks get bundles to put in their mixer strip
610 in / out menus. There may be a nicer way of achieving that;
611 it doesn't really scale that well to higher channel counts
614 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
616 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
618 shared_ptr<Bundle> c (new Bundle (buf, true));
619 c->add_channel (_("mono"));
620 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
625 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
626 if (np + 1 < n_physical_outputs) {
628 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
629 shared_ptr<Bundle> c (new Bundle (buf, true));
630 c->add_channel (_("L"));
631 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
632 c->add_channel (_("R"));
633 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
639 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
641 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
643 shared_ptr<Bundle> c (new Bundle (buf, false));
644 c->add_channel (_("mono"));
645 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
650 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
651 if (np + 1 < n_physical_inputs) {
653 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
655 shared_ptr<Bundle> c (new Bundle (buf, false));
656 c->add_channel (_("L"));
657 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
658 c->add_channel (_("R"));
659 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
665 /* create master/control ports */
669 /* if requested auto-connect the outputs to the first N physical ports.
672 if (Config->get_auto_connect_master()) {
673 uint32_t limit = _master_out->n_outputs().n_total();
675 for (uint32_t n = 0; n < limit; ++n) {
676 Port* p = _master_out->output()->nth (n);
677 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
679 if (!connect_to.empty()) {
680 if (_master_out->output()->connect (p, connect_to, this)) {
681 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
690 BootMessage (_("Setup signal flow and plugins"));
694 /* catch up on send+insert cnts */
696 BootMessage (_("Catch up with send/insert state"));
700 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
703 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
704 if (id > insert_cnt) {
712 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
715 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
723 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
725 /* hook us up to the engine */
727 BootMessage (_("Connect to engine"));
729 _engine.set_session (this);
733 Session::hookup_io ()
735 /* stop graph reordering notifications from
736 causing resorts, etc.
739 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
744 /* we delay creating the auditioner till now because
745 it makes its own connections to ports.
746 the engine has to be running for this to work.
750 auditioner.reset (new Auditioner (*this));
753 catch (failed_constructor& err) {
754 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
758 /* Connect track to listen/solo etc. busses XXX generalize this beyond control_out */
762 // _control_out->ensure_io (_control_out->input_minimum(), _control_out->output_minimum(), false, this);
764 boost::shared_ptr<RouteList> r = routes.reader ();
766 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
768 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
771 t->listen_via (_control_out->input(), X_("listen"));
776 /* load bundles, which we may have postponed earlier on */
777 if (_bundle_xml_node) {
778 load_bundles (*_bundle_xml_node);
779 delete _bundle_xml_node;
782 /* Tell all IO objects to connect themselves together */
784 IO::enable_connecting ();
786 /* Now reset all panners */
788 Delivery::reset_panners ();
790 /* Anyone who cares about input state, wake up and do something */
792 IOConnectionsComplete (); /* EMIT SIGNAL */
794 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
797 /* now handle the whole enchilada as if it was one
803 /* update mixer solo state */
809 Session::playlist_length_changed ()
811 /* we can't just increase end_location->end() if pl->get_maximum_extent()
812 if larger. if the playlist used to be the longest playlist,
813 and its now shorter, we have to decrease end_location->end(). hence,
814 we have to iterate over all diskstreams and check the
815 playlists currently in use.
821 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
823 boost::shared_ptr<Playlist> playlist;
825 if ((playlist = dstream->playlist()) != 0) {
826 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
829 /* see comment in playlist_length_changed () */
834 Session::record_enabling_legal () const
836 /* this used to be in here, but survey says.... we don't need to restrict it */
837 // if (record_status() == Recording) {
841 if (Config->get_all_safe()) {
848 Session::reset_input_monitor_state ()
850 if (transport_rolling()) {
852 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
854 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
855 if ((*i)->record_enabled ()) {
856 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
857 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
861 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
863 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
864 if ((*i)->record_enabled ()) {
865 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
866 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
873 Session::auto_punch_start_changed (Location* location)
875 replace_event (Event::PunchIn, location->start());
877 if (get_record_enabled() && config.get_punch_in()) {
878 /* capture start has been changed, so save new pending state */
879 save_state ("", true);
884 Session::auto_punch_end_changed (Location* location)
886 nframes_t when_to_stop = location->end();
887 // when_to_stop += _worst_output_latency + _worst_input_latency;
888 replace_event (Event::PunchOut, when_to_stop);
892 Session::auto_punch_changed (Location* location)
894 nframes_t when_to_stop = location->end();
896 replace_event (Event::PunchIn, location->start());
897 //when_to_stop += _worst_output_latency + _worst_input_latency;
898 replace_event (Event::PunchOut, when_to_stop);
902 Session::auto_loop_changed (Location* location)
904 replace_event (Event::AutoLoop, location->end(), location->start());
906 if (transport_rolling() && play_loop) {
908 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
910 if (_transport_frame > location->end()) {
911 // relocate to beginning of loop
912 clear_events (Event::LocateRoll);
914 request_locate (location->start(), true);
917 else if (Config->get_seamless_loop() && !loop_changing) {
919 // schedule a locate-roll to refill the diskstreams at the
921 loop_changing = true;
923 if (location->end() > last_loopend) {
924 clear_events (Event::LocateRoll);
925 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
932 last_loopend = location->end();
936 Session::set_auto_punch_location (Location* location)
940 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
941 auto_punch_start_changed_connection.disconnect();
942 auto_punch_end_changed_connection.disconnect();
943 auto_punch_changed_connection.disconnect();
944 existing->set_auto_punch (false, this);
945 remove_event (existing->start(), Event::PunchIn);
946 clear_events (Event::PunchOut);
947 auto_punch_location_changed (0);
956 if (location->end() <= location->start()) {
957 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
961 auto_punch_start_changed_connection.disconnect();
962 auto_punch_end_changed_connection.disconnect();
963 auto_punch_changed_connection.disconnect();
965 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
966 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
967 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
969 location->set_auto_punch (true, this);
972 auto_punch_changed (location);
974 auto_punch_location_changed (location);
978 Session::set_auto_loop_location (Location* location)
982 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
983 auto_loop_start_changed_connection.disconnect();
984 auto_loop_end_changed_connection.disconnect();
985 auto_loop_changed_connection.disconnect();
986 existing->set_auto_loop (false, this);
987 remove_event (existing->end(), Event::AutoLoop);
988 auto_loop_location_changed (0);
997 if (location->end() <= location->start()) {
998 error << _("Session: you can't use a mark for auto loop") << endmsg;
1002 last_loopend = location->end();
1004 auto_loop_start_changed_connection.disconnect();
1005 auto_loop_end_changed_connection.disconnect();
1006 auto_loop_changed_connection.disconnect();
1008 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1009 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1010 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1012 location->set_auto_loop (true, this);
1014 /* take care of our stuff first */
1016 auto_loop_changed (location);
1018 /* now tell everyone else */
1020 auto_loop_location_changed (location);
1024 Session::locations_added (Location* ignored)
1030 Session::locations_changed ()
1032 _locations.apply (*this, &Session::handle_locations_changed);
1036 Session::handle_locations_changed (Locations::LocationList& locations)
1038 Locations::LocationList::iterator i;
1040 bool set_loop = false;
1041 bool set_punch = false;
1043 for (i = locations.begin(); i != locations.end(); ++i) {
1047 if (location->is_auto_punch()) {
1048 set_auto_punch_location (location);
1051 if (location->is_auto_loop()) {
1052 set_auto_loop_location (location);
1056 if (location->is_start()) {
1057 start_location = location;
1059 if (location->is_end()) {
1060 end_location = location;
1065 set_auto_loop_location (0);
1068 set_auto_punch_location (0);
1075 Session::enable_record ()
1077 /* XXX really atomic compare+swap here */
1078 if (g_atomic_int_get (&_record_status) != Recording) {
1079 g_atomic_int_set (&_record_status, Recording);
1080 _last_record_location = _transport_frame;
1081 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1083 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1084 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1085 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1086 if ((*i)->record_enabled ()) {
1087 (*i)->monitor_input (true);
1092 RecordStateChanged ();
1097 Session::disable_record (bool rt_context, bool force)
1101 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1103 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1104 g_atomic_int_set (&_record_status, Disabled);
1106 if (rs == Recording) {
1107 g_atomic_int_set (&_record_status, Enabled);
1111 // FIXME: timestamp correct? [DR]
1112 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1113 // does this /need/ to be sent in all cases?
1115 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1117 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1118 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1120 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1121 if ((*i)->record_enabled ()) {
1122 (*i)->monitor_input (false);
1127 RecordStateChanged (); /* emit signal */
1130 remove_pending_capture_state ();
1136 Session::step_back_from_record ()
1138 /* XXX really atomic compare+swap here */
1139 if (g_atomic_int_get (&_record_status) == Recording) {
1140 g_atomic_int_set (&_record_status, Enabled);
1142 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1143 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1145 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1146 if ((*i)->record_enabled ()) {
1147 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1148 (*i)->monitor_input (false);
1156 Session::maybe_enable_record ()
1158 g_atomic_int_set (&_record_status, Enabled);
1160 /* this function is currently called from somewhere other than an RT thread.
1161 this save_state() call therefore doesn't impact anything.
1164 save_state ("", true);
1166 if (_transport_speed) {
1167 if (!config.get_punch_in()) {
1171 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1172 RecordStateChanged (); /* EMIT SIGNAL */
1179 Session::audible_frame () const
1185 /* the first of these two possible settings for "offset"
1186 mean that the audible frame is stationary until
1187 audio emerges from the latency compensation
1190 the second means that the audible frame is stationary
1191 until audio would emerge from a physical port
1192 in the absence of any plugin latency compensation
1195 offset = _worst_output_latency;
1197 if (offset > current_block_size) {
1198 offset -= current_block_size;
1200 /* XXX is this correct? if we have no external
1201 physical connections and everything is internal
1202 then surely this is zero? still, how
1203 likely is that anyway?
1205 offset = current_block_size;
1208 if (synced_to_jack()) {
1209 tf = _engine.transport_frame();
1211 tf = _transport_frame;
1216 if (!non_realtime_work_pending()) {
1220 /* check to see if we have passed the first guaranteed
1221 audible frame past our last start position. if not,
1222 return that last start point because in terms
1223 of audible frames, we have not moved yet.
1226 if (_transport_speed > 0.0f) {
1228 if (!play_loop || !have_looped) {
1229 if (tf < _last_roll_location + offset) {
1230 return _last_roll_location;
1238 } else if (_transport_speed < 0.0f) {
1240 /* XXX wot? no backward looping? */
1242 if (tf > _last_roll_location - offset) {
1243 return _last_roll_location;
1255 Session::set_frame_rate (nframes_t frames_per_second)
1257 /** \fn void Session::set_frame_size(nframes_t)
1258 the AudioEngine object that calls this guarantees
1259 that it will not be called while we are also in
1260 ::process(). Its fine to do things that block
1264 _base_frame_rate = frames_per_second;
1268 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1272 // XXX we need some equivalent to this, somehow
1273 // SndFileSource::setup_standard_crossfades (frames_per_second);
1277 /* XXX need to reset/reinstantiate all LADSPA plugins */
1281 Session::set_block_size (nframes_t nframes)
1283 /* the AudioEngine guarantees
1284 that it will not be called while we are also in
1285 ::process(). It is therefore fine to do things that block
1290 current_block_size = nframes;
1292 ensure_buffers(_scratch_buffers->available());
1294 delete [] _gain_automation_buffer;
1295 _gain_automation_buffer = new gain_t[nframes];
1297 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1299 boost::shared_ptr<RouteList> r = routes.reader ();
1301 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1302 (*i)->set_block_size (nframes);
1305 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1306 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1307 (*i)->set_block_size (nframes);
1310 set_worst_io_latencies ();
1315 Session::set_default_fade (float steepness, float fade_msecs)
1318 nframes_t fade_frames;
1320 /* Don't allow fade of less 1 frame */
1322 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1329 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1333 default_fade_msecs = fade_msecs;
1334 default_fade_steepness = steepness;
1337 // jlc, WTF is this!
1338 Glib::RWLock::ReaderLock lm (route_lock);
1339 AudioRegion::set_default_fade (steepness, fade_frames);
1344 /* XXX have to do this at some point */
1345 /* foreach region using default fade, reset, then
1346 refill_all_diskstream_buffers ();
1351 struct RouteSorter {
1352 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1353 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1355 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1358 if (r1->fed_by.empty()) {
1359 if (r2->fed_by.empty()) {
1360 /* no ardour-based connections inbound to either route. just use signal order */
1361 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1363 /* r2 has connections, r1 does not; run r1 early */
1367 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1374 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1376 shared_ptr<Route> r2;
1378 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1379 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1383 /* make a copy of the existing list of routes that feed r1 */
1385 set<shared_ptr<Route> > existing = r1->fed_by;
1387 /* for each route that feeds r1, recurse, marking it as feeding
1391 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1394 /* r2 is a route that feeds r1 which somehow feeds base. mark
1395 base as being fed by r2
1398 rbase->fed_by.insert (r2);
1402 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1406 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1410 /* now recurse, so that we can mark base as being fed by
1411 all routes that feed r2
1414 trace_terminal (r2, rbase);
1421 Session::resort_routes ()
1423 /* don't do anything here with signals emitted
1424 by Routes while we are being destroyed.
1427 if (_state_of_the_state & Deletion) {
1434 RCUWriter<RouteList> writer (routes);
1435 shared_ptr<RouteList> r = writer.get_copy ();
1436 resort_routes_using (r);
1437 /* writer goes out of scope and forces update */
1442 Session::resort_routes_using (shared_ptr<RouteList> r)
1444 RouteList::iterator i, j;
1446 for (i = r->begin(); i != r->end(); ++i) {
1448 (*i)->fed_by.clear ();
1450 for (j = r->begin(); j != r->end(); ++j) {
1452 /* although routes can feed themselves, it will
1453 cause an endless recursive descent if we
1454 detect it. so don't bother checking for
1462 if ((*j)->feeds ((*i)->input())) {
1463 (*i)->fed_by.insert (*j);
1468 for (i = r->begin(); i != r->end(); ++i) {
1469 trace_terminal (*i, *i);
1476 cerr << "finished route resort\n";
1478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1479 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1486 list<boost::shared_ptr<MidiTrack> >
1487 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1489 char track_name[32];
1490 uint32_t track_id = 0;
1493 RouteList new_routes;
1494 list<boost::shared_ptr<MidiTrack> > ret;
1495 //uint32_t control_id;
1497 // FIXME: need physical I/O and autoconnect stuff for MIDI
1499 /* count existing midi tracks */
1502 shared_ptr<RouteList> r = routes.reader ();
1504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1505 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1506 if (!(*i)->is_hidden()) {
1508 //channels_used += (*i)->n_inputs().n_midi();
1514 vector<string> physinputs;
1515 vector<string> physoutputs;
1517 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1518 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1520 // control_id = ntracks() + nbusses();
1524 /* check for duplicate route names, since we might have pre-existing
1525 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1526 save, close,restart,add new route - first named route is now
1534 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1536 if (route_by_name (track_name) == 0) {
1540 } while (track_id < (UINT_MAX-1));
1542 shared_ptr<MidiTrack> track;
1545 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1547 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1548 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1553 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1554 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1560 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1564 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1565 port = physinputs[(channels_used+x)%nphysical_in];
1568 if (port.length() && track->connect_input (track->input (x), port, this)) {
1574 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1578 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1579 port = physoutputs[(channels_used+x)%nphysical_out];
1580 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1582 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1586 if (port.length() && track->connect_output (track->output (x), port, this)) {
1591 channels_used += track->n_inputs ().n_midi();
1595 track->midi_diskstream()->non_realtime_input_change();
1597 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1598 //track->set_remote_control_id (control_id);
1600 new_routes.push_back (track);
1601 ret.push_back (track);
1604 catch (failed_constructor &err) {
1605 error << _("Session: could not create new midi track.") << endmsg;
1608 /* we need to get rid of this, since the track failed to be created */
1609 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1612 RCUWriter<DiskstreamList> writer (diskstreams);
1613 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1614 ds->remove (track->midi_diskstream());
1621 catch (AudioEngine::PortRegistrationFailure& pfe) {
1623 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;
1626 /* we need to get rid of this, since the track failed to be created */
1627 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1630 RCUWriter<DiskstreamList> writer (diskstreams);
1631 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1632 ds->remove (track->midi_diskstream());
1643 if (!new_routes.empty()) {
1644 add_routes (new_routes, false);
1645 save_state (_current_snapshot_name);
1651 list<boost::shared_ptr<AudioTrack> >
1652 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1654 char track_name[32];
1655 uint32_t track_id = 0;
1657 uint32_t channels_used = 0;
1659 RouteList new_routes;
1660 list<boost::shared_ptr<AudioTrack> > ret;
1661 uint32_t control_id;
1663 /* count existing audio tracks */
1666 shared_ptr<RouteList> r = routes.reader ();
1668 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1669 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1670 if (!(*i)->is_hidden()) {
1672 channels_used += (*i)->n_inputs().n_audio();
1678 vector<string> physinputs;
1679 vector<string> physoutputs;
1681 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1682 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1684 control_id = ntracks() + nbusses() + 1;
1688 /* check for duplicate route names, since we might have pre-existing
1689 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1690 save, close,restart,add new route - first named route is now
1698 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1700 if (route_by_name (track_name) == 0) {
1704 } while (track_id < (UINT_MAX-1));
1706 shared_ptr<AudioTrack> track;
1709 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1711 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1712 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1713 input_channels, output_channels)
1718 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1719 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1720 input_channels, output_channels)
1725 if (!physinputs.empty()) {
1726 uint32_t nphysical_in = physinputs.size();
1728 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1732 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1733 port = physinputs[(channels_used+x)%nphysical_in];
1736 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1742 if (!physoutputs.empty()) {
1743 uint32_t nphysical_out = physoutputs.size();
1745 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1748 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1749 port = physoutputs[(channels_used+x)%nphysical_out];
1750 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1751 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1752 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1756 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1762 channels_used += track->n_inputs ().n_audio();
1764 track->audio_diskstream()->non_realtime_input_change();
1766 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1767 track->set_remote_control_id (control_id);
1770 new_routes.push_back (track);
1771 ret.push_back (track);
1774 catch (failed_constructor &err) {
1775 error << _("Session: could not create new audio track.") << endmsg;
1778 /* we need to get rid of this, since the track failed to be created */
1779 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1782 RCUWriter<DiskstreamList> writer (diskstreams);
1783 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1784 ds->remove (track->audio_diskstream());
1791 catch (AudioEngine::PortRegistrationFailure& pfe) {
1793 error << pfe.what() << endmsg;
1796 /* we need to get rid of this, since the track failed to be created */
1797 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1800 RCUWriter<DiskstreamList> writer (diskstreams);
1801 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1802 ds->remove (track->audio_diskstream());
1813 if (!new_routes.empty()) {
1814 add_routes (new_routes, true);
1821 Session::set_remote_control_ids ()
1823 RemoteModel m = Config->get_remote_model();
1825 shared_ptr<RouteList> r = routes.reader ();
1827 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1828 if ( MixerOrdered == m) {
1829 long order = (*i)->order_key(N_("signal"));
1830 (*i)->set_remote_control_id( order+1 );
1831 } else if ( EditorOrdered == m) {
1832 long order = (*i)->order_key(N_("editor"));
1833 (*i)->set_remote_control_id( order+1 );
1834 } else if ( UserOrdered == m) {
1835 //do nothing ... only changes to remote id's are initiated by user
1842 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1845 uint32_t bus_id = 1;
1847 uint32_t channels_used = 0;
1850 uint32_t control_id;
1852 /* count existing audio busses */
1855 shared_ptr<RouteList> r = routes.reader ();
1857 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1858 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1860 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1863 channels_used += (*i)->n_inputs().n_audio();
1869 vector<string> physinputs;
1870 vector<string> physoutputs;
1872 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1873 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1875 n_physical_audio_outputs = physoutputs.size();
1876 n_physical_audio_inputs = physinputs.size();
1878 control_id = ntracks() + nbusses() + 1;
1883 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1887 if (route_by_name (bus_name) == 0) {
1891 } while (bus_id < (UINT_MAX-1));
1894 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1896 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1897 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1898 input_channels, output_channels)
1904 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1905 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1906 input_channels, output_channels)
1914 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1918 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1919 port = physinputs[((n+x)%n_physical_audio_inputs)];
1922 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1928 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1931 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1932 port = physoutputs[((n+x)%n_physical_outputs)];
1933 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1935 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1939 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1944 channels_used += bus->n_inputs ().n_audio();
1946 bus->set_remote_control_id (control_id);
1949 ret.push_back (bus);
1953 catch (failed_constructor &err) {
1954 error << _("Session: could not create new audio route.") << endmsg;
1958 catch (AudioEngine::PortRegistrationFailure& pfe) {
1959 error << pfe.what() << endmsg;
1969 add_routes (ret, true);
1977 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1981 uint32_t control_id;
1984 if (!tree.read (template_path.c_str())) {
1988 XMLNode* node = tree.root();
1990 control_id = ntracks() + nbusses() + 1;
1994 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1996 std::string node_name = IO::name_from_state (*node_copy.children().front());
1998 if (route_by_name (node_name) != 0) {
2000 /* generate a new name by adding a number to the end of the template name */
2002 uint32_t number = 1;
2005 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2009 if (route_by_name (name) == 0) {
2013 } while (number < UINT_MAX);
2015 if (number == UINT_MAX) {
2016 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2020 IO::set_name_in_state (*node_copy.children().front(), name);
2023 Track::zero_diskstream_id_in_xml (node_copy);
2026 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2029 error << _("Session: cannot create track/bus from template description") << endmsg;
2033 if (boost::dynamic_pointer_cast<Track>(route)) {
2034 /* force input/output change signals so that the new diskstream
2035 picks up the configuration of the route. During session
2036 loading this normally happens in a different way.
2038 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2039 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2042 route->set_remote_control_id (control_id);
2045 ret.push_back (route);
2048 catch (failed_constructor &err) {
2049 error << _("Session: could not create new route from template") << endmsg;
2053 catch (AudioEngine::PortRegistrationFailure& pfe) {
2054 error << pfe.what() << endmsg;
2063 add_routes (ret, true);
2070 Session::add_routes (RouteList& new_routes, bool save)
2073 RCUWriter<RouteList> writer (routes);
2074 shared_ptr<RouteList> r = writer.get_copy ();
2075 r->insert (r->end(), new_routes.begin(), new_routes.end());
2076 resort_routes_using (r);
2079 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2081 boost::weak_ptr<Route> wpr (*x);
2083 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2084 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2085 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2086 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2088 if ((*x)->is_master()) {
2092 if ((*x)->is_control()) {
2093 _control_out = (*x);
2097 if (_control_out && IO::connecting_legal) {
2099 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2100 (*x)->listen_via (_control_out->input(), "control");
2107 save_state (_current_snapshot_name);
2110 RouteAdded (new_routes); /* EMIT SIGNAL */
2114 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2116 /* need to do this in case we're rolling at the time, to prevent false underruns */
2117 dstream->do_refill_with_alloc ();
2119 dstream->set_block_size (current_block_size);
2122 RCUWriter<DiskstreamList> writer (diskstreams);
2123 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2124 ds->push_back (dstream);
2125 /* writer goes out of scope, copies ds back to main */
2128 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2129 /* this will connect to future changes, and check the current length */
2130 diskstream_playlist_changed (dstream);
2132 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2134 dstream->prepare ();
2139 Session::remove_route (shared_ptr<Route> route)
2142 RCUWriter<RouteList> writer (routes);
2143 shared_ptr<RouteList> rs = writer.get_copy ();
2147 /* deleting the master out seems like a dumb
2148 idea, but its more of a UI policy issue
2152 if (route == _master_out) {
2153 _master_out = shared_ptr<Route> ();
2156 if (route == _control_out) {
2157 /* cancel control outs for all routes */
2159 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2160 (*r)->drop_listen (_control_out->input());
2163 _control_out = shared_ptr<Route> ();
2166 update_route_solo_state ();
2168 /* writer goes out of scope, forces route list update */
2171 boost::shared_ptr<Track> t;
2172 boost::shared_ptr<Diskstream> ds;
2174 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2175 ds = t->diskstream();
2181 RCUWriter<DiskstreamList> dsl (diskstreams);
2182 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2187 find_current_end ();
2189 // We need to disconnect the routes inputs and outputs
2191 route->input()->disconnect (0);
2192 route->output()->disconnect (0);
2194 update_latency_compensation (false, false);
2197 /* get rid of it from the dead wood collection in the route list manager */
2199 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2203 /* try to cause everyone to drop their references */
2205 route->drop_references ();
2207 sync_order_keys (N_("session"));
2209 /* save the new state of the world */
2211 if (save_state (_current_snapshot_name)) {
2212 save_history (_current_snapshot_name);
2217 Session::route_mute_changed (void* src)
2223 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2225 if (solo_update_disabled) {
2230 boost::shared_ptr<Route> route = wpr.lock ();
2233 /* should not happen */
2234 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2238 shared_ptr<RouteList> r = routes.reader ();
2241 if (route->soloed()) {
2247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 if ((*i)->feeds (route->input())) {
2251 solo_update_disabled = true;
2252 (*i)->main_outs()->mod_solo_level (delta);
2253 solo_update_disabled = false;
2257 /* now figure out if anything is soloed */
2259 bool something_soloed = false;
2261 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2262 if ((*i)->soloed()) {
2263 something_soloed = true;
2268 if (something_soloed != _non_soloed_outs_muted) {
2269 _non_soloed_outs_muted = something_soloed;
2270 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2273 SoloChanged (); /* EMIT SIGNAL */
2279 Session::update_route_solo_state ()
2282 bool is_track = false;
2283 bool signal = false;
2285 /* this is where we actually implement solo by changing
2286 the solo mute setting of each track.
2289 shared_ptr<RouteList> r = routes.reader ();
2291 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2292 if ((*i)->soloed()) {
2294 if (boost::dynamic_pointer_cast<Track>(*i)) {
2301 if (mute != currently_soloing) {
2303 currently_soloing = mute;
2306 if (!is_track && !mute) {
2308 /* nothing is soloed */
2318 SoloActive (currently_soloing);
2324 Session::catch_up_on_solo ()
2326 /* this is called after set_state() to catch the full solo
2327 state, which can't be correctly determined on a per-route
2328 basis, but needs the global overview that only the session
2331 update_route_solo_state();
2335 Session::catch_up_on_solo_mute_override ()
2337 if (Config->get_solo_model() != InverseMute) {
2341 /* this is called whenever the param solo-mute-override is
2344 shared_ptr<RouteList> r = routes.reader ();
2346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2347 // (*i)->catch_up_on_solo_mute_override ();
2352 Session::route_by_name (string name)
2354 shared_ptr<RouteList> r = routes.reader ();
2356 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2357 if ((*i)->name() == name) {
2362 return shared_ptr<Route> ((Route*) 0);
2366 Session::route_by_id (PBD::ID id)
2368 shared_ptr<RouteList> r = routes.reader ();
2370 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2371 if ((*i)->id() == id) {
2376 return shared_ptr<Route> ((Route*) 0);
2380 Session::route_by_remote_id (uint32_t id)
2382 shared_ptr<RouteList> r = routes.reader ();
2384 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2385 if ((*i)->remote_control_id() == id) {
2390 return shared_ptr<Route> ((Route*) 0);
2394 Session::find_current_end ()
2396 if (_state_of_the_state & Loading) {
2400 nframes_t max = get_maximum_extent ();
2402 if (max > end_location->end()) {
2403 end_location->set_end (max);
2405 DurationChanged(); /* EMIT SIGNAL */
2410 Session::get_maximum_extent () const
2415 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2417 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2418 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2420 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2421 if ((me = pl->get_maximum_extent()) > max) {
2429 boost::shared_ptr<Diskstream>
2430 Session::diskstream_by_name (string name)
2432 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2434 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2435 if ((*i)->name() == name) {
2440 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2443 boost::shared_ptr<Diskstream>
2444 Session::diskstream_by_id (const PBD::ID& id)
2446 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2448 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2449 if ((*i)->id() == id) {
2454 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2457 /* Region management */
2460 Session::new_region_name (string old)
2462 string::size_type last_period;
2464 string::size_type len = old.length() + 64;
2467 if ((last_period = old.find_last_of ('.')) == string::npos) {
2469 /* no period present - add one explicitly */
2472 last_period = old.length() - 1;
2477 number = atoi (old.substr (last_period+1).c_str());
2481 while (number < (UINT_MAX-1)) {
2483 RegionList::const_iterator i;
2488 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2491 for (i = regions.begin(); i != regions.end(); ++i) {
2492 if (i->second->name() == sbuf) {
2497 if (i == regions.end()) {
2502 if (number != (UINT_MAX-1)) {
2506 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2511 Session::region_name (string& result, string base, bool newlevel)
2516 if (base.find("/") != string::npos) {
2517 base = base.substr(base.find_last_of("/") + 1);
2522 Glib::Mutex::Lock lm (region_lock);
2524 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2533 string::size_type pos;
2535 pos = base.find_last_of ('.');
2537 /* pos may be npos, but then we just use entire base */
2539 subbase = base.substr (0, pos);
2544 Glib::Mutex::Lock lm (region_lock);
2546 map<string,uint32_t>::iterator x;
2550 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2552 region_name_map[subbase] = 1;
2555 snprintf (buf, sizeof (buf), ".%d", x->second);
2566 Session::add_region (boost::shared_ptr<Region> region)
2568 vector<boost::shared_ptr<Region> > v;
2569 v.push_back (region);
2574 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2579 Glib::Mutex::Lock lm (region_lock);
2581 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2583 boost::shared_ptr<Region> region = *ii;
2587 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2591 RegionList::iterator x;
2593 for (x = regions.begin(); x != regions.end(); ++x) {
2595 if (region->region_list_equivalent (x->second)) {
2600 if (x == regions.end()) {
2602 pair<RegionList::key_type,RegionList::mapped_type> entry;
2604 entry.first = region->id();
2605 entry.second = region;
2607 pair<RegionList::iterator,bool> x = regions.insert (entry);
2619 /* mark dirty because something has changed even if we didn't
2620 add the region to the region list.
2627 vector<boost::weak_ptr<Region> > v;
2628 boost::shared_ptr<Region> first_r;
2630 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2632 boost::shared_ptr<Region> region = *ii;
2636 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2639 v.push_back (region);
2646 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2647 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2649 update_region_name_map (region);
2653 RegionsAdded (v); /* EMIT SIGNAL */
2659 Session::update_region_name_map (boost::shared_ptr<Region> region)
2661 string::size_type last_period = region->name().find_last_of ('.');
2663 if (last_period != string::npos && last_period < region->name().length() - 1) {
2665 string base = region->name().substr (0, last_period);
2666 string number = region->name().substr (last_period+1);
2667 map<string,uint32_t>::iterator x;
2669 /* note that if there is no number, we get zero from atoi,
2673 region_name_map[base] = atoi (number);
2678 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2680 boost::shared_ptr<Region> region (weak_region.lock ());
2686 if (what_changed & Region::HiddenChanged) {
2687 /* relay hidden changes */
2688 RegionHiddenChange (region);
2691 if (what_changed & NameChanged) {
2692 update_region_name_map (region);
2697 Session::remove_region (boost::weak_ptr<Region> weak_region)
2699 RegionList::iterator i;
2700 boost::shared_ptr<Region> region (weak_region.lock ());
2706 bool removed = false;
2709 Glib::Mutex::Lock lm (region_lock);
2711 if ((i = regions.find (region->id())) != regions.end()) {
2717 /* mark dirty because something has changed even if we didn't
2718 remove the region from the region list.
2724 RegionRemoved(region); /* EMIT SIGNAL */
2728 boost::shared_ptr<Region>
2729 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2731 RegionList::iterator i;
2732 boost::shared_ptr<Region> region;
2734 Glib::Mutex::Lock lm (region_lock);
2736 for (i = regions.begin(); i != regions.end(); ++i) {
2740 if (region->whole_file()) {
2742 if (child->source_equivalent (region)) {
2748 return boost::shared_ptr<Region> ();
2752 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2754 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2755 (*i)->get_region_list_equivalent_regions (region, result);
2759 Session::destroy_region (boost::shared_ptr<Region> region)
2761 vector<boost::shared_ptr<Source> > srcs;
2764 if (region->playlist()) {
2765 region->playlist()->destroy_region (region);
2768 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2769 srcs.push_back (region->source (n));
2773 region->drop_references ();
2775 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2777 (*i)->mark_for_remove ();
2778 (*i)->drop_references ();
2780 cerr << "source was not used by any playlist\n";
2787 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2789 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2790 destroy_region (*i);
2796 Session::remove_last_capture ()
2798 list<boost::shared_ptr<Region> > r;
2800 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2802 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2803 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2806 r.insert (r.end(), l.begin(), l.end());
2811 destroy_regions (r);
2813 save_state (_current_snapshot_name);
2819 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2825 /* Source Management */
2828 Session::add_source (boost::shared_ptr<Source> source)
2830 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2831 pair<SourceMap::iterator,bool> result;
2833 entry.first = source->id();
2834 entry.second = source;
2837 Glib::Mutex::Lock lm (source_lock);
2838 result = sources.insert (entry);
2841 if (result.second) {
2842 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2846 boost::shared_ptr<AudioFileSource> afs;
2848 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2849 if (Config->get_auto_analyse_audio()) {
2850 Analyser::queue_source_for_analysis (source, false);
2856 Session::remove_source (boost::weak_ptr<Source> src)
2858 SourceMap::iterator i;
2859 boost::shared_ptr<Source> source = src.lock();
2866 Glib::Mutex::Lock lm (source_lock);
2868 if ((i = sources.find (source->id())) != sources.end()) {
2873 if (!_state_of_the_state & InCleanup) {
2875 /* save state so we don't end up with a session file
2876 referring to non-existent sources.
2879 save_state (_current_snapshot_name);
2883 boost::shared_ptr<Source>
2884 Session::source_by_id (const PBD::ID& id)
2886 Glib::Mutex::Lock lm (source_lock);
2887 SourceMap::iterator i;
2888 boost::shared_ptr<Source> source;
2890 if ((i = sources.find (id)) != sources.end()) {
2897 boost::shared_ptr<Source>
2898 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2900 Glib::Mutex::Lock lm (source_lock);
2902 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2903 cerr << "comparing " << path << " with " << i->second->name() << endl;
2904 boost::shared_ptr<AudioFileSource> afs
2905 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2907 if (afs && afs->path() == path && chn == afs->channel()) {
2911 return boost::shared_ptr<Source>();
2916 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2919 string old_basename = PBD::basename_nosuffix (oldname);
2920 string new_legalized = legalize_for_path (newname);
2922 /* note: we know (or assume) the old path is already valid */
2926 /* destructive file sources have a name of the form:
2928 /path/to/Tnnnn-NAME(%[LR])?.wav
2930 the task here is to replace NAME with the new name.
2933 /* find last slash */
2937 string::size_type slash;
2938 string::size_type dash;
2940 if ((slash = path.find_last_of ('/')) == string::npos) {
2944 dir = path.substr (0, slash+1);
2946 /* '-' is not a legal character for the NAME part of the path */
2948 if ((dash = path.find_last_of ('-')) == string::npos) {
2952 prefix = path.substr (slash+1, dash-(slash+1));
2957 path += new_legalized;
2958 path += ".wav"; /* XXX gag me with a spoon */
2962 /* non-destructive file sources have a name of the form:
2964 /path/to/NAME-nnnnn(%[LR])?.ext
2966 the task here is to replace NAME with the new name.
2971 string::size_type slash;
2972 string::size_type dash;
2973 string::size_type postfix;
2975 /* find last slash */
2977 if ((slash = path.find_last_of ('/')) == string::npos) {
2981 dir = path.substr (0, slash+1);
2983 /* '-' is not a legal character for the NAME part of the path */
2985 if ((dash = path.find_last_of ('-')) == string::npos) {
2989 suffix = path.substr (dash+1);
2991 // Suffix is now everything after the dash. Now we need to eliminate
2992 // the nnnnn part, which is done by either finding a '%' or a '.'
2994 postfix = suffix.find_last_of ("%");
2995 if (postfix == string::npos) {
2996 postfix = suffix.find_last_of ('.');
2999 if (postfix != string::npos) {
3000 suffix = suffix.substr (postfix);
3002 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3006 const uint32_t limit = 10000;
3007 char buf[PATH_MAX+1];
3009 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3011 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3013 if (access (buf, F_OK) != 0) {
3021 error << "FATAL ERROR! Could not find a " << endl;
3029 /** Return the full path (in some session directory) for a new embedded source.
3030 * \a name must be a session-unique name that does not contain slashes
3031 * (e.g. as returned by new_*_source_name)
3034 Session::new_source_path_from_name (DataType type, const string& name)
3036 assert(name.find("/") == string::npos);
3038 SessionDirectory sdir(get_best_session_directory_for_new_source());
3041 if (type == DataType::AUDIO) {
3042 p = sdir.sound_path();
3043 } else if (type == DataType::MIDI) {
3044 p = sdir.midi_path();
3046 error << "Unknown source type, unable to create file path" << endmsg;
3051 return p.to_string();
3055 Session::peak_path (Glib::ustring base) const
3057 sys::path peakfile_path(_session_dir->peak_path());
3058 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3059 return peakfile_path.to_string();
3062 /** Return a unique name based on \a base for a new internal audio source */
3064 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3068 char buf[PATH_MAX+1];
3069 const uint32_t limit = 10000;
3073 legalized = legalize_for_path (base);
3075 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3076 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3078 vector<space_and_path>::iterator i;
3079 uint32_t existing = 0;
3081 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3083 SessionDirectory sdir((*i).path);
3085 spath = sdir.sound_path().to_string();
3090 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3091 spath.c_str(), cnt, legalized.c_str());
3092 } else if (nchan == 2) {
3094 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3095 spath.c_str(), cnt, legalized.c_str());
3097 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3098 spath.c_str(), cnt, legalized.c_str());
3100 } else if (nchan < 26) {
3101 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3102 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3104 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3105 spath.c_str(), cnt, legalized.c_str());
3114 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3115 } else if (nchan == 2) {
3117 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3119 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3121 } else if (nchan < 26) {
3122 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3124 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3128 if (sys::exists(buf)) {
3134 if (existing == 0) {
3139 error << string_compose(
3140 _("There are already %1 recordings for %2, which I consider too many."),
3141 limit, base) << endmsg;
3143 throw failed_constructor();
3147 return Glib::path_get_basename(buf);
3150 /** Create a new embedded audio source */
3151 boost::shared_ptr<AudioFileSource>
3152 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3154 const size_t n_chans = ds.n_channels().n_audio();
3155 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3156 const string path = new_source_path_from_name(DataType::AUDIO, name);
3157 return boost::dynamic_pointer_cast<AudioFileSource> (
3158 SourceFactory::createWritable (
3159 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3162 /** Return a unique name based on \a base for a new internal MIDI source */
3164 Session::new_midi_source_name (const string& base)
3167 char buf[PATH_MAX+1];
3168 const uint32_t limit = 10000;
3172 legalized = legalize_for_path (base);
3174 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3175 for (cnt = 1; cnt <= limit; ++cnt) {
3177 vector<space_and_path>::iterator i;
3178 uint32_t existing = 0;
3180 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3182 SessionDirectory sdir((*i).path);
3184 sys::path p = sdir.midi_path();
3187 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3189 if (sys::exists (buf)) {
3194 if (existing == 0) {
3199 error << string_compose(
3200 _("There are already %1 recordings for %2, which I consider too many."),
3201 limit, base) << endmsg;
3203 throw failed_constructor();
3207 return Glib::path_get_basename(buf);
3211 /** Create a new embedded MIDI source */
3212 boost::shared_ptr<MidiSource>
3213 Session::create_midi_source_for_session (MidiDiskstream& ds)
3215 const string name = new_midi_source_name (ds.name());
3216 const string path = new_source_path_from_name (DataType::MIDI, name);
3218 return boost::dynamic_pointer_cast<SMFSource> (
3219 SourceFactory::createWritable (
3220 DataType::MIDI, *this, path, true, false, frame_rate()));
3224 /* Playlist management */
3226 boost::shared_ptr<Playlist>
3227 Session::playlist_by_name (string name)
3229 Glib::Mutex::Lock lm (playlist_lock);
3230 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3231 if ((*i)->name() == name) {
3235 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3236 if ((*i)->name() == name) {
3241 return boost::shared_ptr<Playlist>();
3245 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3247 Glib::Mutex::Lock lm (playlist_lock);
3248 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3249 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3250 list.push_back (*i);
3253 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3254 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3255 list.push_back (*i);
3261 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3263 if (playlist->hidden()) {
3268 Glib::Mutex::Lock lm (playlist_lock);
3269 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3270 playlists.insert (playlists.begin(), playlist);
3271 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3272 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3277 playlist->release();
3282 PlaylistAdded (playlist); /* EMIT SIGNAL */
3286 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3289 Glib::Mutex::Lock lm (playlist_lock);
3290 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3293 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3300 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3302 boost::shared_ptr<Playlist> pl(wpl.lock());
3308 PlaylistList::iterator x;
3311 /* its not supposed to be visible */
3316 Glib::Mutex::Lock lm (playlist_lock);
3320 unused_playlists.insert (pl);
3322 if ((x = playlists.find (pl)) != playlists.end()) {
3323 playlists.erase (x);
3329 playlists.insert (pl);
3331 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3332 unused_playlists.erase (x);
3339 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3341 if (_state_of_the_state & Deletion) {
3345 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3352 Glib::Mutex::Lock lm (playlist_lock);
3354 PlaylistList::iterator i;
3356 i = find (playlists.begin(), playlists.end(), playlist);
3357 if (i != playlists.end()) {
3358 playlists.erase (i);
3361 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3362 if (i != unused_playlists.end()) {
3363 unused_playlists.erase (i);
3370 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3374 Session::set_audition (boost::shared_ptr<Region> r)
3376 pending_audition_region = r;
3377 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3378 schedule_butler_transport_work ();
3382 Session::audition_playlist ()
3384 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3385 ev->region.reset ();
3390 Session::non_realtime_set_audition ()
3392 if (!pending_audition_region) {
3393 auditioner->audition_current_playlist ();
3395 auditioner->audition_region (pending_audition_region);
3396 pending_audition_region.reset ();
3398 AuditionActive (true); /* EMIT SIGNAL */
3402 Session::audition_region (boost::shared_ptr<Region> r)
3404 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3410 Session::cancel_audition ()
3412 if (auditioner->active()) {
3413 auditioner->cancel_audition ();
3414 AuditionActive (false); /* EMIT SIGNAL */
3419 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3421 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3425 Session::remove_empty_sounds ()
3427 vector<string> audio_filenames;
3429 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3431 Glib::Mutex::Lock lm (source_lock);
3433 TapeFileMatcher tape_file_matcher;
3435 remove_if (audio_filenames.begin(), audio_filenames.end(),
3436 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3438 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3440 sys::path audio_file_path (_session_dir->sound_path());
3442 audio_file_path /= *i;
3444 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3448 sys::remove (audio_file_path);
3449 const string peakfile = peak_path (audio_file_path.to_string());
3450 sys::remove (peakfile);
3452 catch (const sys::filesystem_error& err)
3454 error << err.what() << endmsg;
3461 Session::is_auditioning () const
3463 /* can be called before we have an auditioner object */
3465 return auditioner->active();
3472 Session::set_all_solo (bool yn)
3474 shared_ptr<RouteList> r = routes.reader ();
3476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3477 if (!(*i)->is_hidden()) {
3478 (*i)->set_solo (yn, this);
3486 Session::set_all_mute (bool yn)
3488 shared_ptr<RouteList> r = routes.reader ();
3490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3491 if (!(*i)->is_hidden()) {
3492 (*i)->set_mute (yn, this);
3500 Session::n_diskstreams () const
3504 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3506 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3507 if (!(*i)->hidden()) {
3515 Session::graph_reordered ()
3517 /* don't do this stuff if we are setting up connections
3518 from a set_state() call or creating new tracks.
3521 if (_state_of_the_state & InitialConnecting) {
3525 /* every track/bus asked for this to be handled but it was deferred because
3526 we were connecting. do it now.
3529 request_input_change_handling ();
3533 /* force all diskstreams to update their capture offset values to
3534 reflect any changes in latencies within the graph.
3537 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3539 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3540 (*i)->set_capture_offset ();
3545 Session::record_disenable_all ()
3547 record_enable_change_all (false);
3551 Session::record_enable_all ()
3553 record_enable_change_all (true);
3557 Session::record_enable_change_all (bool yn)
3559 shared_ptr<RouteList> r = routes.reader ();
3561 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3562 boost::shared_ptr<Track> t;
3564 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3565 t->set_record_enable (yn, this);
3569 /* since we don't keep rec-enable state, don't mark session dirty */
3573 Session::add_processor (Processor* processor)
3577 PortInsert* port_insert;
3578 PluginInsert* plugin_insert;
3580 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3581 _port_inserts.insert (_port_inserts.begin(), port_insert);
3582 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3583 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3584 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3585 _sends.insert (_sends.begin(), send);
3586 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3587 _returns.insert (_returns.begin(), retrn);
3589 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3593 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3599 Session::remove_processor (Processor* processor)
3603 PortInsert* port_insert;
3604 PluginInsert* plugin_insert;
3606 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3607 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3608 if (x != _port_inserts.end()) {
3609 insert_bitset[port_insert->bit_slot()] = false;
3610 _port_inserts.erase (x);
3612 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3613 _plugin_inserts.remove (plugin_insert);
3614 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3615 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3616 if (x != _sends.end()) {
3617 send_bitset[send->bit_slot()] = false;
3620 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3621 list<Return*>::iterator x = find (_returns.begin(), _returns.end(), retrn);
3622 if (x != _returns.end()) {
3623 return_bitset[send->bit_slot()] = false;
3627 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3635 Session::available_capture_duration ()
3637 float sample_bytes_on_disk = 4.0; // keep gcc happy
3639 switch (config.get_native_file_data_format()) {
3641 sample_bytes_on_disk = 4.0;
3645 sample_bytes_on_disk = 3.0;
3649 sample_bytes_on_disk = 2.0;
3653 /* impossible, but keep some gcc versions happy */
3654 fatal << string_compose (_("programming error: %1"),
3655 X_("illegal native file data format"))
3660 double scale = 4096.0 / sample_bytes_on_disk;
3662 if (_total_free_4k_blocks * scale > (double) max_frames) {
3666 return (nframes_t) floor (_total_free_4k_blocks * scale);
3670 Session::add_bundle (shared_ptr<Bundle> bundle)
3673 RCUWriter<BundleList> writer (_bundles);
3674 boost::shared_ptr<BundleList> b = writer.get_copy ();
3675 b->push_back (bundle);
3678 BundleAdded (bundle); /* EMIT SIGNAL */
3684 Session::remove_bundle (shared_ptr<Bundle> bundle)
3686 bool removed = false;
3689 RCUWriter<BundleList> writer (_bundles);
3690 boost::shared_ptr<BundleList> b = writer.get_copy ();
3691 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3693 if (i != b->end()) {
3700 BundleRemoved (bundle); /* EMIT SIGNAL */
3707 Session::bundle_by_name (string name) const
3709 boost::shared_ptr<BundleList> b = _bundles.reader ();
3711 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3712 if ((*i)->name() == name) {
3717 return boost::shared_ptr<Bundle> ();
3721 Session::tempo_map_changed (Change ignored)
3725 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3726 (*i)->update_after_tempo_map_change ();
3729 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3730 (*i)->update_after_tempo_map_change ();
3736 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3737 * the given count with the current block size.
3740 Session::ensure_buffers (ChanCount howmany)
3742 if (current_block_size == 0) {
3743 return; // too early? (is this ok?)
3746 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3747 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3748 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3749 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3750 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3753 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3757 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3759 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3760 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3765 Session::next_insert_id ()
3767 /* this doesn't really loop forever. just think about it */
3770 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3771 if (!insert_bitset[n]) {
3772 insert_bitset[n] = true;
3778 /* none available, so resize and try again */
3780 insert_bitset.resize (insert_bitset.size() + 16, false);
3785 Session::next_send_id ()
3787 /* this doesn't really loop forever. just think about it */
3790 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3791 if (!send_bitset[n]) {
3792 send_bitset[n] = true;
3798 /* none available, so resize and try again */
3800 send_bitset.resize (send_bitset.size() + 16, false);
3805 Session::next_return_id ()
3807 /* this doesn't really loop forever. just think about it */
3810 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3811 if (!return_bitset[n]) {
3812 return_bitset[n] = true;
3818 /* none available, so resize and try again */
3820 return_bitset.resize (return_bitset.size() + 16, false);
3825 Session::mark_send_id (uint32_t id)
3827 if (id >= send_bitset.size()) {
3828 send_bitset.resize (id+16, false);
3830 if (send_bitset[id]) {
3831 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3833 send_bitset[id] = true;
3837 Session::mark_return_id (uint32_t id)
3839 if (id >= return_bitset.size()) {
3840 return_bitset.resize (id+16, false);
3842 if (return_bitset[id]) {
3843 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3845 return_bitset[id] = true;
3849 Session::mark_insert_id (uint32_t id)
3851 if (id >= insert_bitset.size()) {
3852 insert_bitset.resize (id+16, false);
3854 if (insert_bitset[id]) {
3855 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3857 insert_bitset[id] = true;
3860 /* Named Selection management */
3863 Session::named_selection_by_name (string name)
3865 Glib::Mutex::Lock lm (named_selection_lock);
3866 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3867 if ((*i)->name == name) {
3875 Session::add_named_selection (NamedSelection* named_selection)
3878 Glib::Mutex::Lock lm (named_selection_lock);
3879 named_selections.insert (named_selections.begin(), named_selection);
3882 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3888 NamedSelectionAdded (); /* EMIT SIGNAL */
3892 Session::remove_named_selection (NamedSelection* named_selection)
3894 bool removed = false;
3897 Glib::Mutex::Lock lm (named_selection_lock);
3899 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3901 if (i != named_selections.end()) {
3903 named_selections.erase (i);
3910 NamedSelectionRemoved (); /* EMIT SIGNAL */
3915 Session::reset_native_file_format ()
3917 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3919 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3920 (*i)->reset_write_sources (false);
3925 Session::route_name_unique (string n) const
3927 shared_ptr<RouteList> r = routes.reader ();
3929 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3930 if ((*i)->name() == n) {
3939 Session::route_name_internal (string n) const
3941 if (auditioner && auditioner->name() == n) {
3945 if (_click_io && _click_io->name() == n) {
3953 Session::n_playlists () const
3955 Glib::Mutex::Lock lm (playlist_lock);
3956 return playlists.size();
3960 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3962 if (!force && howmany <= _npan_buffers) {
3966 if (_pan_automation_buffer) {
3968 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3969 delete [] _pan_automation_buffer[i];
3972 delete [] _pan_automation_buffer;
3975 _pan_automation_buffer = new pan_t*[howmany];
3977 for (uint32_t i = 0; i < howmany; ++i) {
3978 _pan_automation_buffer[i] = new pan_t[nframes];
3981 _npan_buffers = howmany;
3985 Session::freeze (InterThreadInfo& itt)
3987 shared_ptr<RouteList> r = routes.reader ();
3989 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3991 boost::shared_ptr<Track> t;
3993 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3994 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4004 boost::shared_ptr<Region>
4005 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4006 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4007 InterThreadInfo& itt, bool enable_processing)
4009 boost::shared_ptr<Region> result;
4010 boost::shared_ptr<Playlist> playlist;
4011 boost::shared_ptr<AudioFileSource> fsource;
4013 char buf[PATH_MAX+1];
4014 ChanCount nchans(track.audio_diskstream()->n_channels());
4016 nframes_t this_chunk;
4019 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4020 const string sound_dir = sdir.sound_path().to_string();
4021 nframes_t len = end - start;
4024 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4025 end, start) << endmsg;
4029 // any bigger than this seems to cause stack overflows in called functions
4030 const nframes_t chunk_size = (128 * 1024)/4;
4032 // block all process callback handling
4034 block_processing ();
4036 /* call tree *MUST* hold route_lock */
4038 if ((playlist = track.diskstream()->playlist()) == 0) {
4042 /* external redirects will be a problem */
4044 if (track.has_external_redirects()) {
4048 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4050 for (x = 0; x < 99999; ++x) {
4051 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4052 if (access (buf, F_OK) != 0) {
4058 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4063 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4064 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4067 catch (failed_constructor& err) {
4068 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4072 srcs.push_back (fsource);
4075 /* XXX need to flush all redirects */
4080 /* create a set of reasonably-sized buffers */
4081 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4082 buffers.set_count(nchans);
4084 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4085 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4087 afs->prepare_for_peakfile_writes ();
4090 while (to_do && !itt.cancel) {
4092 this_chunk = min (to_do, chunk_size);
4094 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4099 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4100 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4103 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4109 start += this_chunk;
4110 to_do -= this_chunk;
4112 itt.progress = (float) (1.0 - ((double) to_do / len));
4121 xnow = localtime (&now);
4123 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4124 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4127 afs->update_header (position, *xnow, now);
4128 afs->flush_header ();
4132 /* construct a region to represent the bounced material */
4134 result = RegionFactory::create (srcs, 0,
4135 srcs.front()->length(srcs.front()->timeline_position()),
4136 region_name_from_path (srcs.front()->name(), true));
4141 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4142 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4145 afs->mark_for_remove ();
4148 (*src)->drop_references ();
4152 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4153 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4156 afs->done_with_peakfile_writes ();
4160 unblock_processing ();
4166 Session::get_silent_buffers (ChanCount count)
4168 assert(_silent_buffers->available() >= count);
4169 _silent_buffers->set_count(count);
4171 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4172 for (size_t i= 0; i < count.get(*t); ++i) {
4173 _silent_buffers->get(*t, i).clear();
4177 return *_silent_buffers;
4181 Session::get_scratch_buffers (ChanCount count)
4183 if (count != ChanCount::ZERO) {
4184 assert(_scratch_buffers->available() >= count);
4185 _scratch_buffers->set_count(count);
4187 _scratch_buffers->set_count (_scratch_buffers->available());
4190 return *_scratch_buffers;
4194 Session::get_mix_buffers (ChanCount count)
4196 assert(_mix_buffers->available() >= count);
4197 _mix_buffers->set_count(count);
4198 return *_mix_buffers;
4202 Session::ntracks () const
4205 shared_ptr<RouteList> r = routes.reader ();
4207 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4208 if (boost::dynamic_pointer_cast<Track> (*i)) {
4217 Session::nbusses () const
4220 shared_ptr<RouteList> r = routes.reader ();
4222 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4223 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4232 Session::add_automation_list(AutomationList *al)
4234 automation_lists[al->id()] = al;
4238 Session::compute_initial_length ()
4240 return _engine.frame_rate() * 60 * 5;
4244 Session::sync_order_keys (const char* base)
4246 if (!Config->get_sync_all_route_ordering()) {
4247 /* leave order keys as they are */
4251 boost::shared_ptr<RouteList> r = routes.reader ();
4253 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4254 (*i)->sync_order_keys (base);
4257 Route::SyncOrderKeys (base); // EMIT SIGNAL
4261 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4263 Session::have_rec_enabled_diskstream () const
4265 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4268 /** Update the state of our rec-enabled diskstreams flag */
4270 Session::update_have_rec_enabled_diskstream ()
4272 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4273 DiskstreamList::iterator i = dsl->begin ();
4274 while (i != dsl->end () && (*i)->record_enabled () == false) {
4278 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4280 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4282 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4283 RecordStateChanged (); /* EMIT SIGNAL */