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 Config->set_input_auto_connect (input_ac);
298 Config->set_output_auto_connect (output_ac);
300 if (second_stage_init (new_session)) {
302 throw failed_constructor ();
305 store_recent_sessions (_name, _path);
307 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
309 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
320 /* if we got to here, leaving pending capture state around
324 remove_pending_capture_state ();
326 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
328 _engine.remove_session ();
330 GoingAway (); /* EMIT SIGNAL */
336 /* clear history so that no references to objects are held any more */
340 /* clear state tree so that no references to objects are held any more */
344 terminate_butler_thread ();
345 //terminate_midi_thread ();
347 if (click_data != default_click) {
348 delete [] click_data;
351 if (click_emphasis_data != default_click_emphasis) {
352 delete [] click_emphasis_data;
357 delete _scratch_buffers;
358 delete _silent_buffers;
361 AudioDiskstream::free_working_buffers();
363 Route::SyncOrderKeys.clear();
365 #undef TRACK_DESTRUCTION
366 #ifdef TRACK_DESTRUCTION
367 cerr << "delete named selections\n";
368 #endif /* TRACK_DESTRUCTION */
369 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
370 NamedSelectionList::iterator tmp;
379 #ifdef TRACK_DESTRUCTION
380 cerr << "delete playlists\n";
381 #endif /* TRACK_DESTRUCTION */
382 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
383 PlaylistList::iterator tmp;
388 (*i)->drop_references ();
393 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
394 PlaylistList::iterator tmp;
399 (*i)->drop_references ();
405 unused_playlists.clear ();
407 #ifdef TRACK_DESTRUCTION
408 cerr << "delete regions\n";
409 #endif /* TRACK_DESTRUCTION */
411 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
412 RegionList::iterator tmp;
417 i->second->drop_references ();
424 #ifdef TRACK_DESTRUCTION
425 cerr << "delete routes\n";
426 #endif /* TRACK_DESTRUCTION */
428 RCUWriter<RouteList> writer (routes);
429 boost::shared_ptr<RouteList> r = writer.get_copy ();
430 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
431 (*i)->drop_references ();
434 /* writer goes out of scope and updates master */
439 #ifdef TRACK_DESTRUCTION
440 cerr << "delete diskstreams\n";
441 #endif /* TRACK_DESTRUCTION */
443 RCUWriter<DiskstreamList> dwriter (diskstreams);
444 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
445 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
446 (*i)->drop_references ();
450 diskstreams.flush ();
452 #ifdef TRACK_DESTRUCTION
453 cerr << "delete audio sources\n";
454 #endif /* TRACK_DESTRUCTION */
455 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
456 SourceMap::iterator tmp;
461 i->second->drop_references ();
467 #ifdef TRACK_DESTRUCTION
468 cerr << "delete mix groups\n";
469 #endif /* TRACK_DESTRUCTION */
470 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
471 list<RouteGroup*>::iterator tmp;
481 #ifdef TRACK_DESTRUCTION
482 cerr << "delete edit groups\n";
483 #endif /* TRACK_DESTRUCTION */
484 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
485 list<RouteGroup*>::iterator tmp;
495 delete [] butler_mixdown_buffer;
496 delete [] butler_gain_buffer;
498 Crossfade::set_buffer_size (0);
504 Session::set_worst_io_latencies ()
506 _worst_output_latency = 0;
507 _worst_input_latency = 0;
509 if (!_engine.connected()) {
513 boost::shared_ptr<RouteList> r = routes.reader ();
515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
516 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
517 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
522 Session::when_engine_running ()
524 string first_physical_output;
526 BootMessage (_("Set block size and sample rate"));
528 set_block_size (_engine.frames_per_cycle());
529 set_frame_rate (_engine.frame_rate());
531 BootMessage (_("Using configuration"));
533 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
535 /* every time we reconnect, recompute worst case output latencies */
537 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
539 if (synced_to_jack()) {
540 _engine.transport_stop ();
543 if (config.get_jack_time_master()) {
544 _engine.transport_locate (_transport_frame);
552 _click_io.reset (new ClickIO (*this, "click"));
554 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
556 /* existing state for Click */
558 if (_click_io->set_state (*child->children().front()) == 0) {
560 _clicking = Config->get_clicking ();
564 error << _("could not setup Click I/O") << endmsg;
570 /* default state for Click: dual-mono to first 2 physical outputs */
572 for (int physport = 0; physport < 2; ++physport) {
573 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
575 if (physical_output.length()) {
576 if (_click_io->add_port (physical_output, this)) {
577 // relax, even though its an error
582 if (_click_io->n_ports () > ChanCount::ZERO) {
583 _clicking = Config->get_clicking ();
588 catch (failed_constructor& err) {
589 error << _("cannot setup Click I/O") << endmsg;
592 BootMessage (_("Compute I/O Latencies"));
594 set_worst_io_latencies ();
597 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
600 BootMessage (_("Set up standard connections"));
602 /* Create a set of Bundle objects that map
603 to the physical I/O currently available. We create both
604 mono and stereo bundles, so that the common cases of mono
605 and stereo tracks get bundles to put in their mixer strip
606 in / out menus. There may be a nicer way of achieving that;
607 it doesn't really scale that well to higher channel counts
610 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
612 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
614 shared_ptr<Bundle> c (new Bundle (buf, true));
615 c->add_channel (_("mono"));
616 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
621 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
622 if (np + 1 < n_physical_outputs) {
624 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
625 shared_ptr<Bundle> c (new Bundle (buf, true));
626 c->add_channel (_("L"));
627 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
628 c->add_channel (_("R"));
629 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
635 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
637 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
639 shared_ptr<Bundle> c (new Bundle (buf, false));
640 c->add_channel (_("mono"));
641 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
646 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
647 if (np + 1 < n_physical_inputs) {
649 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
651 shared_ptr<Bundle> c (new Bundle (buf, false));
652 c->add_channel (_("L"));
653 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
654 c->add_channel (_("R"));
655 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
661 /* create master/control ports */
665 /* if requested auto-connect the outputs to the first N physical ports.
668 if (Config->get_auto_connect_master()) {
669 uint32_t limit = _master_out->n_outputs().n_total();
671 for (uint32_t n = 0; n < limit; ++n) {
672 Port* p = _master_out->output()->nth (n);
673 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
675 if (!connect_to.empty()) {
676 if (_master_out->output()->connect (p, connect_to, this)) {
677 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
686 BootMessage (_("Setup signal flow and plugins"));
690 /* catch up on send+insert cnts */
692 BootMessage (_("Catch up with send/insert state"));
696 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
699 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
700 if (id > insert_cnt) {
708 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
711 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
719 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
721 /* hook us up to the engine */
723 BootMessage (_("Connect to engine"));
725 _engine.set_session (this);
729 Session::hookup_io ()
731 /* stop graph reordering notifications from
732 causing resorts, etc.
735 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
740 /* we delay creating the auditioner till now because
741 it makes its own connections to ports.
742 the engine has to be running for this to work.
746 auditioner.reset (new Auditioner (*this));
749 catch (failed_constructor& err) {
750 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
754 /* Connect track to listen/solo etc. busses XXX generalize this beyond control_out */
758 // _control_out->ensure_io (_control_out->input_minimum(), _control_out->output_minimum(), false, this);
760 boost::shared_ptr<RouteList> r = routes.reader ();
762 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
764 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
767 t->listen_via (_control_out->input(), X_("listen"));
772 /* load bundles, which we may have postponed earlier on */
773 if (_bundle_xml_node) {
774 load_bundles (*_bundle_xml_node);
775 delete _bundle_xml_node;
778 /* Tell all IO objects to connect themselves together */
780 IO::enable_connecting ();
782 /* Now reset all panners */
784 Delivery::reset_panners ();
786 /* Anyone who cares about input state, wake up and do something */
788 IOConnectionsComplete (); /* EMIT SIGNAL */
790 _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)->input())) {
1459 (*i)->fed_by.insert (*j);
1464 for (i = r->begin(); i != r->end(); ++i) {
1465 trace_terminal (*i, *i);
1472 cerr << "finished route resort\n";
1474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1475 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1482 list<boost::shared_ptr<MidiTrack> >
1483 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1485 char track_name[32];
1486 uint32_t track_id = 0;
1489 RouteList new_routes;
1490 list<boost::shared_ptr<MidiTrack> > ret;
1491 //uint32_t control_id;
1493 // FIXME: need physical I/O and autoconnect stuff for MIDI
1495 /* count existing midi tracks */
1498 shared_ptr<RouteList> r = routes.reader ();
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1502 if (!(*i)->is_hidden()) {
1504 //channels_used += (*i)->n_inputs().n_midi();
1510 vector<string> physinputs;
1511 vector<string> physoutputs;
1513 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1514 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1516 // control_id = ntracks() + nbusses();
1520 /* check for duplicate route names, since we might have pre-existing
1521 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1522 save, close,restart,add new route - first named route is now
1530 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1532 if (route_by_name (track_name) == 0) {
1536 } while (track_id < (UINT_MAX-1));
1538 shared_ptr<MidiTrack> track;
1541 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1543 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1544 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1549 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1550 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1556 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1560 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1561 port = physinputs[(channels_used+x)%nphysical_in];
1564 if (port.length() && track->connect_input (track->input (x), port, this)) {
1570 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1574 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1575 port = physoutputs[(channels_used+x)%nphysical_out];
1576 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1578 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1582 if (port.length() && track->connect_output (track->output (x), port, this)) {
1587 channels_used += track->n_inputs ().n_midi();
1591 track->midi_diskstream()->non_realtime_input_change();
1593 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1594 //track->set_remote_control_id (control_id);
1596 new_routes.push_back (track);
1597 ret.push_back (track);
1600 catch (failed_constructor &err) {
1601 error << _("Session: could not create new midi track.") << endmsg;
1604 /* we need to get rid of this, since the track failed to be created */
1605 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1608 RCUWriter<DiskstreamList> writer (diskstreams);
1609 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1610 ds->remove (track->midi_diskstream());
1617 catch (AudioEngine::PortRegistrationFailure& pfe) {
1619 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1622 /* we need to get rid of this, since the track failed to be created */
1623 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1626 RCUWriter<DiskstreamList> writer (diskstreams);
1627 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1628 ds->remove (track->midi_diskstream());
1639 if (!new_routes.empty()) {
1640 add_routes (new_routes, false);
1641 save_state (_current_snapshot_name);
1647 list<boost::shared_ptr<AudioTrack> >
1648 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1650 char track_name[32];
1651 uint32_t track_id = 0;
1653 uint32_t channels_used = 0;
1655 RouteList new_routes;
1656 list<boost::shared_ptr<AudioTrack> > ret;
1657 uint32_t control_id;
1659 /* count existing audio tracks */
1662 shared_ptr<RouteList> r = routes.reader ();
1664 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1665 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1666 if (!(*i)->is_hidden()) {
1668 channels_used += (*i)->n_inputs().n_audio();
1674 vector<string> physinputs;
1675 vector<string> physoutputs;
1677 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1678 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1680 control_id = ntracks() + nbusses() + 1;
1684 /* check for duplicate route names, since we might have pre-existing
1685 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1686 save, close,restart,add new route - first named route is now
1694 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1696 if (route_by_name (track_name) == 0) {
1700 } while (track_id < (UINT_MAX-1));
1702 shared_ptr<AudioTrack> track;
1705 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1707 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1708 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1709 input_channels, output_channels)
1714 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1715 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1716 input_channels, output_channels)
1721 if (!physinputs.empty()) {
1722 uint32_t nphysical_in = physinputs.size();
1724 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1728 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1729 port = physinputs[(channels_used+x)%nphysical_in];
1732 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1738 if (!physoutputs.empty()) {
1739 uint32_t nphysical_out = physoutputs.size();
1741 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1744 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1745 port = physoutputs[(channels_used+x)%nphysical_out];
1746 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1747 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1748 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1752 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1758 channels_used += track->n_inputs ().n_audio();
1760 track->audio_diskstream()->non_realtime_input_change();
1762 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1763 track->set_remote_control_id (control_id);
1766 new_routes.push_back (track);
1767 ret.push_back (track);
1770 catch (failed_constructor &err) {
1771 error << _("Session: could not create new audio track.") << endmsg;
1774 /* we need to get rid of this, since the track failed to be created */
1775 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1778 RCUWriter<DiskstreamList> writer (diskstreams);
1779 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1780 ds->remove (track->audio_diskstream());
1787 catch (AudioEngine::PortRegistrationFailure& pfe) {
1789 error << pfe.what() << endmsg;
1792 /* we need to get rid of this, since the track failed to be created */
1793 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1796 RCUWriter<DiskstreamList> writer (diskstreams);
1797 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1798 ds->remove (track->audio_diskstream());
1809 if (!new_routes.empty()) {
1810 add_routes (new_routes, true);
1817 Session::set_remote_control_ids ()
1819 RemoteModel m = Config->get_remote_model();
1821 shared_ptr<RouteList> r = routes.reader ();
1823 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1824 if ( MixerOrdered == m) {
1825 long order = (*i)->order_key(N_("signal"));
1826 (*i)->set_remote_control_id( order+1 );
1827 } else if ( EditorOrdered == m) {
1828 long order = (*i)->order_key(N_("editor"));
1829 (*i)->set_remote_control_id( order+1 );
1830 } else if ( UserOrdered == m) {
1831 //do nothing ... only changes to remote id's are initiated by user
1838 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1841 uint32_t bus_id = 1;
1843 uint32_t channels_used = 0;
1846 uint32_t control_id;
1848 /* count existing audio busses */
1851 shared_ptr<RouteList> r = routes.reader ();
1853 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1854 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1856 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1859 channels_used += (*i)->n_inputs().n_audio();
1865 vector<string> physinputs;
1866 vector<string> physoutputs;
1868 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1869 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1871 n_physical_audio_outputs = physoutputs.size();
1872 n_physical_audio_inputs = physinputs.size();
1874 control_id = ntracks() + nbusses() + 1;
1879 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1883 if (route_by_name (bus_name) == 0) {
1887 } while (bus_id < (UINT_MAX-1));
1890 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1892 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1893 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1894 input_channels, output_channels)
1900 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1901 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1902 input_channels, output_channels)
1910 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1914 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1915 port = physinputs[((n+x)%n_physical_audio_inputs)];
1918 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1924 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1927 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1928 port = physoutputs[((n+x)%n_physical_outputs)];
1929 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1931 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1935 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1940 channels_used += bus->n_inputs ().n_audio();
1942 bus->set_remote_control_id (control_id);
1945 ret.push_back (bus);
1949 catch (failed_constructor &err) {
1950 error << _("Session: could not create new audio route.") << endmsg;
1954 catch (AudioEngine::PortRegistrationFailure& pfe) {
1955 error << pfe.what() << endmsg;
1965 add_routes (ret, true);
1973 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1977 uint32_t control_id;
1980 if (!tree.read (template_path.c_str())) {
1984 XMLNode* node = tree.root();
1986 control_id = ntracks() + nbusses() + 1;
1990 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1992 std::string node_name = IO::name_from_state (*node_copy.children().front());
1994 if (route_by_name (node_name) != 0) {
1996 /* generate a new name by adding a number to the end of the template name */
1998 uint32_t number = 1;
2001 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2005 if (route_by_name (name) == 0) {
2009 } while (number < UINT_MAX);
2011 if (number == UINT_MAX) {
2012 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2016 IO::set_name_in_state (*node_copy.children().front(), name);
2019 Track::zero_diskstream_id_in_xml (node_copy);
2022 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2025 error << _("Session: cannot create track/bus from template description") << endmsg;
2029 if (boost::dynamic_pointer_cast<Track>(route)) {
2030 /* force input/output change signals so that the new diskstream
2031 picks up the configuration of the route. During session
2032 loading this normally happens in a different way.
2034 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2035 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2038 route->set_remote_control_id (control_id);
2041 ret.push_back (route);
2044 catch (failed_constructor &err) {
2045 error << _("Session: could not create new route from template") << endmsg;
2049 catch (AudioEngine::PortRegistrationFailure& pfe) {
2050 error << pfe.what() << endmsg;
2059 add_routes (ret, true);
2066 Session::add_routes (RouteList& new_routes, bool save)
2069 RCUWriter<RouteList> writer (routes);
2070 shared_ptr<RouteList> r = writer.get_copy ();
2071 r->insert (r->end(), new_routes.begin(), new_routes.end());
2072 resort_routes_using (r);
2075 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2077 boost::weak_ptr<Route> wpr (*x);
2079 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2080 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2081 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2082 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2084 if ((*x)->is_master()) {
2088 if ((*x)->is_control()) {
2089 _control_out = (*x);
2093 if (_control_out && IO::connecting_legal) {
2095 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2096 (*x)->listen_via (_control_out->input(), "control");
2103 save_state (_current_snapshot_name);
2106 RouteAdded (new_routes); /* EMIT SIGNAL */
2110 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2112 /* need to do this in case we're rolling at the time, to prevent false underruns */
2113 dstream->do_refill_with_alloc ();
2115 dstream->set_block_size (current_block_size);
2118 RCUWriter<DiskstreamList> writer (diskstreams);
2119 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2120 ds->push_back (dstream);
2121 /* writer goes out of scope, copies ds back to main */
2124 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2125 /* this will connect to future changes, and check the current length */
2126 diskstream_playlist_changed (dstream);
2128 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2130 dstream->prepare ();
2135 Session::remove_route (shared_ptr<Route> route)
2138 RCUWriter<RouteList> writer (routes);
2139 shared_ptr<RouteList> rs = writer.get_copy ();
2143 /* deleting the master out seems like a dumb
2144 idea, but its more of a UI policy issue
2148 if (route == _master_out) {
2149 _master_out = shared_ptr<Route> ();
2152 if (route == _control_out) {
2153 /* cancel control outs for all routes */
2155 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2156 (*r)->drop_listen (_control_out->input());
2159 _control_out = shared_ptr<Route> ();
2162 update_route_solo_state ();
2164 /* writer goes out of scope, forces route list update */
2167 boost::shared_ptr<Track> t;
2168 boost::shared_ptr<Diskstream> ds;
2170 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2171 ds = t->diskstream();
2177 RCUWriter<DiskstreamList> dsl (diskstreams);
2178 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2183 find_current_end ();
2185 // We need to disconnect the routes inputs and outputs
2187 route->input()->disconnect (0);
2188 route->output()->disconnect (0);
2190 update_latency_compensation (false, false);
2193 /* get rid of it from the dead wood collection in the route list manager */
2195 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2199 /* try to cause everyone to drop their references */
2201 route->drop_references ();
2203 sync_order_keys (N_("session"));
2205 /* save the new state of the world */
2207 if (save_state (_current_snapshot_name)) {
2208 save_history (_current_snapshot_name);
2213 Session::route_mute_changed (void* src)
2219 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2221 if (solo_update_disabled) {
2226 boost::shared_ptr<Route> route = wpr.lock ();
2229 /* should not happen */
2230 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2234 shared_ptr<RouteList> r = routes.reader ();
2237 if (route->soloed()) {
2243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2244 if ((*i)->feeds (route->input())) {
2247 solo_update_disabled = true;
2248 (*i)->main_outs()->mod_solo_level (delta);
2249 solo_update_disabled = false;
2253 /* now figure out if anything is soloed */
2255 bool something_soloed = false;
2257 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2258 if ((*i)->soloed()) {
2259 something_soloed = true;
2264 if (something_soloed != _non_soloed_outs_muted) {
2265 _non_soloed_outs_muted = something_soloed;
2266 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2269 SoloChanged (); /* EMIT SIGNAL */
2275 Session::update_route_solo_state ()
2278 bool is_track = false;
2279 bool signal = false;
2281 /* this is where we actually implement solo by changing
2282 the solo mute setting of each track.
2285 shared_ptr<RouteList> r = routes.reader ();
2287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2288 if ((*i)->soloed()) {
2290 if (boost::dynamic_pointer_cast<Track>(*i)) {
2297 if (mute != currently_soloing) {
2299 currently_soloing = mute;
2302 if (!is_track && !mute) {
2304 /* nothing is soloed */
2314 SoloActive (currently_soloing);
2320 Session::catch_up_on_solo ()
2322 /* this is called after set_state() to catch the full solo
2323 state, which can't be correctly determined on a per-route
2324 basis, but needs the global overview that only the session
2327 update_route_solo_state();
2331 Session::catch_up_on_solo_mute_override ()
2333 if (Config->get_solo_model() != InverseMute) {
2337 /* this is called whenever the param solo-mute-override is
2340 shared_ptr<RouteList> r = routes.reader ();
2342 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2343 // (*i)->catch_up_on_solo_mute_override ();
2348 Session::route_by_name (string name)
2350 shared_ptr<RouteList> r = routes.reader ();
2352 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2353 if ((*i)->name() == name) {
2358 return shared_ptr<Route> ((Route*) 0);
2362 Session::route_by_id (PBD::ID id)
2364 shared_ptr<RouteList> r = routes.reader ();
2366 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2367 if ((*i)->id() == id) {
2372 return shared_ptr<Route> ((Route*) 0);
2376 Session::route_by_remote_id (uint32_t id)
2378 shared_ptr<RouteList> r = routes.reader ();
2380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381 if ((*i)->remote_control_id() == id) {
2386 return shared_ptr<Route> ((Route*) 0);
2390 Session::find_current_end ()
2392 if (_state_of_the_state & Loading) {
2396 nframes_t max = get_maximum_extent ();
2398 if (max > end_location->end()) {
2399 end_location->set_end (max);
2401 DurationChanged(); /* EMIT SIGNAL */
2406 Session::get_maximum_extent () const
2411 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2413 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2414 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2416 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2417 if ((me = pl->get_maximum_extent()) > max) {
2425 boost::shared_ptr<Diskstream>
2426 Session::diskstream_by_name (string name)
2428 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2431 if ((*i)->name() == name) {
2436 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2439 boost::shared_ptr<Diskstream>
2440 Session::diskstream_by_id (const PBD::ID& id)
2442 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2444 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2445 if ((*i)->id() == id) {
2450 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2453 /* Region management */
2456 Session::new_region_name (string old)
2458 string::size_type last_period;
2460 string::size_type len = old.length() + 64;
2463 if ((last_period = old.find_last_of ('.')) == string::npos) {
2465 /* no period present - add one explicitly */
2468 last_period = old.length() - 1;
2473 number = atoi (old.substr (last_period+1).c_str());
2477 while (number < (UINT_MAX-1)) {
2479 RegionList::const_iterator i;
2484 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2487 for (i = regions.begin(); i != regions.end(); ++i) {
2488 if (i->second->name() == sbuf) {
2493 if (i == regions.end()) {
2498 if (number != (UINT_MAX-1)) {
2502 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2507 Session::region_name (string& result, string base, bool newlevel)
2512 if (base.find("/") != string::npos) {
2513 base = base.substr(base.find_last_of("/") + 1);
2518 Glib::Mutex::Lock lm (region_lock);
2520 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2529 string::size_type pos;
2531 pos = base.find_last_of ('.');
2533 /* pos may be npos, but then we just use entire base */
2535 subbase = base.substr (0, pos);
2540 Glib::Mutex::Lock lm (region_lock);
2542 map<string,uint32_t>::iterator x;
2546 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2548 region_name_map[subbase] = 1;
2551 snprintf (buf, sizeof (buf), ".%d", x->second);
2562 Session::add_region (boost::shared_ptr<Region> region)
2564 vector<boost::shared_ptr<Region> > v;
2565 v.push_back (region);
2570 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2575 Glib::Mutex::Lock lm (region_lock);
2577 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2579 boost::shared_ptr<Region> region = *ii;
2583 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2587 RegionList::iterator x;
2589 for (x = regions.begin(); x != regions.end(); ++x) {
2591 if (region->region_list_equivalent (x->second)) {
2596 if (x == regions.end()) {
2598 pair<RegionList::key_type,RegionList::mapped_type> entry;
2600 entry.first = region->id();
2601 entry.second = region;
2603 pair<RegionList::iterator,bool> x = regions.insert (entry);
2615 /* mark dirty because something has changed even if we didn't
2616 add the region to the region list.
2623 vector<boost::weak_ptr<Region> > v;
2624 boost::shared_ptr<Region> first_r;
2626 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2628 boost::shared_ptr<Region> region = *ii;
2632 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2635 v.push_back (region);
2642 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2643 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2645 update_region_name_map (region);
2649 RegionsAdded (v); /* EMIT SIGNAL */
2655 Session::update_region_name_map (boost::shared_ptr<Region> region)
2657 string::size_type last_period = region->name().find_last_of ('.');
2659 if (last_period != string::npos && last_period < region->name().length() - 1) {
2661 string base = region->name().substr (0, last_period);
2662 string number = region->name().substr (last_period+1);
2663 map<string,uint32_t>::iterator x;
2665 /* note that if there is no number, we get zero from atoi,
2669 region_name_map[base] = atoi (number);
2674 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2676 boost::shared_ptr<Region> region (weak_region.lock ());
2682 if (what_changed & Region::HiddenChanged) {
2683 /* relay hidden changes */
2684 RegionHiddenChange (region);
2687 if (what_changed & NameChanged) {
2688 update_region_name_map (region);
2693 Session::remove_region (boost::weak_ptr<Region> weak_region)
2695 RegionList::iterator i;
2696 boost::shared_ptr<Region> region (weak_region.lock ());
2702 bool removed = false;
2705 Glib::Mutex::Lock lm (region_lock);
2707 if ((i = regions.find (region->id())) != regions.end()) {
2713 /* mark dirty because something has changed even if we didn't
2714 remove the region from the region list.
2720 RegionRemoved(region); /* EMIT SIGNAL */
2724 boost::shared_ptr<Region>
2725 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2727 RegionList::iterator i;
2728 boost::shared_ptr<Region> region;
2730 Glib::Mutex::Lock lm (region_lock);
2732 for (i = regions.begin(); i != regions.end(); ++i) {
2736 if (region->whole_file()) {
2738 if (child->source_equivalent (region)) {
2744 return boost::shared_ptr<Region> ();
2748 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2750 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2751 (*i)->get_region_list_equivalent_regions (region, result);
2755 Session::destroy_region (boost::shared_ptr<Region> region)
2757 vector<boost::shared_ptr<Source> > srcs;
2760 if (region->playlist()) {
2761 region->playlist()->destroy_region (region);
2764 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2765 srcs.push_back (region->source (n));
2769 region->drop_references ();
2771 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2773 (*i)->mark_for_remove ();
2774 (*i)->drop_references ();
2776 cerr << "source was not used by any playlist\n";
2783 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2785 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2786 destroy_region (*i);
2792 Session::remove_last_capture ()
2794 list<boost::shared_ptr<Region> > r;
2796 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2798 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2799 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2802 r.insert (r.end(), l.begin(), l.end());
2807 destroy_regions (r);
2809 save_state (_current_snapshot_name);
2815 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2821 /* Source Management */
2824 Session::add_source (boost::shared_ptr<Source> source)
2826 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2827 pair<SourceMap::iterator,bool> result;
2829 entry.first = source->id();
2830 entry.second = source;
2833 Glib::Mutex::Lock lm (source_lock);
2834 result = sources.insert (entry);
2837 if (result.second) {
2838 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2842 boost::shared_ptr<AudioFileSource> afs;
2844 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2845 if (Config->get_auto_analyse_audio()) {
2846 Analyser::queue_source_for_analysis (source, false);
2852 Session::remove_source (boost::weak_ptr<Source> src)
2854 SourceMap::iterator i;
2855 boost::shared_ptr<Source> source = src.lock();
2862 Glib::Mutex::Lock lm (source_lock);
2864 if ((i = sources.find (source->id())) != sources.end()) {
2869 if (!_state_of_the_state & InCleanup) {
2871 /* save state so we don't end up with a session file
2872 referring to non-existent sources.
2875 save_state (_current_snapshot_name);
2879 boost::shared_ptr<Source>
2880 Session::source_by_id (const PBD::ID& id)
2882 Glib::Mutex::Lock lm (source_lock);
2883 SourceMap::iterator i;
2884 boost::shared_ptr<Source> source;
2886 if ((i = sources.find (id)) != sources.end()) {
2893 boost::shared_ptr<Source>
2894 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2896 Glib::Mutex::Lock lm (source_lock);
2898 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2899 cerr << "comparing " << path << " with " << i->second->name() << endl;
2900 boost::shared_ptr<AudioFileSource> afs
2901 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2903 if (afs && afs->path() == path && chn == afs->channel()) {
2907 return boost::shared_ptr<Source>();
2912 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2915 string old_basename = PBD::basename_nosuffix (oldname);
2916 string new_legalized = legalize_for_path (newname);
2918 /* note: we know (or assume) the old path is already valid */
2922 /* destructive file sources have a name of the form:
2924 /path/to/Tnnnn-NAME(%[LR])?.wav
2926 the task here is to replace NAME with the new name.
2929 /* find last slash */
2933 string::size_type slash;
2934 string::size_type dash;
2936 if ((slash = path.find_last_of ('/')) == string::npos) {
2940 dir = path.substr (0, slash+1);
2942 /* '-' is not a legal character for the NAME part of the path */
2944 if ((dash = path.find_last_of ('-')) == string::npos) {
2948 prefix = path.substr (slash+1, dash-(slash+1));
2953 path += new_legalized;
2954 path += ".wav"; /* XXX gag me with a spoon */
2958 /* non-destructive file sources have a name of the form:
2960 /path/to/NAME-nnnnn(%[LR])?.ext
2962 the task here is to replace NAME with the new name.
2967 string::size_type slash;
2968 string::size_type dash;
2969 string::size_type postfix;
2971 /* find last slash */
2973 if ((slash = path.find_last_of ('/')) == string::npos) {
2977 dir = path.substr (0, slash+1);
2979 /* '-' is not a legal character for the NAME part of the path */
2981 if ((dash = path.find_last_of ('-')) == string::npos) {
2985 suffix = path.substr (dash+1);
2987 // Suffix is now everything after the dash. Now we need to eliminate
2988 // the nnnnn part, which is done by either finding a '%' or a '.'
2990 postfix = suffix.find_last_of ("%");
2991 if (postfix == string::npos) {
2992 postfix = suffix.find_last_of ('.');
2995 if (postfix != string::npos) {
2996 suffix = suffix.substr (postfix);
2998 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3002 const uint32_t limit = 10000;
3003 char buf[PATH_MAX+1];
3005 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3007 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3009 if (access (buf, F_OK) != 0) {
3017 error << "FATAL ERROR! Could not find a " << endl;
3025 /** Return the full path (in some session directory) for a new embedded source.
3026 * \a name must be a session-unique name that does not contain slashes
3027 * (e.g. as returned by new_*_source_name)
3030 Session::new_source_path_from_name (DataType type, const string& name)
3032 assert(name.find("/") == string::npos);
3034 SessionDirectory sdir(get_best_session_directory_for_new_source());
3037 if (type == DataType::AUDIO) {
3038 p = sdir.sound_path();
3039 } else if (type == DataType::MIDI) {
3040 p = sdir.midi_path();
3042 error << "Unknown source type, unable to create file path" << endmsg;
3047 return p.to_string();
3051 Session::peak_path (Glib::ustring base) const
3053 sys::path peakfile_path(_session_dir->peak_path());
3054 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3055 return peakfile_path.to_string();
3058 /** Return a unique name based on \a base for a new internal audio source */
3060 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3064 char buf[PATH_MAX+1];
3065 const uint32_t limit = 10000;
3069 legalized = legalize_for_path (base);
3071 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3072 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3074 vector<space_and_path>::iterator i;
3075 uint32_t existing = 0;
3077 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3079 SessionDirectory sdir((*i).path);
3081 spath = sdir.sound_path().to_string();
3086 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3087 spath.c_str(), cnt, legalized.c_str());
3088 } else if (nchan == 2) {
3090 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3091 spath.c_str(), cnt, legalized.c_str());
3093 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3094 spath.c_str(), cnt, legalized.c_str());
3096 } else if (nchan < 26) {
3097 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3098 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3100 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3101 spath.c_str(), cnt, legalized.c_str());
3110 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3111 } else if (nchan == 2) {
3113 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3115 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3117 } else if (nchan < 26) {
3118 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3120 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3124 if (sys::exists(buf)) {
3130 if (existing == 0) {
3135 error << string_compose(
3136 _("There are already %1 recordings for %2, which I consider too many."),
3137 limit, base) << endmsg;
3139 throw failed_constructor();
3143 return Glib::path_get_basename(buf);
3146 /** Create a new embedded audio source */
3147 boost::shared_ptr<AudioFileSource>
3148 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3150 const size_t n_chans = ds.n_channels().n_audio();
3151 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3152 const string path = new_source_path_from_name(DataType::AUDIO, name);
3153 return boost::dynamic_pointer_cast<AudioFileSource> (
3154 SourceFactory::createWritable (
3155 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3158 /** Return a unique name based on \a base for a new internal MIDI source */
3160 Session::new_midi_source_name (const string& base)
3163 char buf[PATH_MAX+1];
3164 const uint32_t limit = 10000;
3168 legalized = legalize_for_path (base);
3170 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3171 for (cnt = 1; cnt <= limit; ++cnt) {
3173 vector<space_and_path>::iterator i;
3174 uint32_t existing = 0;
3176 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3178 SessionDirectory sdir((*i).path);
3180 sys::path p = sdir.midi_path();
3183 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3185 if (sys::exists (buf)) {
3190 if (existing == 0) {
3195 error << string_compose(
3196 _("There are already %1 recordings for %2, which I consider too many."),
3197 limit, base) << endmsg;
3199 throw failed_constructor();
3203 return Glib::path_get_basename(buf);
3207 /** Create a new embedded MIDI source */
3208 boost::shared_ptr<MidiSource>
3209 Session::create_midi_source_for_session (MidiDiskstream& ds)
3211 const string name = new_midi_source_name (ds.name());
3212 const string path = new_source_path_from_name (DataType::MIDI, name);
3214 return boost::dynamic_pointer_cast<SMFSource> (
3215 SourceFactory::createWritable (
3216 DataType::MIDI, *this, path, true, false, frame_rate()));
3220 /* Playlist management */
3222 boost::shared_ptr<Playlist>
3223 Session::playlist_by_name (string name)
3225 Glib::Mutex::Lock lm (playlist_lock);
3226 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3227 if ((*i)->name() == name) {
3231 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3232 if ((*i)->name() == name) {
3237 return boost::shared_ptr<Playlist>();
3241 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3243 Glib::Mutex::Lock lm (playlist_lock);
3244 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3245 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3246 list.push_back (*i);
3249 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3250 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3251 list.push_back (*i);
3257 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3259 if (playlist->hidden()) {
3264 Glib::Mutex::Lock lm (playlist_lock);
3265 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3266 playlists.insert (playlists.begin(), playlist);
3267 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3268 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3273 playlist->release();
3278 PlaylistAdded (playlist); /* EMIT SIGNAL */
3282 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3285 Glib::Mutex::Lock lm (playlist_lock);
3286 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3289 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3296 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3298 boost::shared_ptr<Playlist> pl(wpl.lock());
3304 PlaylistList::iterator x;
3307 /* its not supposed to be visible */
3312 Glib::Mutex::Lock lm (playlist_lock);
3316 unused_playlists.insert (pl);
3318 if ((x = playlists.find (pl)) != playlists.end()) {
3319 playlists.erase (x);
3325 playlists.insert (pl);
3327 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3328 unused_playlists.erase (x);
3335 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3337 if (_state_of_the_state & Deletion) {
3341 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3348 Glib::Mutex::Lock lm (playlist_lock);
3350 PlaylistList::iterator i;
3352 i = find (playlists.begin(), playlists.end(), playlist);
3353 if (i != playlists.end()) {
3354 playlists.erase (i);
3357 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3358 if (i != unused_playlists.end()) {
3359 unused_playlists.erase (i);
3366 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3370 Session::set_audition (boost::shared_ptr<Region> r)
3372 pending_audition_region = r;
3373 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3374 schedule_butler_transport_work ();
3378 Session::audition_playlist ()
3380 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3381 ev->region.reset ();
3386 Session::non_realtime_set_audition ()
3388 if (!pending_audition_region) {
3389 auditioner->audition_current_playlist ();
3391 auditioner->audition_region (pending_audition_region);
3392 pending_audition_region.reset ();
3394 AuditionActive (true); /* EMIT SIGNAL */
3398 Session::audition_region (boost::shared_ptr<Region> r)
3400 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3406 Session::cancel_audition ()
3408 if (auditioner->active()) {
3409 auditioner->cancel_audition ();
3410 AuditionActive (false); /* EMIT SIGNAL */
3415 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3417 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3421 Session::remove_empty_sounds ()
3423 vector<string> audio_filenames;
3425 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3427 Glib::Mutex::Lock lm (source_lock);
3429 TapeFileMatcher tape_file_matcher;
3431 remove_if (audio_filenames.begin(), audio_filenames.end(),
3432 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3434 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3436 sys::path audio_file_path (_session_dir->sound_path());
3438 audio_file_path /= *i;
3440 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3444 sys::remove (audio_file_path);
3445 const string peakfile = peak_path (audio_file_path.to_string());
3446 sys::remove (peakfile);
3448 catch (const sys::filesystem_error& err)
3450 error << err.what() << endmsg;
3457 Session::is_auditioning () const
3459 /* can be called before we have an auditioner object */
3461 return auditioner->active();
3468 Session::set_all_solo (bool yn)
3470 shared_ptr<RouteList> r = routes.reader ();
3472 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3473 if (!(*i)->is_hidden()) {
3474 (*i)->set_solo (yn, this);
3482 Session::set_all_mute (bool yn)
3484 shared_ptr<RouteList> r = routes.reader ();
3486 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3487 if (!(*i)->is_hidden()) {
3488 (*i)->set_mute (yn, this);
3496 Session::n_diskstreams () const
3500 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3502 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3503 if (!(*i)->hidden()) {
3511 Session::graph_reordered ()
3513 /* don't do this stuff if we are setting up connections
3514 from a set_state() call or creating new tracks.
3517 if (_state_of_the_state & InitialConnecting) {
3521 /* every track/bus asked for this to be handled but it was deferred because
3522 we were connecting. do it now.
3525 request_input_change_handling ();
3529 /* force all diskstreams to update their capture offset values to
3530 reflect any changes in latencies within the graph.
3533 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3535 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3536 (*i)->set_capture_offset ();
3541 Session::record_disenable_all ()
3543 record_enable_change_all (false);
3547 Session::record_enable_all ()
3549 record_enable_change_all (true);
3553 Session::record_enable_change_all (bool yn)
3555 shared_ptr<RouteList> r = routes.reader ();
3557 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3558 boost::shared_ptr<Track> t;
3560 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3561 t->set_record_enable (yn, this);
3565 /* since we don't keep rec-enable state, don't mark session dirty */
3569 Session::add_processor (Processor* processor)
3573 PortInsert* port_insert;
3574 PluginInsert* plugin_insert;
3576 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3577 _port_inserts.insert (_port_inserts.begin(), port_insert);
3578 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3579 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3580 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3581 _sends.insert (_sends.begin(), send);
3582 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3583 _returns.insert (_returns.begin(), retrn);
3585 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3589 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3595 Session::remove_processor (Processor* processor)
3599 PortInsert* port_insert;
3600 PluginInsert* plugin_insert;
3602 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3603 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3604 if (x != _port_inserts.end()) {
3605 insert_bitset[port_insert->bit_slot()] = false;
3606 _port_inserts.erase (x);
3608 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3609 _plugin_inserts.remove (plugin_insert);
3610 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3611 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3612 if (x != _sends.end()) {
3613 send_bitset[send->bit_slot()] = false;
3616 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3617 list<Return*>::iterator x = find (_returns.begin(), _returns.end(), retrn);
3618 if (x != _returns.end()) {
3619 return_bitset[send->bit_slot()] = false;
3623 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3631 Session::available_capture_duration ()
3633 float sample_bytes_on_disk = 4.0; // keep gcc happy
3635 switch (config.get_native_file_data_format()) {
3637 sample_bytes_on_disk = 4.0;
3641 sample_bytes_on_disk = 3.0;
3645 sample_bytes_on_disk = 2.0;
3649 /* impossible, but keep some gcc versions happy */
3650 fatal << string_compose (_("programming error: %1"),
3651 X_("illegal native file data format"))
3656 double scale = 4096.0 / sample_bytes_on_disk;
3658 if (_total_free_4k_blocks * scale > (double) max_frames) {
3662 return (nframes_t) floor (_total_free_4k_blocks * scale);
3666 Session::add_bundle (shared_ptr<Bundle> bundle)
3669 RCUWriter<BundleList> writer (_bundles);
3670 boost::shared_ptr<BundleList> b = writer.get_copy ();
3671 b->push_back (bundle);
3674 BundleAdded (bundle); /* EMIT SIGNAL */
3680 Session::remove_bundle (shared_ptr<Bundle> bundle)
3682 bool removed = false;
3685 RCUWriter<BundleList> writer (_bundles);
3686 boost::shared_ptr<BundleList> b = writer.get_copy ();
3687 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3689 if (i != b->end()) {
3696 BundleRemoved (bundle); /* EMIT SIGNAL */
3703 Session::bundle_by_name (string name) const
3705 boost::shared_ptr<BundleList> b = _bundles.reader ();
3707 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3708 if ((*i)->name() == name) {
3713 return boost::shared_ptr<Bundle> ();
3717 Session::tempo_map_changed (Change ignored)
3721 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3722 (*i)->update_after_tempo_map_change ();
3725 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3726 (*i)->update_after_tempo_map_change ();
3732 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3733 * the given count with the current block size.
3736 Session::ensure_buffers (ChanCount howmany)
3738 if (current_block_size == 0) {
3739 return; // too early? (is this ok?)
3742 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3743 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3744 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3745 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3746 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3749 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3753 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3755 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3756 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3761 Session::next_insert_id ()
3763 /* this doesn't really loop forever. just think about it */
3766 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3767 if (!insert_bitset[n]) {
3768 insert_bitset[n] = true;
3774 /* none available, so resize and try again */
3776 insert_bitset.resize (insert_bitset.size() + 16, false);
3781 Session::next_send_id ()
3783 /* this doesn't really loop forever. just think about it */
3786 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3787 if (!send_bitset[n]) {
3788 send_bitset[n] = true;
3794 /* none available, so resize and try again */
3796 send_bitset.resize (send_bitset.size() + 16, false);
3801 Session::next_return_id ()
3803 /* this doesn't really loop forever. just think about it */
3806 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3807 if (!return_bitset[n]) {
3808 return_bitset[n] = true;
3814 /* none available, so resize and try again */
3816 return_bitset.resize (return_bitset.size() + 16, false);
3821 Session::mark_send_id (uint32_t id)
3823 if (id >= send_bitset.size()) {
3824 send_bitset.resize (id+16, false);
3826 if (send_bitset[id]) {
3827 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3829 send_bitset[id] = true;
3833 Session::mark_return_id (uint32_t id)
3835 if (id >= return_bitset.size()) {
3836 return_bitset.resize (id+16, false);
3838 if (return_bitset[id]) {
3839 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3841 return_bitset[id] = true;
3845 Session::mark_insert_id (uint32_t id)
3847 if (id >= insert_bitset.size()) {
3848 insert_bitset.resize (id+16, false);
3850 if (insert_bitset[id]) {
3851 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3853 insert_bitset[id] = true;
3856 /* Named Selection management */
3859 Session::named_selection_by_name (string name)
3861 Glib::Mutex::Lock lm (named_selection_lock);
3862 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3863 if ((*i)->name == name) {
3871 Session::add_named_selection (NamedSelection* named_selection)
3874 Glib::Mutex::Lock lm (named_selection_lock);
3875 named_selections.insert (named_selections.begin(), named_selection);
3878 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3884 NamedSelectionAdded (); /* EMIT SIGNAL */
3888 Session::remove_named_selection (NamedSelection* named_selection)
3890 bool removed = false;
3893 Glib::Mutex::Lock lm (named_selection_lock);
3895 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3897 if (i != named_selections.end()) {
3899 named_selections.erase (i);
3906 NamedSelectionRemoved (); /* EMIT SIGNAL */
3911 Session::reset_native_file_format ()
3913 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3915 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3916 (*i)->reset_write_sources (false);
3921 Session::route_name_unique (string n) const
3923 shared_ptr<RouteList> r = routes.reader ();
3925 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3926 if ((*i)->name() == n) {
3935 Session::route_name_internal (string n) const
3937 if (auditioner && auditioner->name() == n) {
3941 if (_click_io && _click_io->name() == n) {
3949 Session::n_playlists () const
3951 Glib::Mutex::Lock lm (playlist_lock);
3952 return playlists.size();
3956 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3958 if (!force && howmany <= _npan_buffers) {
3962 if (_pan_automation_buffer) {
3964 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3965 delete [] _pan_automation_buffer[i];
3968 delete [] _pan_automation_buffer;
3971 _pan_automation_buffer = new pan_t*[howmany];
3973 for (uint32_t i = 0; i < howmany; ++i) {
3974 _pan_automation_buffer[i] = new pan_t[nframes];
3977 _npan_buffers = howmany;
3981 Session::freeze (InterThreadInfo& itt)
3983 shared_ptr<RouteList> r = routes.reader ();
3985 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3987 boost::shared_ptr<Track> t;
3989 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3990 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4000 boost::shared_ptr<Region>
4001 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4002 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4003 InterThreadInfo& itt, bool enable_processing)
4005 boost::shared_ptr<Region> result;
4006 boost::shared_ptr<Playlist> playlist;
4007 boost::shared_ptr<AudioFileSource> fsource;
4009 char buf[PATH_MAX+1];
4010 ChanCount nchans(track.audio_diskstream()->n_channels());
4012 nframes_t this_chunk;
4015 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4016 const string sound_dir = sdir.sound_path().to_string();
4017 nframes_t len = end - start;
4020 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4021 end, start) << endmsg;
4025 // any bigger than this seems to cause stack overflows in called functions
4026 const nframes_t chunk_size = (128 * 1024)/4;
4028 // block all process callback handling
4030 block_processing ();
4032 /* call tree *MUST* hold route_lock */
4034 if ((playlist = track.diskstream()->playlist()) == 0) {
4038 /* external redirects will be a problem */
4040 if (track.has_external_redirects()) {
4044 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4046 for (x = 0; x < 99999; ++x) {
4047 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4048 if (access (buf, F_OK) != 0) {
4054 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4059 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4060 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4063 catch (failed_constructor& err) {
4064 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4068 srcs.push_back (fsource);
4071 /* XXX need to flush all redirects */
4076 /* create a set of reasonably-sized buffers */
4077 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4078 buffers.set_count(nchans);
4080 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4081 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4083 afs->prepare_for_peakfile_writes ();
4086 while (to_do && !itt.cancel) {
4088 this_chunk = min (to_do, chunk_size);
4090 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4095 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4096 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4099 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4105 start += this_chunk;
4106 to_do -= this_chunk;
4108 itt.progress = (float) (1.0 - ((double) to_do / len));
4117 xnow = localtime (&now);
4119 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4120 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4123 afs->update_header (position, *xnow, now);
4124 afs->flush_header ();
4128 /* construct a region to represent the bounced material */
4130 result = RegionFactory::create (srcs, 0,
4131 srcs.front()->length(srcs.front()->timeline_position()),
4132 region_name_from_path (srcs.front()->name(), true));
4137 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4138 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4141 afs->mark_for_remove ();
4144 (*src)->drop_references ();
4148 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4149 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4152 afs->done_with_peakfile_writes ();
4156 unblock_processing ();
4162 Session::get_silent_buffers (ChanCount count)
4164 assert(_silent_buffers->available() >= count);
4165 _silent_buffers->set_count(count);
4167 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4168 for (size_t i= 0; i < count.get(*t); ++i) {
4169 _silent_buffers->get(*t, i).clear();
4173 return *_silent_buffers;
4177 Session::get_scratch_buffers (ChanCount count)
4179 if (count != ChanCount::ZERO) {
4180 assert(_scratch_buffers->available() >= count);
4181 _scratch_buffers->set_count(count);
4183 _scratch_buffers->set_count (_scratch_buffers->available());
4186 return *_scratch_buffers;
4190 Session::get_mix_buffers (ChanCount count)
4192 assert(_mix_buffers->available() >= count);
4193 _mix_buffers->set_count(count);
4194 return *_mix_buffers;
4198 Session::ntracks () const
4201 shared_ptr<RouteList> r = routes.reader ();
4203 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4204 if (boost::dynamic_pointer_cast<Track> (*i)) {
4213 Session::nbusses () const
4216 shared_ptr<RouteList> r = routes.reader ();
4218 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4219 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4228 Session::add_automation_list(AutomationList *al)
4230 automation_lists[al->id()] = al;
4234 Session::compute_initial_length ()
4236 return _engine.frame_rate() * 60 * 5;
4240 Session::sync_order_keys (const char* base)
4242 if (!Config->get_sync_all_route_ordering()) {
4243 /* leave order keys as they are */
4247 boost::shared_ptr<RouteList> r = routes.reader ();
4249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4250 (*i)->sync_order_keys (base);
4253 Route::SyncOrderKeys (base); // EMIT SIGNAL
4257 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4259 Session::have_rec_enabled_diskstream () const
4261 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4264 /** Update the state of our rec-enabled diskstreams flag */
4266 Session::update_have_rec_enabled_diskstream ()
4268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4269 DiskstreamList::iterator i = dsl->begin ();
4270 while (i != dsl->end () && (*i)->record_enabled () == false) {
4274 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4276 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4278 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4279 RecordStateChanged (); /* EMIT SIGNAL */