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/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/session_directory.h>
50 #include <ardour/session_metadata.h>
51 #include <ardour/utils.h>
52 #include <ardour/audio_diskstream.h>
53 #include <ardour/audioplaylist.h>
54 #include <ardour/audioregion.h>
55 #include <ardour/audiofilesource.h>
56 #include <ardour/midi_diskstream.h>
57 #include <ardour/midi_playlist.h>
58 #include <ardour/midi_region.h>
59 #include <ardour/smf_source.h>
60 #include <ardour/auditioner.h>
61 #include <ardour/recent_sessions.h>
62 #include <ardour/io_processor.h>
63 #include <ardour/send.h>
64 #include <ardour/processor.h>
65 #include <ardour/plugin_insert.h>
66 #include <ardour/port_insert.h>
67 #include <ardour/auto_bundle.h>
68 #include <ardour/slave.h>
69 #include <ardour/tempo.h>
70 #include <ardour/audio_track.h>
71 #include <ardour/midi_track.h>
72 #include <ardour/cycle_timer.h>
73 #include <ardour/named_selection.h>
74 #include <ardour/crossfade.h>
75 #include <ardour/playlist.h>
76 #include <ardour/click.h>
77 #include <ardour/data_type.h>
78 #include <ardour/buffer_set.h>
79 #include <ardour/source_factory.h>
80 #include <ardour/region_factory.h>
81 #include <ardour/filename_extensions.h>
82 #include <ardour/session_directory.h>
83 #include <ardour/tape_file_matcher.h>
84 #include <ardour/analyser.h>
87 #include <ardour/osc.h>
93 using namespace ARDOUR;
95 using boost::shared_ptr;
98 static const int CPU_CACHE_ALIGN = 64;
100 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
103 bool Session::_disable_all_loaded_plugins = false;
105 sigc::signal<void,std::string> Session::Dialog;
106 sigc::signal<int> Session::AskAboutPendingState;
107 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
108 sigc::signal<void> Session::SendFeedback;
110 sigc::signal<void> Session::SMPTEOffsetChanged;
111 sigc::signal<void> Session::StartTimeChanged;
112 sigc::signal<void> Session::EndTimeChanged;
113 sigc::signal<void> Session::AutoBindingOn;
114 sigc::signal<void> Session::AutoBindingOff;
115 sigc::signal<void, std::string, std::string> Session::Exported;
117 Session::Session (AudioEngine &eng,
118 const string& fullpath,
119 const string& snapshot_name,
123 _scratch_buffers(new BufferSet()),
124 _silent_buffers(new BufferSet()),
125 _mix_buffers(new BufferSet()),
127 _mmc_port (default_mmc_port),
128 _mtc_port (default_mtc_port),
129 _midi_port (default_midi_port),
130 _midi_clock_port (default_midi_clock_port),
131 _session_dir (new SessionDirectory(fullpath)),
132 pending_events (2048),
134 butler_mixdown_buffer (0),
135 butler_gain_buffer (0),
136 post_transport_work((PostTransportWork)0),
137 _send_smpte_update (false),
138 midi_thread (pthread_t (0)),
139 midi_requests (128), // the size of this should match the midi request pool size
140 diskstreams (new DiskstreamList),
141 routes (new RouteList),
142 auditioner ((Auditioner*) 0),
143 _total_free_4k_blocks (0),
144 _bundle_xml_node (0),
147 click_emphasis_data (0),
149 _metadata (new SessionMetadata())
154 if (!eng.connected()) {
155 throw failed_constructor();
158 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
160 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
161 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
163 first_stage_init (fullpath, snapshot_name);
165 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
168 if (create (new_session, mix_template, compute_initial_length())) {
170 throw failed_constructor ();
174 if (second_stage_init (new_session)) {
176 throw failed_constructor ();
179 store_recent_sessions(_name, _path);
181 bool was_dirty = dirty();
183 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
185 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _scratch_buffers(new BufferSet()),
205 _silent_buffers(new BufferSet()),
206 _mix_buffers(new BufferSet()),
208 _mmc_port (default_mmc_port),
209 _mtc_port (default_mtc_port),
210 _midi_port (default_midi_port),
211 _midi_clock_port (default_midi_clock_port),
212 _session_dir ( new SessionDirectory(fullpath)),
213 pending_events (2048),
215 butler_mixdown_buffer (0),
216 butler_gain_buffer (0),
217 post_transport_work((PostTransportWork)0),
218 _send_smpte_update (false),
219 midi_thread (pthread_t (0)),
221 diskstreams (new DiskstreamList),
222 routes (new RouteList),
223 auditioner ((Auditioner *) 0),
224 _total_free_4k_blocks (0),
225 _bundle_xml_node (0),
226 _click_io ((IO *) 0),
228 click_emphasis_data (0),
230 _metadata (new SessionMetadata())
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 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
270 r->set_remote_control_id (control_id++);
275 if (master_out_channels) {
276 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
277 r->set_remote_control_id (control_id);
281 /* prohibit auto-connect to master, because there isn't one */
282 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
286 add_routes (rl, false);
291 Config->set_input_auto_connect (input_ac);
292 Config->set_output_auto_connect (output_ac);
294 if (second_stage_init (new_session)) {
296 throw failed_constructor ();
299 store_recent_sessions (_name, _path);
301 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
303 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
314 /* if we got to here, leaving pending capture state around
318 remove_pending_capture_state ();
320 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
322 _engine.remove_session ();
324 GoingAway (); /* EMIT SIGNAL */
330 /* clear history so that no references to objects are held any more */
334 /* clear state tree so that no references to objects are held any more */
338 terminate_butler_thread ();
339 //terminate_midi_thread ();
341 if (click_data != default_click) {
342 delete [] click_data;
345 if (click_emphasis_data != default_click_emphasis) {
346 delete [] click_emphasis_data;
351 delete _scratch_buffers;
352 delete _silent_buffers;
355 AudioDiskstream::free_working_buffers();
357 Route::SyncOrderKeys.clear();
359 #undef TRACK_DESTRUCTION
360 #ifdef TRACK_DESTRUCTION
361 cerr << "delete named selections\n";
362 #endif /* TRACK_DESTRUCTION */
363 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
364 NamedSelectionList::iterator tmp;
373 #ifdef TRACK_DESTRUCTION
374 cerr << "delete playlists\n";
375 #endif /* TRACK_DESTRUCTION */
376 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
377 PlaylistList::iterator tmp;
382 (*i)->drop_references ();
387 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
388 PlaylistList::iterator tmp;
393 (*i)->drop_references ();
399 unused_playlists.clear ();
401 #ifdef TRACK_DESTRUCTION
402 cerr << "delete regions\n";
403 #endif /* TRACK_DESTRUCTION */
405 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
406 RegionList::iterator tmp;
411 i->second->drop_references ();
418 #ifdef TRACK_DESTRUCTION
419 cerr << "delete routes\n";
420 #endif /* TRACK_DESTRUCTION */
422 RCUWriter<RouteList> writer (routes);
423 boost::shared_ptr<RouteList> r = writer.get_copy ();
424 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
425 (*i)->drop_references ();
428 /* writer goes out of scope and updates master */
433 #ifdef TRACK_DESTRUCTION
434 cerr << "delete diskstreams\n";
435 #endif /* TRACK_DESTRUCTION */
437 RCUWriter<DiskstreamList> dwriter (diskstreams);
438 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
439 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
440 (*i)->drop_references ();
444 diskstreams.flush ();
446 #ifdef TRACK_DESTRUCTION
447 cerr << "delete audio sources\n";
448 #endif /* TRACK_DESTRUCTION */
449 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
450 SourceMap::iterator tmp;
455 i->second->drop_references ();
461 #ifdef TRACK_DESTRUCTION
462 cerr << "delete mix groups\n";
463 #endif /* TRACK_DESTRUCTION */
464 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
465 list<RouteGroup*>::iterator tmp;
475 #ifdef TRACK_DESTRUCTION
476 cerr << "delete edit groups\n";
477 #endif /* TRACK_DESTRUCTION */
478 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
479 list<RouteGroup*>::iterator tmp;
489 delete [] butler_mixdown_buffer;
490 delete [] butler_gain_buffer;
492 Crossfade::set_buffer_size (0);
498 Session::set_worst_io_latencies ()
500 _worst_output_latency = 0;
501 _worst_input_latency = 0;
503 if (!_engine.connected()) {
507 boost::shared_ptr<RouteList> r = routes.reader ();
509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
510 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
511 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
516 Session::when_engine_running ()
518 string first_physical_output;
520 /* we don't want to run execute this again */
522 BootMessage (_("Set block size and sample rate"));
524 set_block_size (_engine.frames_per_cycle());
525 set_frame_rate (_engine.frame_rate());
527 BootMessage (_("Using configuration"));
529 Config->map_parameters (mem_fun (*this, &Session::config_changed));
531 /* every time we reconnect, recompute worst case output latencies */
533 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
535 if (synced_to_jack()) {
536 _engine.transport_stop ();
539 if (Config->get_jack_time_master()) {
540 _engine.transport_locate (_transport_frame);
548 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
550 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
552 /* existing state for Click */
554 if (_click_io->set_state (*child->children().front()) == 0) {
556 _clicking = Config->get_clicking ();
560 error << _("could not setup Click I/O") << endmsg;
566 /* default state for Click */
568 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
570 if (first_physical_output.length()) {
571 if (_click_io->add_output_port (first_physical_output, this)) {
572 // relax, even though its an error
574 _clicking = Config->get_clicking ();
580 catch (failed_constructor& err) {
581 error << _("cannot setup Click I/O") << endmsg;
584 BootMessage (_("Compute I/O Latencies"));
586 set_worst_io_latencies ();
589 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
592 /* Create a set of Bundle objects that map
593 to the physical outputs currently available
596 BootMessage (_("Set up standard connections"));
600 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
602 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
604 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
606 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
611 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
613 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
615 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
617 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
624 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
626 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
628 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
630 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
631 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
636 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
638 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
640 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
642 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
643 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
652 /* create master/control ports */
657 /* force the master to ignore any later call to this */
659 if (_master_out->pending_state_node) {
660 _master_out->ports_became_legal();
663 /* no panner resets till we are through */
665 _master_out->defer_pan_reset ();
667 while (_master_out->n_inputs().n_audio()
668 < _master_out->input_maximum().n_audio()) {
669 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
670 error << _("cannot setup master inputs")
676 while (_master_out->n_outputs().n_audio()
677 < _master_out->output_maximum().n_audio()) {
678 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
679 error << _("cannot setup master outputs")
686 _master_out->allow_pan_reset ();
690 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
692 c->set_channels (_master_out->n_inputs().n_total());
693 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
694 c->set_port (n, _master_out->input(n)->name());
699 BootMessage (_("Setup signal flow and plugins"));
703 /* catch up on send+insert cnts */
705 BootMessage (_("Catch up with send/insert state"));
709 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
712 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
713 if (id > insert_cnt) {
721 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
724 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
732 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
734 /* hook us up to the engine */
736 BootMessage (_("Connect to engine"));
738 _engine.set_session (this);
743 BootMessage (_("OSC startup"));
745 osc->set_session (*this);
751 Session::hookup_io ()
753 /* stop graph reordering notifications from
754 causing resorts, etc.
757 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
760 if (auditioner == 0) {
762 /* we delay creating the auditioner till now because
763 it makes its own connections to ports.
764 the engine has to be running for this to work.
768 auditioner.reset (new Auditioner (*this));
771 catch (failed_constructor& err) {
772 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
776 /* Tell all IO objects to create their ports */
782 vector<string> cports;
784 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
785 if (_control_out->add_input_port ("", this)) {
786 error << _("cannot setup control inputs")
792 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
793 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
794 error << _("cannot set up master outputs")
802 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
804 for (n = 0; n < ni; ++n) {
805 cports.push_back (_control_out->input(n)->name());
808 boost::shared_ptr<RouteList> r = routes.reader ();
810 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
811 (*x)->set_control_outs (cports);
815 /* load bundles, which we may have postponed earlier on */
816 if (_bundle_xml_node) {
817 load_bundles (*_bundle_xml_node);
818 delete _bundle_xml_node;
821 /* Tell all IO objects to connect themselves together */
823 IO::enable_connecting ();
825 /* Now reset all panners */
827 IO::reset_panners ();
829 /* Anyone who cares about input state, wake up and do something */
831 IOConnectionsComplete (); /* EMIT SIGNAL */
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
836 /* now handle the whole enchilada as if it was one
842 /* update mixer solo state */
848 Session::playlist_length_changed ()
850 /* we can't just increase end_location->end() if pl->get_maximum_extent()
851 if larger. if the playlist used to be the longest playlist,
852 and its now shorter, we have to decrease end_location->end(). hence,
853 we have to iterate over all diskstreams and check the
854 playlists currently in use.
860 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
862 boost::shared_ptr<Playlist> playlist;
864 if ((playlist = dstream->playlist()) != 0) {
865 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
868 /* see comment in playlist_length_changed () */
873 Session::record_enabling_legal () const
875 /* this used to be in here, but survey says.... we don't need to restrict it */
876 // if (record_status() == Recording) {
880 if (Config->get_all_safe()) {
887 Session::reset_input_monitor_state ()
889 if (transport_rolling()) {
891 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
893 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
894 if ((*i)->record_enabled ()) {
895 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
896 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
900 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
902 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
903 if ((*i)->record_enabled ()) {
904 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
905 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
912 Session::auto_punch_start_changed (Location* location)
914 replace_event (Event::PunchIn, location->start());
916 if (get_record_enabled() && Config->get_punch_in()) {
917 /* capture start has been changed, so save new pending state */
918 save_state ("", true);
923 Session::auto_punch_end_changed (Location* location)
925 nframes_t when_to_stop = location->end();
926 // when_to_stop += _worst_output_latency + _worst_input_latency;
927 replace_event (Event::PunchOut, when_to_stop);
931 Session::auto_punch_changed (Location* location)
933 nframes_t when_to_stop = location->end();
935 replace_event (Event::PunchIn, location->start());
936 //when_to_stop += _worst_output_latency + _worst_input_latency;
937 replace_event (Event::PunchOut, when_to_stop);
941 Session::auto_loop_changed (Location* location)
943 replace_event (Event::AutoLoop, location->end(), location->start());
945 if (transport_rolling() && play_loop) {
947 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
949 if (_transport_frame > location->end()) {
950 // relocate to beginning of loop
951 clear_events (Event::LocateRoll);
953 request_locate (location->start(), true);
956 else if (Config->get_seamless_loop() && !loop_changing) {
958 // schedule a locate-roll to refill the diskstreams at the
960 loop_changing = true;
962 if (location->end() > last_loopend) {
963 clear_events (Event::LocateRoll);
964 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
971 last_loopend = location->end();
975 Session::set_auto_punch_location (Location* location)
979 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
980 auto_punch_start_changed_connection.disconnect();
981 auto_punch_end_changed_connection.disconnect();
982 auto_punch_changed_connection.disconnect();
983 existing->set_auto_punch (false, this);
984 remove_event (existing->start(), Event::PunchIn);
985 clear_events (Event::PunchOut);
986 auto_punch_location_changed (0);
995 if (location->end() <= location->start()) {
996 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1000 auto_punch_start_changed_connection.disconnect();
1001 auto_punch_end_changed_connection.disconnect();
1002 auto_punch_changed_connection.disconnect();
1004 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1005 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1006 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1008 location->set_auto_punch (true, this);
1011 auto_punch_changed (location);
1013 auto_punch_location_changed (location);
1017 Session::set_auto_loop_location (Location* location)
1021 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1022 auto_loop_start_changed_connection.disconnect();
1023 auto_loop_end_changed_connection.disconnect();
1024 auto_loop_changed_connection.disconnect();
1025 existing->set_auto_loop (false, this);
1026 remove_event (existing->end(), Event::AutoLoop);
1027 auto_loop_location_changed (0);
1032 if (location == 0) {
1036 if (location->end() <= location->start()) {
1037 error << _("Session: you can't use a mark for auto loop") << endmsg;
1041 last_loopend = location->end();
1043 auto_loop_start_changed_connection.disconnect();
1044 auto_loop_end_changed_connection.disconnect();
1045 auto_loop_changed_connection.disconnect();
1047 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1048 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1049 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1051 location->set_auto_loop (true, this);
1053 /* take care of our stuff first */
1055 auto_loop_changed (location);
1057 /* now tell everyone else */
1059 auto_loop_location_changed (location);
1063 Session::locations_added (Location* ignored)
1069 Session::locations_changed ()
1071 _locations.apply (*this, &Session::handle_locations_changed);
1075 Session::handle_locations_changed (Locations::LocationList& locations)
1077 Locations::LocationList::iterator i;
1079 bool set_loop = false;
1080 bool set_punch = false;
1082 for (i = locations.begin(); i != locations.end(); ++i) {
1086 if (location->is_auto_punch()) {
1087 set_auto_punch_location (location);
1090 if (location->is_auto_loop()) {
1091 set_auto_loop_location (location);
1095 if (location->is_start()) {
1096 start_location = location;
1098 if (location->is_end()) {
1099 end_location = location;
1104 set_auto_loop_location (0);
1107 set_auto_punch_location (0);
1114 Session::enable_record ()
1116 /* XXX really atomic compare+swap here */
1117 if (g_atomic_int_get (&_record_status) != Recording) {
1118 g_atomic_int_set (&_record_status, Recording);
1119 _last_record_location = _transport_frame;
1120 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1122 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1123 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1124 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1125 if ((*i)->record_enabled ()) {
1126 (*i)->monitor_input (true);
1131 RecordStateChanged ();
1136 Session::disable_record (bool rt_context, bool force)
1140 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1142 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1143 g_atomic_int_set (&_record_status, Disabled);
1145 if (rs == Recording) {
1146 g_atomic_int_set (&_record_status, Enabled);
1150 // FIXME: timestamp correct? [DR]
1151 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1152 // does this /need/ to be sent in all cases?
1154 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1156 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1157 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1159 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1160 if ((*i)->record_enabled ()) {
1161 (*i)->monitor_input (false);
1166 RecordStateChanged (); /* emit signal */
1169 remove_pending_capture_state ();
1175 Session::step_back_from_record ()
1177 /* XXX really atomic compare+swap here */
1178 if (g_atomic_int_get (&_record_status) == Recording) {
1179 g_atomic_int_set (&_record_status, Enabled);
1181 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1182 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1184 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1185 if ((*i)->record_enabled ()) {
1186 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1187 (*i)->monitor_input (false);
1195 Session::maybe_enable_record ()
1197 g_atomic_int_set (&_record_status, Enabled);
1199 /* this function is currently called from somewhere other than an RT thread.
1200 this save_state() call therefore doesn't impact anything.
1203 save_state ("", true);
1205 if (_transport_speed) {
1206 if (!Config->get_punch_in()) {
1210 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1211 RecordStateChanged (); /* EMIT SIGNAL */
1218 Session::audible_frame () const
1224 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1225 return last_stop_frame;
1228 /* the first of these two possible settings for "offset"
1229 mean that the audible frame is stationary until
1230 audio emerges from the latency compensation
1233 the second means that the audible frame is stationary
1234 until audio would emerge from a physical port
1235 in the absence of any plugin latency compensation
1238 offset = _worst_output_latency;
1240 if (offset > current_block_size) {
1241 offset -= current_block_size;
1243 /* XXX is this correct? if we have no external
1244 physical connections and everything is internal
1245 then surely this is zero? still, how
1246 likely is that anyway?
1248 offset = current_block_size;
1251 if (synced_to_jack()) {
1252 tf = _engine.transport_frame();
1254 tf = _transport_frame;
1259 if (!non_realtime_work_pending()) {
1263 /* check to see if we have passed the first guaranteed
1264 audible frame past our last stopping position. if not,
1265 the return that last stopping point because in terms
1266 of audible frames, we have not moved yet.
1269 if (_transport_speed > 0.0f) {
1271 if (!play_loop || !have_looped) {
1272 if (tf < last_stop_frame + offset) {
1273 return last_stop_frame;
1282 } else if (_transport_speed < 0.0f) {
1284 /* XXX wot? no backward looping? */
1286 if (tf > last_stop_frame - offset) {
1287 return last_stop_frame;
1299 Session::set_frame_rate (nframes_t frames_per_second)
1301 /** \fn void Session::set_frame_size(nframes_t)
1302 the AudioEngine object that calls this guarantees
1303 that it will not be called while we are also in
1304 ::process(). Its fine to do things that block
1308 _base_frame_rate = frames_per_second;
1312 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1316 // XXX we need some equivalent to this, somehow
1317 // SndFileSource::setup_standard_crossfades (frames_per_second);
1321 /* XXX need to reset/reinstantiate all LADSPA plugins */
1325 Session::set_block_size (nframes_t nframes)
1327 /* the AudioEngine guarantees
1328 that it will not be called while we are also in
1329 ::process(). It is therefore fine to do things that block
1335 current_block_size = nframes;
1337 ensure_buffers(_scratch_buffers->available());
1339 if (_gain_automation_buffer) {
1340 delete [] _gain_automation_buffer;
1342 _gain_automation_buffer = new gain_t[nframes];
1344 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1346 boost::shared_ptr<RouteList> r = routes.reader ();
1348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1349 (*i)->set_block_size (nframes);
1352 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1353 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1354 (*i)->set_block_size (nframes);
1357 set_worst_io_latencies ();
1362 Session::set_default_fade (float steepness, float fade_msecs)
1365 nframes_t fade_frames;
1367 /* Don't allow fade of less 1 frame */
1369 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1376 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1380 default_fade_msecs = fade_msecs;
1381 default_fade_steepness = steepness;
1384 // jlc, WTF is this!
1385 Glib::RWLock::ReaderLock lm (route_lock);
1386 AudioRegion::set_default_fade (steepness, fade_frames);
1391 /* XXX have to do this at some point */
1392 /* foreach region using default fade, reset, then
1393 refill_all_diskstream_buffers ();
1398 struct RouteSorter {
1399 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1400 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1402 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1405 if (r1->fed_by.empty()) {
1406 if (r2->fed_by.empty()) {
1407 /* no ardour-based connections inbound to either route. just use signal order */
1408 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1410 /* r2 has connections, r1 does not; run r1 early */
1414 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1421 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1423 shared_ptr<Route> r2;
1425 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1426 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1430 /* make a copy of the existing list of routes that feed r1 */
1432 set<shared_ptr<Route> > existing = r1->fed_by;
1434 /* for each route that feeds r1, recurse, marking it as feeding
1438 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1441 /* r2 is a route that feeds r1 which somehow feeds base. mark
1442 base as being fed by r2
1445 rbase->fed_by.insert (r2);
1449 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1453 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1457 /* now recurse, so that we can mark base as being fed by
1458 all routes that feed r2
1461 trace_terminal (r2, rbase);
1468 Session::resort_routes ()
1470 /* don't do anything here with signals emitted
1471 by Routes while we are being destroyed.
1474 if (_state_of_the_state & Deletion) {
1481 RCUWriter<RouteList> writer (routes);
1482 shared_ptr<RouteList> r = writer.get_copy ();
1483 resort_routes_using (r);
1484 /* writer goes out of scope and forces update */
1489 Session::resort_routes_using (shared_ptr<RouteList> r)
1491 RouteList::iterator i, j;
1493 for (i = r->begin(); i != r->end(); ++i) {
1495 (*i)->fed_by.clear ();
1497 for (j = r->begin(); j != r->end(); ++j) {
1499 /* although routes can feed themselves, it will
1500 cause an endless recursive descent if we
1501 detect it. so don't bother checking for
1509 if ((*j)->feeds (*i)) {
1510 (*i)->fed_by.insert (*j);
1515 for (i = r->begin(); i != r->end(); ++i) {
1516 trace_terminal (*i, *i);
1523 cerr << "finished route resort\n";
1525 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1526 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1533 list<boost::shared_ptr<MidiTrack> >
1534 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1536 char track_name[32];
1537 uint32_t track_id = 0;
1540 RouteList new_routes;
1541 list<boost::shared_ptr<MidiTrack> > ret;
1542 //uint32_t control_id;
1544 // FIXME: need physical I/O and autoconnect stuff for MIDI
1546 /* count existing midi tracks */
1549 shared_ptr<RouteList> r = routes.reader ();
1551 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1552 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1553 if (!(*i)->is_hidden()) {
1555 //channels_used += (*i)->n_inputs().n_midi();
1561 vector<string> physinputs;
1562 vector<string> physoutputs;
1564 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1565 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1567 // control_id = ntracks() + nbusses();
1571 /* check for duplicate route names, since we might have pre-existing
1572 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1573 save, close,restart,add new route - first named route is now
1581 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1583 if (route_by_name (track_name) == 0) {
1587 } while (track_id < (UINT_MAX-1));
1589 shared_ptr<MidiTrack> track;
1592 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1594 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1595 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1601 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1605 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1606 port = physinputs[(channels_used+x)%nphysical_in];
1609 if (port.length() && track->connect_input (track->input (x), port, this)) {
1615 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1619 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1620 port = physoutputs[(channels_used+x)%nphysical_out];
1621 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1623 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1627 if (port.length() && track->connect_output (track->output (x), port, this)) {
1632 channels_used += track->n_inputs ().n_midi();
1636 track->midi_diskstream()->non_realtime_input_change();
1638 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1639 //track->set_remote_control_id (control_id);
1641 new_routes.push_back (track);
1642 ret.push_back (track);
1645 catch (failed_constructor &err) {
1646 error << _("Session: could not create new midi track.") << endmsg;
1649 /* we need to get rid of this, since the track failed to be created */
1650 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1653 RCUWriter<DiskstreamList> writer (diskstreams);
1654 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1655 ds->remove (track->midi_diskstream());
1662 catch (AudioEngine::PortRegistrationFailure& pfe) {
1664 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;
1667 /* we need to get rid of this, since the track failed to be created */
1668 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1671 RCUWriter<DiskstreamList> writer (diskstreams);
1672 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1673 ds->remove (track->midi_diskstream());
1684 if (!new_routes.empty()) {
1685 add_routes (new_routes, false);
1686 save_state (_current_snapshot_name);
1692 list<boost::shared_ptr<AudioTrack> >
1693 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1695 char track_name[32];
1696 uint32_t track_id = 0;
1698 uint32_t channels_used = 0;
1700 RouteList new_routes;
1701 list<boost::shared_ptr<AudioTrack> > ret;
1702 uint32_t control_id;
1704 /* count existing audio tracks */
1707 shared_ptr<RouteList> r = routes.reader ();
1709 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1710 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1711 if (!(*i)->is_hidden()) {
1713 channels_used += (*i)->n_inputs().n_audio();
1719 vector<string> physinputs;
1720 vector<string> physoutputs;
1722 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1723 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1725 control_id = ntracks() + nbusses() + 1;
1729 /* check for duplicate route names, since we might have pre-existing
1730 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1731 save, close,restart,add new route - first named route is now
1739 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1741 if (route_by_name (track_name) == 0) {
1745 } while (track_id < (UINT_MAX-1));
1747 shared_ptr<AudioTrack> track;
1750 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1752 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1753 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1754 input_channels, output_channels)
1759 if (!physinputs.empty()) {
1760 uint32_t nphysical_in = physinputs.size();
1762 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1766 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1767 port = physinputs[(channels_used+x)%nphysical_in];
1770 if (port.length() && track->connect_input (track->input (x), port, this)) {
1776 if (!physoutputs.empty()) {
1777 uint32_t nphysical_out = physoutputs.size();
1779 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1783 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1784 port = physoutputs[(channels_used+x)%nphysical_out];
1785 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1787 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1791 if (port.length() && track->connect_output (track->output (x), port, this)) {
1797 channels_used += track->n_inputs ().n_audio();
1799 track->audio_diskstream()->non_realtime_input_change();
1801 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1802 track->set_remote_control_id (control_id);
1805 new_routes.push_back (track);
1806 ret.push_back (track);
1809 catch (failed_constructor &err) {
1810 error << _("Session: could not create new audio track.") << endmsg;
1813 /* we need to get rid of this, since the track failed to be created */
1814 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1817 RCUWriter<DiskstreamList> writer (diskstreams);
1818 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1819 ds->remove (track->audio_diskstream());
1826 catch (AudioEngine::PortRegistrationFailure& pfe) {
1828 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;
1831 /* we need to get rid of this, since the track failed to be created */
1832 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1835 RCUWriter<DiskstreamList> writer (diskstreams);
1836 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1837 ds->remove (track->audio_diskstream());
1848 if (!new_routes.empty()) {
1849 add_routes (new_routes, true);
1856 Session::set_remote_control_ids ()
1858 RemoteModel m = Config->get_remote_model();
1860 shared_ptr<RouteList> r = routes.reader ();
1862 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1863 if ( MixerOrdered == m) {
1864 long order = (*i)->order_key(N_("signal"));
1865 (*i)->set_remote_control_id( order+1 );
1866 } else if ( EditorOrdered == m) {
1867 long order = (*i)->order_key(N_("editor"));
1868 (*i)->set_remote_control_id( order+1 );
1869 } else if ( UserOrdered == m) {
1870 //do nothing ... only changes to remote id's are initiated by user
1877 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1880 uint32_t bus_id = 1;
1882 uint32_t channels_used = 0;
1885 uint32_t control_id;
1887 /* count existing audio busses */
1890 shared_ptr<RouteList> r = routes.reader ();
1892 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1893 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1895 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1898 channels_used += (*i)->n_inputs().n_audio();
1904 vector<string> physinputs;
1905 vector<string> physoutputs;
1907 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1908 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1910 n_physical_audio_outputs = physoutputs.size();
1911 n_physical_audio_inputs = physinputs.size();
1913 control_id = ntracks() + nbusses() + 1;
1918 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1922 if (route_by_name (bus_name) == 0) {
1926 } while (bus_id < (UINT_MAX-1));
1929 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1931 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1932 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1933 input_channels, output_channels)
1941 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1945 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1946 port = physinputs[((n+x)%n_physical_audio_inputs)];
1949 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1955 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1958 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1959 port = physoutputs[((n+x)%n_physical_outputs)];
1960 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1962 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1966 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1971 channels_used += bus->n_inputs ().n_audio();
1973 bus->set_remote_control_id (control_id);
1976 ret.push_back (bus);
1980 catch (failed_constructor &err) {
1981 error << _("Session: could not create new audio route.") << endmsg;
1985 catch (AudioEngine::PortRegistrationFailure& pfe) {
1986 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;
1996 add_routes (ret, true);
2004 Session::add_routes (RouteList& new_routes, bool save)
2007 RCUWriter<RouteList> writer (routes);
2008 shared_ptr<RouteList> r = writer.get_copy ();
2009 r->insert (r->end(), new_routes.begin(), new_routes.end());
2010 resort_routes_using (r);
2013 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2015 boost::weak_ptr<Route> wpr (*x);
2017 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2018 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2019 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2020 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2022 if ((*x)->is_master()) {
2026 if ((*x)->is_control()) {
2027 _control_out = (*x);
2030 /* only busses get automatic bundles formed */
2032 if (!boost::dynamic_pointer_cast<Track> (*x)) {
2033 add_bundle ((*x)->bundle_for_inputs());
2034 add_bundle ((*x)->bundle_for_outputs());
2038 if (_control_out && IO::connecting_legal) {
2040 vector<string> cports;
2041 uint32_t ni = _control_out->n_inputs().n_audio();
2043 for (uint32_t n = 0; n < ni; ++n) {
2044 cports.push_back (_control_out->input(n)->name());
2047 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2048 (*x)->set_control_outs (cports);
2055 save_state (_current_snapshot_name);
2058 RouteAdded (new_routes); /* EMIT SIGNAL */
2062 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2064 /* need to do this in case we're rolling at the time, to prevent false underruns */
2065 dstream->do_refill_with_alloc ();
2067 dstream->set_block_size (current_block_size);
2070 RCUWriter<DiskstreamList> writer (diskstreams);
2071 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2072 ds->push_back (dstream);
2073 /* writer goes out of scope, copies ds back to main */
2076 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2077 /* this will connect to future changes, and check the current length */
2078 diskstream_playlist_changed (dstream);
2080 dstream->prepare ();
2085 Session::remove_route (shared_ptr<Route> route)
2088 RCUWriter<RouteList> writer (routes);
2089 shared_ptr<RouteList> rs = writer.get_copy ();
2093 /* deleting the master out seems like a dumb
2094 idea, but its more of a UI policy issue
2098 if (route == _master_out) {
2099 _master_out = shared_ptr<Route> ();
2102 if (route == _control_out) {
2103 _control_out = shared_ptr<Route> ();
2105 /* cancel control outs for all routes */
2107 vector<string> empty;
2109 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2110 (*r)->set_control_outs (empty);
2114 update_route_solo_state ();
2116 /* writer goes out of scope, forces route list update */
2120 boost::shared_ptr<Diskstream> ds;
2122 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2123 ds = t->diskstream();
2129 RCUWriter<DiskstreamList> dsl (diskstreams);
2130 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2135 find_current_end ();
2137 // We need to disconnect the routes inputs and outputs
2139 route->disconnect_inputs (0);
2140 route->disconnect_outputs (0);
2142 update_latency_compensation (false, false);
2145 /* get rid of it from the dead wood collection in the route list manager */
2147 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2151 /* try to cause everyone to drop their references */
2153 route->drop_references ();
2155 sync_order_keys (N_("session"));
2157 /* save the new state of the world */
2159 if (save_state (_current_snapshot_name)) {
2160 save_history (_current_snapshot_name);
2165 Session::route_mute_changed (void* src)
2171 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2173 if (solo_update_disabled) {
2179 boost::shared_ptr<Route> route = wpr.lock ();
2182 /* should not happen */
2183 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2187 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2189 shared_ptr<RouteList> r = routes.reader ();
2191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2193 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2197 /* don't mess with busses */
2199 if (dynamic_cast<Track*>((*i).get()) == 0) {
2205 /* don't mess with tracks */
2207 if (dynamic_cast<Track*>((*i).get()) != 0) {
2212 if ((*i) != route &&
2213 ((*i)->mix_group () == 0 ||
2214 (*i)->mix_group () != route->mix_group () ||
2215 !route->mix_group ()->is_active())) {
2217 if ((*i)->soloed()) {
2219 /* if its already soloed, and solo latching is enabled,
2220 then leave it as it is.
2223 if (Config->get_solo_latched()) {
2230 solo_update_disabled = true;
2231 (*i)->set_solo (false, src);
2232 solo_update_disabled = false;
2236 bool something_soloed = false;
2237 bool same_thing_soloed = false;
2238 bool signal = false;
2240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2241 if ((*i)->soloed()) {
2242 something_soloed = true;
2243 if (dynamic_cast<Track*>((*i).get())) {
2245 same_thing_soloed = true;
2250 same_thing_soloed = true;
2258 if (something_soloed != currently_soloing) {
2260 currently_soloing = something_soloed;
2263 modify_solo_mute (is_track, same_thing_soloed);
2266 SoloActive (currently_soloing); /* 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 (dynamic_cast<Track*>((*i).get())) {
2297 if (mute != currently_soloing) {
2299 currently_soloing = mute;
2302 if (!is_track && !mute) {
2304 /* nothing is soloed */
2306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2307 (*i)->set_solo_mute (false);
2317 modify_solo_mute (is_track, mute);
2320 SoloActive (currently_soloing);
2325 Session::modify_solo_mute (bool is_track, bool mute)
2327 shared_ptr<RouteList> r = routes.reader ();
2329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2333 /* only alter track solo mute */
2335 if (dynamic_cast<Track*>((*i).get())) {
2336 if ((*i)->soloed()) {
2337 (*i)->set_solo_mute (!mute);
2339 (*i)->set_solo_mute (mute);
2345 /* only alter bus solo mute */
2347 if (!dynamic_cast<Track*>((*i).get())) {
2349 if ((*i)->soloed()) {
2351 (*i)->set_solo_mute (false);
2355 /* don't mute master or control outs
2356 in response to another bus solo
2359 if ((*i) != _master_out &&
2360 (*i) != _control_out) {
2361 (*i)->set_solo_mute (mute);
2372 Session::catch_up_on_solo ()
2374 /* this is called after set_state() to catch the full solo
2375 state, which can't be correctly determined on a per-route
2376 basis, but needs the global overview that only the session
2379 update_route_solo_state();
2383 Session::catch_up_on_solo_mute_override ()
2385 if (Config->get_solo_model() != InverseMute) {
2389 /* this is called whenever the param solo-mute-override is
2392 shared_ptr<RouteList> r = routes.reader ();
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 (*i)->catch_up_on_solo_mute_override ();
2400 Session::route_by_name (string name)
2402 shared_ptr<RouteList> r = routes.reader ();
2404 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2405 if ((*i)->name() == name) {
2410 return shared_ptr<Route> ((Route*) 0);
2414 Session::route_by_id (PBD::ID id)
2416 shared_ptr<RouteList> r = routes.reader ();
2418 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2419 if ((*i)->id() == id) {
2424 return shared_ptr<Route> ((Route*) 0);
2428 Session::route_by_remote_id (uint32_t id)
2430 shared_ptr<RouteList> r = routes.reader ();
2432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2433 if ((*i)->remote_control_id() == id) {
2438 return shared_ptr<Route> ((Route*) 0);
2442 Session::find_current_end ()
2444 if (_state_of_the_state & Loading) {
2448 nframes_t max = get_maximum_extent ();
2450 if (max > end_location->end()) {
2451 end_location->set_end (max);
2453 DurationChanged(); /* EMIT SIGNAL */
2458 Session::get_maximum_extent () const
2463 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2465 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2466 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2468 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2469 if ((me = pl->get_maximum_extent()) > max) {
2477 boost::shared_ptr<Diskstream>
2478 Session::diskstream_by_name (string name)
2480 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2482 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2483 if ((*i)->name() == name) {
2488 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2491 boost::shared_ptr<Diskstream>
2492 Session::diskstream_by_id (const PBD::ID& id)
2494 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2496 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2497 if ((*i)->id() == id) {
2502 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2505 /* Region management */
2508 Session::new_region_name (string old)
2510 string::size_type last_period;
2512 string::size_type len = old.length() + 64;
2515 if ((last_period = old.find_last_of ('.')) == string::npos) {
2517 /* no period present - add one explicitly */
2520 last_period = old.length() - 1;
2525 number = atoi (old.substr (last_period+1).c_str());
2529 while (number < (UINT_MAX-1)) {
2531 RegionList::const_iterator i;
2536 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2539 for (i = regions.begin(); i != regions.end(); ++i) {
2540 if (i->second->name() == sbuf) {
2545 if (i == regions.end()) {
2550 if (number != (UINT_MAX-1)) {
2554 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2559 Session::region_name (string& result, string base, bool newlevel)
2564 assert(base.find("/") == string::npos);
2568 Glib::Mutex::Lock lm (region_lock);
2570 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2579 string::size_type pos;
2581 pos = base.find_last_of ('.');
2583 /* pos may be npos, but then we just use entire base */
2585 subbase = base.substr (0, pos);
2590 Glib::Mutex::Lock lm (region_lock);
2592 map<string,uint32_t>::iterator x;
2596 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2598 region_name_map[subbase] = 1;
2601 snprintf (buf, sizeof (buf), ".%d", x->second);
2612 Session::add_region (boost::shared_ptr<Region> region)
2614 vector<boost::shared_ptr<Region> > v;
2615 v.push_back (region);
2620 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2625 Glib::Mutex::Lock lm (region_lock);
2627 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2629 boost::shared_ptr<Region> region = *ii;
2633 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2637 RegionList::iterator x;
2639 for (x = regions.begin(); x != regions.end(); ++x) {
2641 if (region->region_list_equivalent (x->second)) {
2646 if (x == regions.end()) {
2648 pair<RegionList::key_type,RegionList::mapped_type> entry;
2650 entry.first = region->id();
2651 entry.second = region;
2653 pair<RegionList::iterator,bool> x = regions.insert (entry);
2665 /* mark dirty because something has changed even if we didn't
2666 add the region to the region list.
2673 vector<boost::weak_ptr<Region> > v;
2674 boost::shared_ptr<Region> first_r;
2676 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2678 boost::shared_ptr<Region> region = *ii;
2682 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2685 v.push_back (region);
2692 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2693 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2695 update_region_name_map (region);
2699 RegionsAdded (v); /* EMIT SIGNAL */
2705 Session::update_region_name_map (boost::shared_ptr<Region> region)
2707 string::size_type last_period = region->name().find_last_of ('.');
2709 if (last_period != string::npos && last_period < region->name().length() - 1) {
2711 string base = region->name().substr (0, last_period);
2712 string number = region->name().substr (last_period+1);
2713 map<string,uint32_t>::iterator x;
2715 /* note that if there is no number, we get zero from atoi,
2719 region_name_map[base] = atoi (number);
2724 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2726 boost::shared_ptr<Region> region (weak_region.lock ());
2732 if (what_changed & Region::HiddenChanged) {
2733 /* relay hidden changes */
2734 RegionHiddenChange (region);
2737 if (what_changed & NameChanged) {
2738 update_region_name_map (region);
2743 Session::remove_region (boost::weak_ptr<Region> weak_region)
2745 RegionList::iterator i;
2746 boost::shared_ptr<Region> region (weak_region.lock ());
2752 bool removed = false;
2755 Glib::Mutex::Lock lm (region_lock);
2757 if ((i = regions.find (region->id())) != regions.end()) {
2763 /* mark dirty because something has changed even if we didn't
2764 remove the region from the region list.
2770 RegionRemoved(region); /* EMIT SIGNAL */
2774 boost::shared_ptr<Region>
2775 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2777 RegionList::iterator i;
2778 boost::shared_ptr<Region> region;
2780 Glib::Mutex::Lock lm (region_lock);
2782 for (i = regions.begin(); i != regions.end(); ++i) {
2786 if (region->whole_file()) {
2788 if (child->source_equivalent (region)) {
2794 return boost::shared_ptr<Region> ();
2798 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2800 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2801 (*i)->get_region_list_equivalent_regions (region, result);
2805 Session::destroy_region (boost::shared_ptr<Region> region)
2807 vector<boost::shared_ptr<Source> > srcs;
2810 if (region->playlist()) {
2811 region->playlist()->destroy_region (region);
2814 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2815 srcs.push_back (region->source (n));
2819 region->drop_references ();
2821 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2823 (*i)->mark_for_remove ();
2824 (*i)->drop_references ();
2826 cerr << "source was not used by any playlist\n";
2833 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2835 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2836 destroy_region (*i);
2842 Session::remove_last_capture ()
2844 list<boost::shared_ptr<Region> > r;
2846 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2848 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2849 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2852 r.insert (r.end(), l.begin(), l.end());
2857 destroy_regions (r);
2859 save_state (_current_snapshot_name);
2865 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2871 /* Source Management */
2873 Session::add_source (boost::shared_ptr<Source> source)
2875 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2876 pair<SourceMap::iterator,bool> result;
2878 entry.first = source->id();
2879 entry.second = source;
2882 Glib::Mutex::Lock lm (source_lock);
2883 result = sources.insert (entry);
2886 if (result.second) {
2887 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2891 boost::shared_ptr<AudioFileSource> afs;
2893 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2894 if (Config->get_auto_analyse_audio()) {
2895 Analyser::queue_source_for_analysis (source, false);
2901 Session::remove_source (boost::weak_ptr<Source> src)
2903 SourceMap::iterator i;
2904 boost::shared_ptr<Source> source = src.lock();
2911 Glib::Mutex::Lock lm (source_lock);
2913 if ((i = sources.find (source->id())) != sources.end()) {
2918 if (!_state_of_the_state & InCleanup) {
2920 /* save state so we don't end up with a session file
2921 referring to non-existent sources.
2924 save_state (_current_snapshot_name);
2928 boost::shared_ptr<Source>
2929 Session::source_by_id (const PBD::ID& id)
2931 Glib::Mutex::Lock lm (source_lock);
2932 SourceMap::iterator i;
2933 boost::shared_ptr<Source> source;
2935 if ((i = sources.find (id)) != sources.end()) {
2943 boost::shared_ptr<Source>
2944 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2946 Glib::Mutex::Lock lm (source_lock);
2948 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2949 cerr << "comparing " << path << " with " << i->second->name() << endl;
2950 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2952 if (afs && afs->path() == path && chn == afs->channel()) {
2957 return boost::shared_ptr<Source>();
2961 Session::peak_path (Glib::ustring base) const
2963 sys::path peakfile_path(_session_dir->peak_path());
2964 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2965 return peakfile_path.to_string();
2969 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2972 string old_basename = PBD::basename_nosuffix (oldname);
2973 string new_legalized = legalize_for_path (newname);
2975 /* note: we know (or assume) the old path is already valid */
2979 /* destructive file sources have a name of the form:
2981 /path/to/Tnnnn-NAME(%[LR])?.wav
2983 the task here is to replace NAME with the new name.
2986 /* find last slash */
2990 string::size_type slash;
2991 string::size_type dash;
2993 if ((slash = path.find_last_of ('/')) == string::npos) {
2997 dir = path.substr (0, slash+1);
2999 /* '-' is not a legal character for the NAME part of the path */
3001 if ((dash = path.find_last_of ('-')) == string::npos) {
3005 prefix = path.substr (slash+1, dash-(slash+1));
3010 path += new_legalized;
3011 path += ".wav"; /* XXX gag me with a spoon */
3015 /* non-destructive file sources have a name of the form:
3017 /path/to/NAME-nnnnn(%[LR])?.wav
3019 the task here is to replace NAME with the new name.
3024 string::size_type slash;
3025 string::size_type dash;
3026 string::size_type postfix;
3028 /* find last slash */
3030 if ((slash = path.find_last_of ('/')) == string::npos) {
3034 dir = path.substr (0, slash+1);
3036 /* '-' is not a legal character for the NAME part of the path */
3038 if ((dash = path.find_last_of ('-')) == string::npos) {
3042 suffix = path.substr (dash+1);
3044 // Suffix is now everything after the dash. Now we need to eliminate
3045 // the nnnnn part, which is done by either finding a '%' or a '.'
3047 postfix = suffix.find_last_of ("%");
3048 if (postfix == string::npos) {
3049 postfix = suffix.find_last_of ('.');
3052 if (postfix != string::npos) {
3053 suffix = suffix.substr (postfix);
3055 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3059 const uint32_t limit = 10000;
3060 char buf[PATH_MAX+1];
3062 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3064 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3066 if (access (buf, F_OK) != 0) {
3074 error << "FATAL ERROR! Could not find a " << endl;
3083 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3087 char buf[PATH_MAX+1];
3088 const uint32_t limit = 10000;
3092 legalized = legalize_for_path (name);
3094 /* find a "version" of the file name that doesn't exist in
3095 any of the possible directories.
3098 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3100 vector<space_and_path>::iterator i;
3101 uint32_t existing = 0;
3103 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3105 SessionDirectory sdir((*i).path);
3107 spath = sdir.sound_path().to_string();
3111 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3112 } else if (nchan == 2) {
3114 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3116 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3118 } else if (nchan < 26) {
3119 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3121 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3130 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3131 } else if (nchan == 2) {
3133 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3135 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3137 } else if (nchan < 26) {
3138 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3140 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3144 if (sys::exists(buf)) {
3150 if (existing == 0) {
3155 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3157 throw failed_constructor();
3161 /* we now have a unique name for the file, but figure out where to
3167 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3169 spath = sdir.sound_path().to_string();
3172 string::size_type pos = foo.find_last_of ('/');
3174 if (pos == string::npos) {
3177 spath += foo.substr (pos + 1);
3183 boost::shared_ptr<AudioFileSource>
3184 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3186 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3187 return boost::dynamic_pointer_cast<AudioFileSource> (
3188 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3191 // FIXME: _terrible_ code duplication
3193 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3196 string old_basename = PBD::basename_nosuffix (oldname);
3197 string new_legalized = legalize_for_path (newname);
3199 /* note: we know (or assume) the old path is already valid */
3203 /* destructive file sources have a name of the form:
3205 /path/to/Tnnnn-NAME(%[LR])?.wav
3207 the task here is to replace NAME with the new name.
3210 /* find last slash */
3214 string::size_type slash;
3215 string::size_type dash;
3217 if ((slash = path.find_last_of ('/')) == string::npos) {
3221 dir = path.substr (0, slash+1);
3223 /* '-' is not a legal character for the NAME part of the path */
3225 if ((dash = path.find_last_of ('-')) == string::npos) {
3229 prefix = path.substr (slash+1, dash-(slash+1));
3234 path += new_legalized;
3235 path += ".mid"; /* XXX gag me with a spoon */
3239 /* non-destructive file sources have a name of the form:
3241 /path/to/NAME-nnnnn(%[LR])?.wav
3243 the task here is to replace NAME with the new name.
3248 string::size_type slash;
3249 string::size_type dash;
3250 string::size_type postfix;
3252 /* find last slash */
3254 if ((slash = path.find_last_of ('/')) == string::npos) {
3258 dir = path.substr (0, slash+1);
3260 /* '-' is not a legal character for the NAME part of the path */
3262 if ((dash = path.find_last_of ('-')) == string::npos) {
3266 suffix = path.substr (dash+1);
3268 // Suffix is now everything after the dash. Now we need to eliminate
3269 // the nnnnn part, which is done by either finding a '%' or a '.'
3271 postfix = suffix.find_last_of ("%");
3272 if (postfix == string::npos) {
3273 postfix = suffix.find_last_of ('.');
3276 if (postfix != string::npos) {
3277 suffix = suffix.substr (postfix);
3279 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3283 const uint32_t limit = 10000;
3284 char buf[PATH_MAX+1];
3286 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3288 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3290 if (access (buf, F_OK) != 0) {
3298 error << "FATAL ERROR! Could not find a " << endl;
3307 Session::midi_path_from_name (string name)
3311 char buf[PATH_MAX+1];
3312 const uint32_t limit = 10000;
3316 legalized = legalize_for_path (name);
3318 /* find a "version" of the file name that doesn't exist in
3319 any of the possible directories.
3322 for (cnt = 1; cnt <= limit; ++cnt) {
3324 vector<space_and_path>::iterator i;
3325 uint32_t existing = 0;
3327 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3329 SessionDirectory sdir((*i).path);
3331 sys::path p = sdir.midi_path();
3335 spath = p.to_string();
3337 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3339 if (sys::exists (buf)) {
3344 if (existing == 0) {
3349 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3350 throw failed_constructor();
3354 /* we now have a unique name for the file, but figure out where to
3360 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3362 spath = sdir.midi_path().to_string();
3365 string::size_type pos = foo.find_last_of ('/');
3367 if (pos == string::npos) {
3370 spath += foo.substr (pos + 1);
3376 boost::shared_ptr<MidiSource>
3377 Session::create_midi_source_for_session (MidiDiskstream& ds)
3379 string mpath = midi_path_from_name (ds.name());
3381 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3385 /* Playlist management */
3387 boost::shared_ptr<Playlist>
3388 Session::playlist_by_name (string name)
3390 Glib::Mutex::Lock lm (playlist_lock);
3391 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3392 if ((*i)->name() == name) {
3396 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3397 if ((*i)->name() == name) {
3402 return boost::shared_ptr<Playlist>();
3406 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3408 Glib::Mutex::Lock lm (playlist_lock);
3409 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3410 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3411 list.push_back (*i);
3414 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3415 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3416 list.push_back (*i);
3422 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3424 if (playlist->hidden()) {
3429 Glib::Mutex::Lock lm (playlist_lock);
3430 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3431 playlists.insert (playlists.begin(), playlist);
3432 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3433 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3438 playlist->release();
3443 PlaylistAdded (playlist); /* EMIT SIGNAL */
3447 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3450 Glib::Mutex::Lock lm (playlist_lock);
3451 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3454 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3461 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3463 boost::shared_ptr<Playlist> pl(wpl.lock());
3469 PlaylistList::iterator x;
3472 /* its not supposed to be visible */
3477 Glib::Mutex::Lock lm (playlist_lock);
3481 unused_playlists.insert (pl);
3483 if ((x = playlists.find (pl)) != playlists.end()) {
3484 playlists.erase (x);
3490 playlists.insert (pl);
3492 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3493 unused_playlists.erase (x);
3500 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3502 if (_state_of_the_state & Deletion) {
3506 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3513 Glib::Mutex::Lock lm (playlist_lock);
3515 PlaylistList::iterator i;
3517 i = find (playlists.begin(), playlists.end(), playlist);
3518 if (i != playlists.end()) {
3519 playlists.erase (i);
3522 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3523 if (i != unused_playlists.end()) {
3524 unused_playlists.erase (i);
3531 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3535 Session::set_audition (boost::shared_ptr<Region> r)
3537 pending_audition_region = r;
3538 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3539 schedule_butler_transport_work ();
3543 Session::audition_playlist ()
3545 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3546 ev->region.reset ();
3551 Session::non_realtime_set_audition ()
3553 if (!pending_audition_region) {
3554 auditioner->audition_current_playlist ();
3556 auditioner->audition_region (pending_audition_region);
3557 pending_audition_region.reset ();
3559 AuditionActive (true); /* EMIT SIGNAL */
3563 Session::audition_region (boost::shared_ptr<Region> r)
3565 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3571 Session::cancel_audition ()
3573 if (auditioner->active()) {
3574 auditioner->cancel_audition ();
3575 AuditionActive (false); /* EMIT SIGNAL */
3580 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3582 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3586 Session::remove_empty_sounds ()
3588 vector<string> audio_filenames;
3590 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3592 Glib::Mutex::Lock lm (source_lock);
3594 TapeFileMatcher tape_file_matcher;
3596 remove_if (audio_filenames.begin(), audio_filenames.end(),
3597 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3599 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3601 sys::path audio_file_path (_session_dir->sound_path());
3603 audio_file_path /= *i;
3605 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3609 sys::remove (audio_file_path);
3610 const string peakfile = peak_path (audio_file_path.to_string());
3611 sys::remove (peakfile);
3613 catch (const sys::filesystem_error& err)
3615 error << err.what() << endmsg;
3622 Session::is_auditioning () const
3624 /* can be called before we have an auditioner object */
3626 return auditioner->active();
3633 Session::set_all_solo (bool yn)
3635 shared_ptr<RouteList> r = routes.reader ();
3637 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3638 if (!(*i)->is_hidden()) {
3639 (*i)->set_solo (yn, this);
3647 Session::set_all_mute (bool yn)
3649 shared_ptr<RouteList> r = routes.reader ();
3651 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3652 if (!(*i)->is_hidden()) {
3653 (*i)->set_mute (yn, this);
3661 Session::n_diskstreams () const
3665 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3667 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3668 if (!(*i)->hidden()) {
3676 Session::graph_reordered ()
3678 /* don't do this stuff if we are setting up connections
3679 from a set_state() call or creating new tracks.
3682 if (_state_of_the_state & InitialConnecting) {
3686 /* every track/bus asked for this to be handled but it was deferred because
3687 we were connecting. do it now.
3690 request_input_change_handling ();
3694 /* force all diskstreams to update their capture offset values to
3695 reflect any changes in latencies within the graph.
3698 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3700 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3701 (*i)->set_capture_offset ();
3706 Session::record_disenable_all ()
3708 record_enable_change_all (false);
3712 Session::record_enable_all ()
3714 record_enable_change_all (true);
3718 Session::record_enable_change_all (bool yn)
3720 shared_ptr<RouteList> r = routes.reader ();
3722 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3725 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3726 at->set_record_enable (yn, this);
3730 /* since we don't keep rec-enable state, don't mark session dirty */
3734 Session::add_processor (Processor* processor)
3737 PortInsert* port_insert;
3738 PluginInsert* plugin_insert;
3740 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3741 _port_inserts.insert (_port_inserts.begin(), port_insert);
3742 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3743 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3744 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3745 _sends.insert (_sends.begin(), send);
3747 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3751 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3757 Session::remove_processor (Processor* processor)
3760 PortInsert* port_insert;
3761 PluginInsert* plugin_insert;
3763 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3764 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3765 if (x != _port_inserts.end()) {
3766 insert_bitset[port_insert->bit_slot()] = false;
3767 _port_inserts.erase (x);
3769 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3770 _plugin_inserts.remove (plugin_insert);
3771 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3772 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3773 if (x != _sends.end()) {
3774 send_bitset[send->bit_slot()] = false;
3778 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3786 Session::available_capture_duration ()
3788 float sample_bytes_on_disk = 4.0; // keep gcc happy
3790 switch (Config->get_native_file_data_format()) {
3792 sample_bytes_on_disk = 4.0;
3796 sample_bytes_on_disk = 3.0;
3800 sample_bytes_on_disk = 2.0;
3804 /* impossible, but keep some gcc versions happy */
3805 fatal << string_compose (_("programming error: %1"),
3806 X_("illegal native file data format"))
3811 double scale = 4096.0 / sample_bytes_on_disk;
3813 if (_total_free_4k_blocks * scale > (double) max_frames) {
3817 return (nframes_t) floor (_total_free_4k_blocks * scale);
3821 Session::add_bundle (shared_ptr<Bundle> bundle)
3824 Glib::Mutex::Lock guard (bundle_lock);
3825 _bundles.push_back (bundle);
3828 BundleAdded (bundle); /* EMIT SIGNAL */
3834 Session::remove_bundle (shared_ptr<Bundle> bundle)
3836 bool removed = false;
3839 Glib::Mutex::Lock guard (bundle_lock);
3840 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3842 if (i != _bundles.end()) {
3849 BundleRemoved (bundle); /* EMIT SIGNAL */
3856 Session::bundle_by_name (string name) const
3858 Glib::Mutex::Lock lm (bundle_lock);
3860 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3861 if ((*i)->name() == name) {
3866 return boost::shared_ptr<Bundle> ();
3870 Session::tempo_map_changed (Change ignored)
3874 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3875 (*i)->update_after_tempo_map_change ();
3878 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3879 (*i)->update_after_tempo_map_change ();
3885 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3886 * the given count with the current block size.
3889 Session::ensure_buffers (ChanCount howmany)
3891 if (current_block_size == 0)
3892 return; // too early? (is this ok?)
3894 // We need at least 2 MIDI scratch buffers to mix/merge
3895 if (howmany.n_midi() < 2)
3896 howmany.set_midi(2);
3898 // FIXME: JACK needs to tell us maximum MIDI buffer size
3899 // Using nasty assumption (max # events == nframes) for now
3900 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3901 _mix_buffers->ensure_buffers(howmany, current_block_size);
3902 _silent_buffers->ensure_buffers(howmany, current_block_size);
3904 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3908 Session::next_insert_id ()
3910 /* this doesn't really loop forever. just think about it */
3913 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3914 if (!insert_bitset[n]) {
3915 insert_bitset[n] = true;
3921 /* none available, so resize and try again */
3923 insert_bitset.resize (insert_bitset.size() + 16, false);
3928 Session::next_send_id ()
3930 /* this doesn't really loop forever. just think about it */
3933 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3934 if (!send_bitset[n]) {
3935 send_bitset[n] = true;
3941 /* none available, so resize and try again */
3943 send_bitset.resize (send_bitset.size() + 16, false);
3948 Session::mark_send_id (uint32_t id)
3950 if (id >= send_bitset.size()) {
3951 send_bitset.resize (id+16, false);
3953 if (send_bitset[id]) {
3954 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3956 send_bitset[id] = true;
3960 Session::mark_insert_id (uint32_t id)
3962 if (id >= insert_bitset.size()) {
3963 insert_bitset.resize (id+16, false);
3965 if (insert_bitset[id]) {
3966 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3968 insert_bitset[id] = true;
3971 /* Named Selection management */
3974 Session::named_selection_by_name (string name)
3976 Glib::Mutex::Lock lm (named_selection_lock);
3977 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3978 if ((*i)->name == name) {
3986 Session::add_named_selection (NamedSelection* named_selection)
3989 Glib::Mutex::Lock lm (named_selection_lock);
3990 named_selections.insert (named_selections.begin(), named_selection);
3993 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3999 NamedSelectionAdded (); /* EMIT SIGNAL */
4003 Session::remove_named_selection (NamedSelection* named_selection)
4005 bool removed = false;
4008 Glib::Mutex::Lock lm (named_selection_lock);
4010 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4012 if (i != named_selections.end()) {
4014 named_selections.erase (i);
4021 NamedSelectionRemoved (); /* EMIT SIGNAL */
4026 Session::reset_native_file_format ()
4028 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4030 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4031 (*i)->reset_write_sources (false);
4036 Session::route_name_unique (string n) const
4038 shared_ptr<RouteList> r = routes.reader ();
4040 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4041 if ((*i)->name() == n) {
4050 Session::n_playlists () const
4052 Glib::Mutex::Lock lm (playlist_lock);
4053 return playlists.size();
4057 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4059 if (!force && howmany <= _npan_buffers) {
4063 if (_pan_automation_buffer) {
4065 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4066 delete [] _pan_automation_buffer[i];
4069 delete [] _pan_automation_buffer;
4072 _pan_automation_buffer = new pan_t*[howmany];
4074 for (uint32_t i = 0; i < howmany; ++i) {
4075 _pan_automation_buffer[i] = new pan_t[nframes];
4078 _npan_buffers = howmany;
4082 Session::freeze (InterThreadInfo& itt)
4084 shared_ptr<RouteList> r = routes.reader ();
4086 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4090 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4091 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4101 boost::shared_ptr<Region>
4102 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4103 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4105 boost::shared_ptr<Region> result;
4106 boost::shared_ptr<Playlist> playlist;
4107 boost::shared_ptr<AudioFileSource> fsource;
4109 char buf[PATH_MAX+1];
4110 ChanCount nchans(track.audio_diskstream()->n_channels());
4112 nframes_t this_chunk;
4115 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4116 const string sound_dir = sdir.sound_path().to_string();
4117 nframes_t len = end - start;
4120 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4121 end, start) << endmsg;
4125 // any bigger than this seems to cause stack overflows in called functions
4126 const nframes_t chunk_size = (128 * 1024)/4;
4128 g_atomic_int_set (&processing_prohibited, 1);
4130 /* call tree *MUST* hold route_lock */
4132 if ((playlist = track.diskstream()->playlist()) == 0) {
4136 /* external redirects will be a problem */
4138 if (track.has_external_redirects()) {
4142 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4144 for (x = 0; x < 99999; ++x) {
4145 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4146 if (access (buf, F_OK) != 0) {
4152 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4157 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4158 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4161 catch (failed_constructor& err) {
4162 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4166 srcs.push_back (fsource);
4169 /* XXX need to flush all redirects */
4174 /* create a set of reasonably-sized buffers */
4175 buffers.ensure_buffers(nchans, chunk_size);
4176 buffers.set_count(nchans);
4178 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4179 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4181 afs->prepare_for_peakfile_writes ();
4184 while (to_do && !itt.cancel) {
4186 this_chunk = min (to_do, chunk_size);
4188 if (track.export_stuff (buffers, start, this_chunk)) {
4193 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4194 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4197 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4203 start += this_chunk;
4204 to_do -= this_chunk;
4206 itt.progress = (float) (1.0 - ((double) to_do / len));
4215 xnow = localtime (&now);
4217 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4218 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4221 afs->update_header (position, *xnow, now);
4222 afs->flush_header ();
4226 /* construct a region to represent the bounced material */
4228 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4229 region_name_from_path (srcs.front()->name(), true));
4234 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4235 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4238 afs->mark_for_remove ();
4241 (*src)->drop_references ();
4245 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4246 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4249 afs->done_with_peakfile_writes ();
4253 g_atomic_int_set (&processing_prohibited, 0);
4259 Session::get_silent_buffers (ChanCount count)
4261 assert(_silent_buffers->available() >= count);
4262 _silent_buffers->set_count(count);
4264 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4265 for (size_t i= 0; i < count.get(*t); ++i) {
4266 _silent_buffers->get(*t, i).clear();
4270 return *_silent_buffers;
4274 Session::get_scratch_buffers (ChanCount count)
4276 if (count != ChanCount::ZERO) {
4277 assert(_scratch_buffers->available() >= count);
4278 _scratch_buffers->set_count(count);
4280 _scratch_buffers->set_count (_scratch_buffers->available());
4283 return *_scratch_buffers;
4287 Session::get_mix_buffers (ChanCount count)
4289 assert(_mix_buffers->available() >= count);
4290 _mix_buffers->set_count(count);
4291 return *_mix_buffers;
4295 Session::ntracks () const
4298 shared_ptr<RouteList> r = routes.reader ();
4300 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4301 if (dynamic_cast<Track*> ((*i).get())) {
4310 Session::nbusses () const
4313 shared_ptr<RouteList> r = routes.reader ();
4315 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4316 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4325 Session::add_automation_list(AutomationList *al)
4327 automation_lists[al->id()] = al;
4331 Session::compute_initial_length ()
4333 return _engine.frame_rate() * 60 * 5;
4337 Session::sync_order_keys (const char* base)
4339 if (!Config->get_sync_all_route_ordering()) {
4340 /* leave order keys as they are */
4344 boost::shared_ptr<RouteList> r = routes.reader ();
4346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4347 (*i)->sync_order_keys (base);
4350 Route::SyncOrderKeys (base); // EMIT SIGNAL
4354 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4356 Glib::Mutex::Lock lm (bundle_lock);
4357 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {