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/utils.h>
51 #include <ardour/audio_diskstream.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/audiofilesource.h>
55 #include <ardour/midi_diskstream.h>
56 #include <ardour/midi_playlist.h>
57 #include <ardour/midi_region.h>
58 #include <ardour/smf_source.h>
59 #include <ardour/auditioner.h>
60 #include <ardour/recent_sessions.h>
61 #include <ardour/io_processor.h>
62 #include <ardour/send.h>
63 #include <ardour/processor.h>
64 #include <ardour/plugin_insert.h>
65 #include <ardour/port_insert.h>
66 #include <ardour/auto_bundle.h>
67 #include <ardour/slave.h>
68 #include <ardour/tempo.h>
69 #include <ardour/audio_track.h>
70 #include <ardour/midi_track.h>
71 #include <ardour/cycle_timer.h>
72 #include <ardour/named_selection.h>
73 #include <ardour/crossfade.h>
74 #include <ardour/playlist.h>
75 #include <ardour/click.h>
76 #include <ardour/data_type.h>
77 #include <ardour/buffer_set.h>
78 #include <ardour/source_factory.h>
79 #include <ardour/region_factory.h>
80 #include <ardour/filename_extensions.h>
81 #include <ardour/session_directory.h>
82 #include <ardour/tape_file_matcher.h>
83 #include <ardour/analyser.h>
86 #include <ardour/osc.h>
92 using namespace ARDOUR;
94 using boost::shared_ptr;
97 static const int CPU_CACHE_ALIGN = 64;
99 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
102 bool Session::_disable_all_loaded_plugins = false;
104 Session::compute_peak_t Session::compute_peak = 0;
105 Session::find_peaks_t Session::find_peaks = 0;
106 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
107 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
108 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
110 sigc::signal<int> Session::AskAboutPendingState;
111 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
112 sigc::signal<void> Session::SendFeedback;
114 sigc::signal<void> Session::SMPTEOffsetChanged;
115 sigc::signal<void> Session::StartTimeChanged;
116 sigc::signal<void> Session::EndTimeChanged;
118 Session::Session (AudioEngine &eng,
119 const string& fullpath,
120 const string& snapshot_name,
124 _scratch_buffers(new BufferSet()),
125 _silent_buffers(new BufferSet()),
126 _mix_buffers(new BufferSet()),
127 _mmc_port (default_mmc_port),
128 _mtc_port (default_mtc_port),
129 _midi_port (default_midi_port),
130 _session_dir (new SessionDirectory(fullpath)),
131 pending_events (2048),
132 post_transport_work((PostTransportWork)0),
134 _send_smpte_update (false),
135 diskstreams (new DiskstreamList),
136 routes (new RouteList),
137 auditioner ((Auditioner*) 0),
138 _bundle_xml_node (0),
144 if (!eng.connected()) {
145 throw failed_constructor();
148 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
150 n_physical_outputs = _engine.n_physical_outputs();
151 n_physical_inputs = _engine.n_physical_inputs();
153 first_stage_init (fullpath, snapshot_name);
155 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
158 if (create (new_session, mix_template, compute_initial_length())) {
160 throw failed_constructor ();
164 if (second_stage_init (new_session)) {
166 throw failed_constructor ();
169 store_recent_sessions(_name, _path);
171 bool was_dirty = dirty();
173 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
175 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
178 DirtyChanged (); /* EMIT SIGNAL */
182 Session::Session (AudioEngine &eng,
184 string snapshot_name,
185 AutoConnectOption input_ac,
186 AutoConnectOption output_ac,
187 uint32_t control_out_channels,
188 uint32_t master_out_channels,
189 uint32_t requested_physical_in,
190 uint32_t requested_physical_out,
191 nframes_t initial_length)
194 _scratch_buffers(new BufferSet()),
195 _silent_buffers(new BufferSet()),
196 _mix_buffers(new BufferSet()),
197 _mmc_port (default_mmc_port),
198 _mtc_port (default_mtc_port),
199 _midi_port (default_midi_port),
200 _session_dir ( new SessionDirectory(fullpath)),
201 pending_events (2048),
202 post_transport_work((PostTransportWork)0),
204 _send_smpte_update (false),
205 diskstreams (new DiskstreamList),
206 routes (new RouteList),
207 _bundle_xml_node (0),
213 if (!eng.connected()) {
214 throw failed_constructor();
217 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
219 n_physical_outputs = _engine.n_physical_outputs();
220 n_physical_inputs = _engine.n_physical_inputs();
222 if (n_physical_inputs) {
223 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
226 if (n_physical_outputs) {
227 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
230 first_stage_init (fullpath, snapshot_name);
232 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
235 if (create (new_session, string(), initial_length)) {
237 throw failed_constructor ();
242 /* set up Master Out and Control Out if necessary */
247 if (control_out_channels) {
248 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
249 r->set_remote_control_id (control_id++);
254 if (master_out_channels) {
255 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
256 r->set_remote_control_id (control_id);
260 /* prohibit auto-connect to master, because there isn't one */
261 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
265 add_routes (rl, false);
270 Config->set_input_auto_connect (input_ac);
271 Config->set_output_auto_connect (output_ac);
273 if (second_stage_init (new_session)) {
275 throw failed_constructor ();
278 store_recent_sessions (_name, _path);
280 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
282 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
293 /* if we got to here, leaving pending capture state around
297 remove_pending_capture_state ();
299 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
301 _engine.remove_session ();
303 GoingAway (); /* EMIT SIGNAL */
309 /* clear history so that no references to objects are held any more */
313 /* clear state tree so that no references to objects are held any more */
319 terminate_butler_thread ();
320 //terminate_midi_thread ();
322 if (click_data && click_data != default_click) {
323 delete [] click_data;
326 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
327 delete [] click_emphasis_data;
332 delete _scratch_buffers;
333 delete _silent_buffers;
336 AudioDiskstream::free_working_buffers();
338 Route::SyncOrderKeys.clear();
340 #undef TRACK_DESTRUCTION
341 #ifdef TRACK_DESTRUCTION
342 cerr << "delete named selections\n";
343 #endif /* TRACK_DESTRUCTION */
344 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
345 NamedSelectionList::iterator tmp;
354 #ifdef TRACK_DESTRUCTION
355 cerr << "delete playlists\n";
356 #endif /* TRACK_DESTRUCTION */
357 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
358 PlaylistList::iterator tmp;
363 (*i)->drop_references ();
368 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
369 PlaylistList::iterator tmp;
374 (*i)->drop_references ();
380 unused_playlists.clear ();
382 #ifdef TRACK_DESTRUCTION
383 cerr << "delete regions\n";
384 #endif /* TRACK_DESTRUCTION */
386 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
387 RegionList::iterator tmp;
392 i->second->drop_references ();
399 #ifdef TRACK_DESTRUCTION
400 cerr << "delete routes\n";
401 #endif /* TRACK_DESTRUCTION */
403 RCUWriter<RouteList> writer (routes);
404 boost::shared_ptr<RouteList> r = writer.get_copy ();
405 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
406 (*i)->drop_references ();
409 /* writer goes out of scope and updates master */
414 #ifdef TRACK_DESTRUCTION
415 cerr << "delete diskstreams\n";
416 #endif /* TRACK_DESTRUCTION */
418 RCUWriter<DiskstreamList> dwriter (diskstreams);
419 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
420 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
421 (*i)->drop_references ();
425 diskstreams.flush ();
427 #ifdef TRACK_DESTRUCTION
428 cerr << "delete audio sources\n";
429 #endif /* TRACK_DESTRUCTION */
430 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
431 SourceMap::iterator tmp;
436 i->second->drop_references ();
442 #ifdef TRACK_DESTRUCTION
443 cerr << "delete mix groups\n";
444 #endif /* TRACK_DESTRUCTION */
445 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
446 list<RouteGroup*>::iterator tmp;
456 #ifdef TRACK_DESTRUCTION
457 cerr << "delete edit groups\n";
458 #endif /* TRACK_DESTRUCTION */
459 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
460 list<RouteGroup*>::iterator tmp;
470 if (butler_mixdown_buffer) {
471 delete [] butler_mixdown_buffer;
474 if (butler_gain_buffer) {
475 delete [] butler_gain_buffer;
478 Crossfade::set_buffer_size (0);
486 Session::set_worst_io_latencies ()
488 _worst_output_latency = 0;
489 _worst_input_latency = 0;
491 if (!_engine.connected()) {
495 boost::shared_ptr<RouteList> r = routes.reader ();
497 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
498 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
499 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
504 Session::when_engine_running ()
506 string first_physical_output;
508 /* we don't want to run execute this again */
510 BootMessage (_("Set block size and sample rate"));
512 set_block_size (_engine.frames_per_cycle());
513 set_frame_rate (_engine.frame_rate());
515 BootMessage (_("Using configuration"));
517 Config->map_parameters (mem_fun (*this, &Session::config_changed));
519 /* every time we reconnect, recompute worst case output latencies */
521 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
523 if (synced_to_jack()) {
524 _engine.transport_stop ();
527 if (Config->get_jack_time_master()) {
528 _engine.transport_locate (_transport_frame);
536 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
538 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
540 /* existing state for Click */
542 if (_click_io->set_state (*child->children().front()) == 0) {
544 _clicking = Config->get_clicking ();
548 error << _("could not setup Click I/O") << endmsg;
554 /* default state for Click */
556 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
558 if (first_physical_output.length()) {
559 if (_click_io->add_output_port (first_physical_output, this)) {
560 // relax, even though its an error
562 _clicking = Config->get_clicking ();
568 catch (failed_constructor& err) {
569 error << _("cannot setup Click I/O") << endmsg;
572 BootMessage (_("Compute I/O Latencies"));
574 set_worst_io_latencies ();
577 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
580 /* Create a set of Bundle objects that map
581 to the physical outputs currently available
584 BootMessage (_("Set up standard connections"));
588 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
590 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
592 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
594 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
599 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
601 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
603 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
605 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
612 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
614 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
616 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
618 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
619 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
624 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
626 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
628 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
630 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
631 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
640 /* create master/control ports */
645 /* force the master to ignore any later call to this */
647 if (_master_out->pending_state_node) {
648 _master_out->ports_became_legal();
651 /* no panner resets till we are through */
653 _master_out->defer_pan_reset ();
655 while (_master_out->n_inputs().n_audio()
656 < _master_out->input_maximum().n_audio()) {
657 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
658 error << _("cannot setup master inputs")
664 while (_master_out->n_outputs().n_audio()
665 < _master_out->output_maximum().n_audio()) {
666 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
667 error << _("cannot setup master outputs")
674 _master_out->allow_pan_reset ();
678 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
680 c->set_channels (_master_out->n_inputs().n_total());
681 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
682 c->set_port (n, _master_out->input(n)->name());
687 BootMessage (_("Setup signal flow and plugins"));
691 /* catch up on send+insert cnts */
693 BootMessage (_("Catch up with send/insert state"));
697 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
700 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
701 if (id > insert_cnt) {
709 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
712 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
720 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
722 /* hook us up to the engine */
724 BootMessage (_("Connect to engine"));
726 _engine.set_session (this);
731 BootMessage (_("OSC startup"));
733 osc->set_session (*this);
739 Session::hookup_io ()
741 /* stop graph reordering notifications from
742 causing resorts, etc.
745 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
748 if (auditioner == 0) {
750 /* we delay creating the auditioner till now because
751 it makes its own connections to ports.
752 the engine has to be running for this to work.
756 auditioner.reset (new Auditioner (*this));
759 catch (failed_constructor& err) {
760 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
764 /* Tell all IO objects to create their ports */
770 vector<string> cports;
772 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
773 if (_control_out->add_input_port ("", this)) {
774 error << _("cannot setup control inputs")
780 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
781 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
782 error << _("cannot set up master outputs")
790 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
792 for (n = 0; n < ni; ++n) {
793 cports.push_back (_control_out->input(n)->name());
796 boost::shared_ptr<RouteList> r = routes.reader ();
798 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
799 (*x)->set_control_outs (cports);
803 /* load bundles, which we may have postponed earlier on */
804 if (_bundle_xml_node) {
805 load_bundles (*_bundle_xml_node);
806 delete _bundle_xml_node;
809 /* Tell all IO objects to connect themselves together */
811 IO::enable_connecting ();
813 /* Now reset all panners */
815 IO::reset_panners ();
817 /* Anyone who cares about input state, wake up and do something */
819 IOConnectionsComplete (); /* EMIT SIGNAL */
821 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
824 /* now handle the whole enchilada as if it was one
830 /* update mixer solo state */
836 Session::playlist_length_changed ()
838 /* we can't just increase end_location->end() if pl->get_maximum_extent()
839 if larger. if the playlist used to be the longest playlist,
840 and its now shorter, we have to decrease end_location->end(). hence,
841 we have to iterate over all diskstreams and check the
842 playlists currently in use.
848 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
850 boost::shared_ptr<Playlist> playlist;
852 if ((playlist = dstream->playlist()) != 0) {
853 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
856 /* see comment in playlist_length_changed () */
861 Session::record_enabling_legal () const
863 /* this used to be in here, but survey says.... we don't need to restrict it */
864 // if (record_status() == Recording) {
868 if (Config->get_all_safe()) {
875 Session::reset_input_monitor_state ()
877 if (transport_rolling()) {
879 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
881 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
882 if ((*i)->record_enabled ()) {
883 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
884 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
888 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
890 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
891 if ((*i)->record_enabled ()) {
892 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
893 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
900 Session::auto_punch_start_changed (Location* location)
902 replace_event (Event::PunchIn, location->start());
904 if (get_record_enabled() && Config->get_punch_in()) {
905 /* capture start has been changed, so save new pending state */
906 save_state ("", true);
911 Session::auto_punch_end_changed (Location* location)
913 nframes_t when_to_stop = location->end();
914 // when_to_stop += _worst_output_latency + _worst_input_latency;
915 replace_event (Event::PunchOut, when_to_stop);
919 Session::auto_punch_changed (Location* location)
921 nframes_t when_to_stop = location->end();
923 replace_event (Event::PunchIn, location->start());
924 //when_to_stop += _worst_output_latency + _worst_input_latency;
925 replace_event (Event::PunchOut, when_to_stop);
929 Session::auto_loop_changed (Location* location)
931 replace_event (Event::AutoLoop, location->end(), location->start());
933 if (transport_rolling() && play_loop) {
935 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
937 if (_transport_frame > location->end()) {
938 // relocate to beginning of loop
939 clear_events (Event::LocateRoll);
941 request_locate (location->start(), true);
944 else if (Config->get_seamless_loop() && !loop_changing) {
946 // schedule a locate-roll to refill the diskstreams at the
948 loop_changing = true;
950 if (location->end() > last_loopend) {
951 clear_events (Event::LocateRoll);
952 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
959 last_loopend = location->end();
964 Session::set_auto_punch_location (Location* location)
968 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
969 auto_punch_start_changed_connection.disconnect();
970 auto_punch_end_changed_connection.disconnect();
971 auto_punch_changed_connection.disconnect();
972 existing->set_auto_punch (false, this);
973 remove_event (existing->start(), Event::PunchIn);
974 clear_events (Event::PunchOut);
975 auto_punch_location_changed (0);
984 if (location->end() <= location->start()) {
985 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
989 auto_punch_start_changed_connection.disconnect();
990 auto_punch_end_changed_connection.disconnect();
991 auto_punch_changed_connection.disconnect();
993 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
994 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
995 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
997 location->set_auto_punch (true, this);
998 auto_punch_location_changed (location);
1002 Session::set_auto_loop_location (Location* location)
1006 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1007 auto_loop_start_changed_connection.disconnect();
1008 auto_loop_end_changed_connection.disconnect();
1009 auto_loop_changed_connection.disconnect();
1010 existing->set_auto_loop (false, this);
1011 remove_event (existing->end(), Event::AutoLoop);
1012 auto_loop_location_changed (0);
1017 if (location == 0) {
1021 if (location->end() <= location->start()) {
1022 error << _("Session: you can't use a mark for auto loop") << endmsg;
1026 last_loopend = location->end();
1028 auto_loop_start_changed_connection.disconnect();
1029 auto_loop_end_changed_connection.disconnect();
1030 auto_loop_changed_connection.disconnect();
1032 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1033 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1034 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1036 location->set_auto_loop (true, this);
1037 auto_loop_location_changed (location);
1041 Session::locations_added (Location* ignored)
1047 Session::locations_changed ()
1049 _locations.apply (*this, &Session::handle_locations_changed);
1053 Session::handle_locations_changed (Locations::LocationList& locations)
1055 Locations::LocationList::iterator i;
1057 bool set_loop = false;
1058 bool set_punch = false;
1060 for (i = locations.begin(); i != locations.end(); ++i) {
1064 if (location->is_auto_punch()) {
1065 set_auto_punch_location (location);
1068 if (location->is_auto_loop()) {
1069 set_auto_loop_location (location);
1076 set_auto_loop_location (0);
1079 set_auto_punch_location (0);
1086 Session::enable_record ()
1088 /* XXX really atomic compare+swap here */
1089 if (g_atomic_int_get (&_record_status) != Recording) {
1090 g_atomic_int_set (&_record_status, Recording);
1091 _last_record_location = _transport_frame;
1092 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1094 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1095 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1096 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1097 if ((*i)->record_enabled ()) {
1098 (*i)->monitor_input (true);
1103 RecordStateChanged ();
1108 Session::disable_record (bool rt_context, bool force)
1112 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1114 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1115 g_atomic_int_set (&_record_status, Disabled);
1117 if (rs == Recording) {
1118 g_atomic_int_set (&_record_status, Enabled);
1122 // FIXME: timestamp correct? [DR]
1123 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1124 // does this /need/ to be sent in all cases?
1126 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1128 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1129 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1131 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1132 if ((*i)->record_enabled ()) {
1133 (*i)->monitor_input (false);
1138 RecordStateChanged (); /* emit signal */
1141 remove_pending_capture_state ();
1147 Session::step_back_from_record ()
1149 /* XXX really atomic compare+swap here */
1150 if (g_atomic_int_get (&_record_status) == Recording) {
1151 g_atomic_int_set (&_record_status, Enabled);
1153 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1154 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1156 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1157 if ((*i)->record_enabled ()) {
1158 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1159 (*i)->monitor_input (false);
1167 Session::maybe_enable_record ()
1169 g_atomic_int_set (&_record_status, Enabled);
1171 /* this function is currently called from somewhere other than an RT thread.
1172 this save_state() call therefore doesn't impact anything.
1175 save_state ("", true);
1177 if (_transport_speed) {
1178 if (!Config->get_punch_in()) {
1182 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1183 RecordStateChanged (); /* EMIT SIGNAL */
1190 Session::audible_frame () const
1196 /* the first of these two possible settings for "offset"
1197 mean that the audible frame is stationary until
1198 audio emerges from the latency compensation
1201 the second means that the audible frame is stationary
1202 until audio would emerge from a physical port
1203 in the absence of any plugin latency compensation
1206 offset = _worst_output_latency;
1208 if (offset > current_block_size) {
1209 offset -= current_block_size;
1211 /* XXX is this correct? if we have no external
1212 physical connections and everything is internal
1213 then surely this is zero? still, how
1214 likely is that anyway?
1216 offset = current_block_size;
1219 if (synced_to_jack()) {
1220 tf = _engine.transport_frame();
1222 tf = _transport_frame;
1225 if (_transport_speed == 0) {
1235 if (!non_realtime_work_pending()) {
1239 /* take latency into account */
1248 Session::set_frame_rate (nframes_t frames_per_second)
1250 /** \fn void Session::set_frame_size(nframes_t)
1251 the AudioEngine object that calls this guarantees
1252 that it will not be called while we are also in
1253 ::process(). Its fine to do things that block
1257 _base_frame_rate = frames_per_second;
1261 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1265 // XXX we need some equivalent to this, somehow
1266 // SndFileSource::setup_standard_crossfades (frames_per_second);
1270 /* XXX need to reset/reinstantiate all LADSPA plugins */
1274 Session::set_block_size (nframes_t nframes)
1276 /* the AudioEngine guarantees
1277 that it will not be called while we are also in
1278 ::process(). It is therefore fine to do things that block
1284 current_block_size = nframes;
1286 ensure_buffers(_scratch_buffers->available());
1288 if (_gain_automation_buffer) {
1289 delete [] _gain_automation_buffer;
1291 _gain_automation_buffer = new gain_t[nframes];
1293 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1295 boost::shared_ptr<RouteList> r = routes.reader ();
1297 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1298 (*i)->set_block_size (nframes);
1301 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1303 (*i)->set_block_size (nframes);
1306 set_worst_io_latencies ();
1311 Session::set_default_fade (float steepness, float fade_msecs)
1314 nframes_t fade_frames;
1316 /* Don't allow fade of less 1 frame */
1318 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1325 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1329 default_fade_msecs = fade_msecs;
1330 default_fade_steepness = steepness;
1333 // jlc, WTF is this!
1334 Glib::RWLock::ReaderLock lm (route_lock);
1335 AudioRegion::set_default_fade (steepness, fade_frames);
1340 /* XXX have to do this at some point */
1341 /* foreach region using default fade, reset, then
1342 refill_all_diskstream_buffers ();
1347 struct RouteSorter {
1348 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1349 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1351 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1354 if (r1->fed_by.empty()) {
1355 if (r2->fed_by.empty()) {
1356 /* no ardour-based connections inbound to either route. just use signal order */
1357 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1359 /* r2 has connections, r1 does not; run r1 early */
1363 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1370 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1372 shared_ptr<Route> r2;
1374 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1375 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1379 /* make a copy of the existing list of routes that feed r1 */
1381 set<shared_ptr<Route> > existing = r1->fed_by;
1383 /* for each route that feeds r1, recurse, marking it as feeding
1387 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1390 /* r2 is a route that feeds r1 which somehow feeds base. mark
1391 base as being fed by r2
1394 rbase->fed_by.insert (r2);
1398 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1402 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1406 /* now recurse, so that we can mark base as being fed by
1407 all routes that feed r2
1410 trace_terminal (r2, rbase);
1417 Session::resort_routes ()
1419 /* don't do anything here with signals emitted
1420 by Routes while we are being destroyed.
1423 if (_state_of_the_state & Deletion) {
1430 RCUWriter<RouteList> writer (routes);
1431 shared_ptr<RouteList> r = writer.get_copy ();
1432 resort_routes_using (r);
1433 /* writer goes out of scope and forces update */
1438 Session::resort_routes_using (shared_ptr<RouteList> r)
1440 RouteList::iterator i, j;
1442 for (i = r->begin(); i != r->end(); ++i) {
1444 (*i)->fed_by.clear ();
1446 for (j = r->begin(); j != r->end(); ++j) {
1448 /* although routes can feed themselves, it will
1449 cause an endless recursive descent if we
1450 detect it. so don't bother checking for
1458 if ((*j)->feeds (*i)) {
1459 (*i)->fed_by.insert (*j);
1464 for (i = r->begin(); i != r->end(); ++i) {
1465 trace_terminal (*i, *i);
1472 cerr << "finished route resort\n";
1474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1475 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1482 list<boost::shared_ptr<MidiTrack> >
1483 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1485 char track_name[32];
1486 uint32_t track_id = 0;
1489 RouteList new_routes;
1490 list<boost::shared_ptr<MidiTrack> > ret;
1491 //uint32_t control_id;
1493 // FIXME: need physical I/O and autoconnect stuff for MIDI
1495 /* count existing midi tracks */
1498 shared_ptr<RouteList> r = routes.reader ();
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1502 if (!(*i)->is_hidden()) {
1504 //channels_used += (*i)->n_inputs().n_midi();
1511 vector<string> physinputs;
1512 vector<string> physoutputs;
1513 uint32_t nphysical_in;
1514 uint32_t nphysical_out;
1516 _engine.get_physical_outputs (physoutputs);
1517 _engine.get_physical_inputs (physinputs);
1518 control_id = ntracks() + nbusses() + 1;
1523 /* check for duplicate route names, since we might have pre-existing
1524 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1525 save, close,restart,add new route - first named route is now
1533 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1535 if (route_by_name (track_name) == 0) {
1539 } while (track_id < (UINT_MAX-1));
1542 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1543 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1548 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1549 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1555 shared_ptr<MidiTrack> track;
1558 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1560 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1561 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1567 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1571 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1572 port = physinputs[(channels_used+x)%nphysical_in];
1575 if (port.length() && track->connect_input (track->input (x), port, this)) {
1581 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1585 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1586 port = physoutputs[(channels_used+x)%nphysical_out];
1587 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1589 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1593 if (port.length() && track->connect_output (track->output (x), port, this)) {
1598 channels_used += track->n_inputs ().n_midi();
1602 track->midi_diskstream()->non_realtime_input_change();
1604 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1605 //track->set_remote_control_id (control_id);
1607 new_routes.push_back (track);
1608 ret.push_back (track);
1611 catch (failed_constructor &err) {
1612 error << _("Session: could not create new midi track.") << endmsg;
1615 /* we need to get rid of this, since the track failed to be created */
1616 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1619 RCUWriter<DiskstreamList> writer (diskstreams);
1620 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1621 ds->remove (track->midi_diskstream());
1628 catch (AudioEngine::PortRegistrationFailure& pfe) {
1630 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;
1633 /* we need to get rid of this, since the track failed to be created */
1634 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1637 RCUWriter<DiskstreamList> writer (diskstreams);
1638 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1639 ds->remove (track->midi_diskstream());
1650 if (!new_routes.empty()) {
1651 add_routes (new_routes, false);
1652 save_state (_current_snapshot_name);
1658 list<boost::shared_ptr<AudioTrack> >
1659 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1661 char track_name[32];
1662 uint32_t track_id = 0;
1664 uint32_t channels_used = 0;
1666 RouteList new_routes;
1667 list<boost::shared_ptr<AudioTrack> > ret;
1668 uint32_t control_id;
1670 /* count existing audio tracks */
1673 shared_ptr<RouteList> r = routes.reader ();
1675 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1676 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1677 if (!(*i)->is_hidden()) {
1679 channels_used += (*i)->n_inputs().n_audio();
1685 vector<string> physinputs;
1686 vector<string> physoutputs;
1687 uint32_t nphysical_in;
1688 uint32_t nphysical_out;
1690 _engine.get_physical_outputs (physoutputs);
1691 _engine.get_physical_inputs (physinputs);
1692 control_id = ntracks() + nbusses() + 1;
1696 /* check for duplicate route names, since we might have pre-existing
1697 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1698 save, close,restart,add new route - first named route is now
1706 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1708 if (route_by_name (track_name) == 0) {
1712 } while (track_id < (UINT_MAX-1));
1714 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1715 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1720 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1721 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1726 shared_ptr<AudioTrack> track;
1729 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1731 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1732 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1733 input_channels, output_channels)
1739 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1743 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1744 port = physinputs[(channels_used+x)%nphysical_in];
1747 if (port.length() && track->connect_input (track->input (x), port, this)) {
1753 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1757 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1758 port = physoutputs[(channels_used+x)%nphysical_out];
1759 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1761 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1765 if (port.length() && track->connect_output (track->output (x), port, this)) {
1770 channels_used += track->n_inputs ().n_audio();
1772 track->audio_diskstream()->non_realtime_input_change();
1774 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1775 track->set_remote_control_id (control_id);
1778 new_routes.push_back (track);
1779 ret.push_back (track);
1782 catch (failed_constructor &err) {
1783 error << _("Session: could not create new audio track.") << endmsg;
1786 /* we need to get rid of this, since the track failed to be created */
1787 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1790 RCUWriter<DiskstreamList> writer (diskstreams);
1791 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1792 ds->remove (track->audio_diskstream());
1799 catch (AudioEngine::PortRegistrationFailure& pfe) {
1801 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;
1804 /* we need to get rid of this, since the track failed to be created */
1805 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1808 RCUWriter<DiskstreamList> writer (diskstreams);
1809 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1810 ds->remove (track->audio_diskstream());
1821 if (!new_routes.empty()) {
1822 add_routes (new_routes, true);
1829 Session::set_remote_control_ids ()
1831 RemoteModel m = Config->get_remote_model();
1833 shared_ptr<RouteList> r = routes.reader ();
1835 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1836 if ( MixerOrdered == m) {
1837 long order = (*i)->order_key(N_("signal"));
1838 (*i)->set_remote_control_id( order+1 );
1839 } else if ( EditorOrdered == m) {
1840 long order = (*i)->order_key(N_("editor"));
1841 (*i)->set_remote_control_id( order+1 );
1842 } else if ( UserOrdered == m) {
1843 //do nothing ... only changes to remote id's are initiated by user
1850 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1853 uint32_t bus_id = 1;
1857 uint32_t control_id;
1859 /* count existing audio busses */
1862 shared_ptr<RouteList> r = routes.reader ();
1864 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1865 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1866 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1873 vector<string> physinputs;
1874 vector<string> physoutputs;
1876 _engine.get_physical_outputs (physoutputs);
1877 _engine.get_physical_inputs (physinputs);
1878 control_id = ntracks() + nbusses() + 1;
1883 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1887 if (route_by_name (bus_name) == 0) {
1891 } while (bus_id < (UINT_MAX-1));
1894 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1896 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1897 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1898 input_channels, output_channels)
1903 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1907 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1908 port = physinputs[((n+x)%n_physical_inputs)];
1911 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1916 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1920 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1921 port = physoutputs[((n+x)%n_physical_outputs)];
1922 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1924 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1928 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1933 bus->set_remote_control_id (control_id);
1936 ret.push_back (bus);
1940 catch (failed_constructor &err) {
1941 error << _("Session: could not create new audio route.") << endmsg;
1945 catch (AudioEngine::PortRegistrationFailure& pfe) {
1946 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;
1956 add_routes (ret, true);
1964 Session::add_routes (RouteList& new_routes, bool save)
1967 RCUWriter<RouteList> writer (routes);
1968 shared_ptr<RouteList> r = writer.get_copy ();
1969 r->insert (r->end(), new_routes.begin(), new_routes.end());
1970 resort_routes_using (r);
1973 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1975 boost::weak_ptr<Route> wpr (*x);
1977 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1978 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1979 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1980 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1982 if ((*x)->is_master()) {
1986 if ((*x)->is_control()) {
1987 _control_out = (*x);
1990 add_bundle ((*x)->bundle_for_inputs());
1991 add_bundle ((*x)->bundle_for_outputs());
1994 if (_control_out && IO::connecting_legal) {
1996 vector<string> cports;
1997 uint32_t ni = _control_out->n_inputs().n_audio();
1999 for (uint32_t n = 0; n < ni; ++n) {
2000 cports.push_back (_control_out->input(n)->name());
2003 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2004 (*x)->set_control_outs (cports);
2011 save_state (_current_snapshot_name);
2014 RouteAdded (new_routes); /* EMIT SIGNAL */
2018 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2020 /* need to do this in case we're rolling at the time, to prevent false underruns */
2021 dstream->do_refill_with_alloc ();
2023 dstream->set_block_size (current_block_size);
2026 RCUWriter<DiskstreamList> writer (diskstreams);
2027 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2028 ds->push_back (dstream);
2029 /* writer goes out of scope, copies ds back to main */
2032 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2033 /* this will connect to future changes, and check the current length */
2034 diskstream_playlist_changed (dstream);
2036 dstream->prepare ();
2041 Session::remove_route (shared_ptr<Route> route)
2044 RCUWriter<RouteList> writer (routes);
2045 shared_ptr<RouteList> rs = writer.get_copy ();
2049 /* deleting the master out seems like a dumb
2050 idea, but its more of a UI policy issue
2054 if (route == _master_out) {
2055 _master_out = shared_ptr<Route> ();
2058 if (route == _control_out) {
2059 _control_out = shared_ptr<Route> ();
2061 /* cancel control outs for all routes */
2063 vector<string> empty;
2065 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2066 (*r)->set_control_outs (empty);
2070 update_route_solo_state ();
2072 /* writer goes out of scope, forces route list update */
2076 boost::shared_ptr<Diskstream> ds;
2078 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2079 ds = t->diskstream();
2085 RCUWriter<DiskstreamList> dsl (diskstreams);
2086 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2091 find_current_end ();
2093 // We need to disconnect the routes inputs and outputs
2095 route->disconnect_inputs (0);
2096 route->disconnect_outputs (0);
2098 update_latency_compensation (false, false);
2101 /* get rid of it from the dead wood collection in the route list manager */
2103 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2107 /* try to cause everyone to drop their references */
2109 route->drop_references ();
2111 /* save the new state of the world */
2113 if (save_state (_current_snapshot_name)) {
2114 save_history (_current_snapshot_name);
2119 Session::route_mute_changed (void* src)
2125 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2127 if (solo_update_disabled) {
2133 boost::shared_ptr<Route> route = wpr.lock ();
2136 /* should not happen */
2137 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2141 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2143 shared_ptr<RouteList> r = routes.reader ();
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2147 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2151 /* don't mess with busses */
2153 if (dynamic_cast<Track*>((*i).get()) == 0) {
2159 /* don't mess with tracks */
2161 if (dynamic_cast<Track*>((*i).get()) != 0) {
2166 if ((*i) != route &&
2167 ((*i)->mix_group () == 0 ||
2168 (*i)->mix_group () != route->mix_group () ||
2169 !route->mix_group ()->is_active())) {
2171 if ((*i)->soloed()) {
2173 /* if its already soloed, and solo latching is enabled,
2174 then leave it as it is.
2177 if (Config->get_solo_latched()) {
2184 solo_update_disabled = true;
2185 (*i)->set_solo (false, src);
2186 solo_update_disabled = false;
2190 bool something_soloed = false;
2191 bool same_thing_soloed = false;
2192 bool signal = false;
2194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2195 if ((*i)->soloed()) {
2196 something_soloed = true;
2197 if (dynamic_cast<Track*>((*i).get())) {
2199 same_thing_soloed = true;
2204 same_thing_soloed = true;
2212 if (something_soloed != currently_soloing) {
2214 currently_soloing = something_soloed;
2217 modify_solo_mute (is_track, same_thing_soloed);
2220 SoloActive (currently_soloing); /* EMIT SIGNAL */
2223 SoloChanged (); /* EMIT SIGNAL */
2229 Session::update_route_solo_state ()
2232 bool is_track = false;
2233 bool signal = false;
2235 /* caller must hold RouteLock */
2237 /* this is where we actually implement solo by changing
2238 the solo mute setting of each track.
2241 shared_ptr<RouteList> r = routes.reader ();
2243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2244 if ((*i)->soloed()) {
2246 if (dynamic_cast<Track*>((*i).get())) {
2253 if (mute != currently_soloing) {
2255 currently_soloing = mute;
2258 if (!is_track && !mute) {
2260 /* nothing is soloed */
2262 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2263 (*i)->set_solo_mute (false);
2273 modify_solo_mute (is_track, mute);
2276 SoloActive (currently_soloing);
2281 Session::modify_solo_mute (bool is_track, bool mute)
2283 shared_ptr<RouteList> r = routes.reader ();
2285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 /* only alter track solo mute */
2291 if (dynamic_cast<Track*>((*i).get())) {
2292 if ((*i)->soloed()) {
2293 (*i)->set_solo_mute (!mute);
2295 (*i)->set_solo_mute (mute);
2301 /* only alter bus solo mute */
2303 if (!dynamic_cast<Track*>((*i).get())) {
2305 if ((*i)->soloed()) {
2307 (*i)->set_solo_mute (false);
2311 /* don't mute master or control outs
2312 in response to another bus solo
2315 if ((*i) != _master_out &&
2316 (*i) != _control_out) {
2317 (*i)->set_solo_mute (mute);
2328 Session::catch_up_on_solo ()
2330 /* this is called after set_state() to catch the full solo
2331 state, which can't be correctly determined on a per-route
2332 basis, but needs the global overview that only the session
2335 update_route_solo_state();
2339 Session::route_by_name (string name)
2341 shared_ptr<RouteList> r = routes.reader ();
2343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2344 if ((*i)->name() == name) {
2349 return shared_ptr<Route> ((Route*) 0);
2353 Session::route_by_id (PBD::ID id)
2355 shared_ptr<RouteList> r = routes.reader ();
2357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358 if ((*i)->id() == id) {
2363 return shared_ptr<Route> ((Route*) 0);
2367 Session::route_by_remote_id (uint32_t id)
2369 shared_ptr<RouteList> r = routes.reader ();
2371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2372 if ((*i)->remote_control_id() == id) {
2377 return shared_ptr<Route> ((Route*) 0);
2381 Session::find_current_end ()
2383 if (_state_of_the_state & Loading) {
2387 nframes_t max = get_maximum_extent ();
2389 if (max > end_location->end()) {
2390 end_location->set_end (max);
2392 DurationChanged(); /* EMIT SIGNAL */
2397 Session::get_maximum_extent () const
2402 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2404 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2405 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2406 if ((me = pl->get_maximum_extent()) > max) {
2414 boost::shared_ptr<Diskstream>
2415 Session::diskstream_by_name (string name)
2417 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2419 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2420 if ((*i)->name() == name) {
2425 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2428 boost::shared_ptr<Diskstream>
2429 Session::diskstream_by_id (const PBD::ID& id)
2431 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2433 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2434 if ((*i)->id() == id) {
2439 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2442 /* Region management */
2445 Session::new_region_name (string old)
2447 string::size_type last_period;
2449 string::size_type len = old.length() + 64;
2452 if ((last_period = old.find_last_of ('.')) == string::npos) {
2454 /* no period present - add one explicitly */
2457 last_period = old.length() - 1;
2462 number = atoi (old.substr (last_period+1).c_str());
2466 while (number < (UINT_MAX-1)) {
2468 RegionList::const_iterator i;
2473 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2476 for (i = regions.begin(); i != regions.end(); ++i) {
2477 if (i->second->name() == sbuf) {
2482 if (i == regions.end()) {
2487 if (number != (UINT_MAX-1)) {
2491 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2496 Session::region_name (string& result, string base, bool newlevel) const
2501 assert(base.find("/") == string::npos);
2505 Glib::Mutex::Lock lm (region_lock);
2507 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2515 /* XXX this is going to be slow. optimize me later */
2520 string::size_type pos;
2522 pos = base.find_last_of ('.');
2524 /* pos may be npos, but then we just use entire base */
2526 subbase = base.substr (0, pos);
2530 bool name_taken = true;
2533 Glib::Mutex::Lock lm (region_lock);
2535 for (int n = 1; n < 5000; ++n) {
2538 snprintf (buf, sizeof (buf), ".%d", n);
2543 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2544 if (i->second->name() == result) {
2557 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2565 Session::add_region (boost::shared_ptr<Region> region)
2567 vector<boost::shared_ptr<Region> > v;
2568 v.push_back (region);
2573 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2578 Glib::Mutex::Lock lm (region_lock);
2580 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2582 boost::shared_ptr<Region> region = *ii;
2586 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2590 RegionList::iterator x;
2592 for (x = regions.begin(); x != regions.end(); ++x) {
2594 if (region->region_list_equivalent (x->second)) {
2599 if (x == regions.end()) {
2601 pair<RegionList::key_type,RegionList::mapped_type> entry;
2603 entry.first = region->id();
2604 entry.second = region;
2606 pair<RegionList::iterator,bool> x = regions.insert (entry);
2618 /* mark dirty because something has changed even if we didn't
2619 add the region to the region list.
2626 vector<boost::weak_ptr<Region> > v;
2627 boost::shared_ptr<Region> first_r;
2629 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2631 boost::shared_ptr<Region> region = *ii;
2635 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2638 v.push_back (region);
2645 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2646 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2650 RegionsAdded (v); /* EMIT SIGNAL */
2656 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2658 boost::shared_ptr<Region> region (weak_region.lock ());
2664 if (what_changed & Region::HiddenChanged) {
2665 /* relay hidden changes */
2666 RegionHiddenChange (region);
2671 Session::remove_region (boost::weak_ptr<Region> weak_region)
2673 RegionList::iterator i;
2674 boost::shared_ptr<Region> region (weak_region.lock ());
2680 bool removed = false;
2683 Glib::Mutex::Lock lm (region_lock);
2685 if ((i = regions.find (region->id())) != regions.end()) {
2691 /* mark dirty because something has changed even if we didn't
2692 remove the region from the region list.
2698 RegionRemoved(region); /* EMIT SIGNAL */
2702 boost::shared_ptr<Region>
2703 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2705 RegionList::iterator i;
2706 boost::shared_ptr<Region> region;
2708 Glib::Mutex::Lock lm (region_lock);
2710 for (i = regions.begin(); i != regions.end(); ++i) {
2714 if (region->whole_file()) {
2716 if (child->source_equivalent (region)) {
2722 return boost::shared_ptr<Region> ();
2726 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2728 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2729 (*i)->get_region_list_equivalent_regions (region, result);
2733 Session::destroy_region (boost::shared_ptr<Region> region)
2735 vector<boost::shared_ptr<Source> > srcs;
2738 if (region->playlist()) {
2739 region->playlist()->destroy_region (region);
2742 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2743 srcs.push_back (region->source (n));
2747 region->drop_references ();
2749 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2751 (*i)->mark_for_remove ();
2752 (*i)->drop_references ();
2754 cerr << "source was not used by any playlist\n";
2761 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2763 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2764 destroy_region (*i);
2770 Session::remove_last_capture ()
2772 list<boost::shared_ptr<Region> > r;
2774 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2776 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2777 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2780 r.insert (r.end(), l.begin(), l.end());
2785 destroy_regions (r);
2787 save_state (_current_snapshot_name);
2793 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2799 /* Source Management */
2801 Session::add_source (boost::shared_ptr<Source> source)
2803 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2804 pair<SourceMap::iterator,bool> result;
2806 entry.first = source->id();
2807 entry.second = source;
2810 Glib::Mutex::Lock lm (source_lock);
2811 result = sources.insert (entry);
2814 if (result.second) {
2815 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2819 boost::shared_ptr<AudioFileSource> afs;
2821 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2822 if (Config->get_auto_analyse_audio()) {
2823 Analyser::queue_source_for_analysis (source, false);
2829 Session::remove_source (boost::weak_ptr<Source> src)
2831 SourceMap::iterator i;
2832 boost::shared_ptr<Source> source = src.lock();
2838 cerr << "remove source for " << source->name() << endl;
2841 Glib::Mutex::Lock lm (source_lock);
2843 if ((i = sources.find (source->id())) != sources.end()) {
2848 if (!_state_of_the_state & InCleanup) {
2850 /* save state so we don't end up with a session file
2851 referring to non-existent sources.
2854 save_state (_current_snapshot_name);
2858 boost::shared_ptr<Source>
2859 Session::source_by_id (const PBD::ID& id)
2861 Glib::Mutex::Lock lm (source_lock);
2862 SourceMap::iterator i;
2863 boost::shared_ptr<Source> source;
2865 if ((i = sources.find (id)) != sources.end()) {
2873 boost::shared_ptr<Source>
2874 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2876 Glib::Mutex::Lock lm (source_lock);
2878 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2879 cerr << "comparing " << path << " with " << i->second->name() << endl;
2880 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2882 if (afs && afs->path() == path && chn == afs->channel()) {
2887 return boost::shared_ptr<Source>();
2891 Session::peak_path (Glib::ustring base) const
2893 sys::path peakfile_path(_session_dir->peak_path());
2894 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2895 return peakfile_path.to_string();
2899 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2902 string old_basename = PBD::basename_nosuffix (oldname);
2903 string new_legalized = legalize_for_path (newname);
2905 /* note: we know (or assume) the old path is already valid */
2909 /* destructive file sources have a name of the form:
2911 /path/to/Tnnnn-NAME(%[LR])?.wav
2913 the task here is to replace NAME with the new name.
2916 /* find last slash */
2920 string::size_type slash;
2921 string::size_type dash;
2923 if ((slash = path.find_last_of ('/')) == string::npos) {
2927 dir = path.substr (0, slash+1);
2929 /* '-' is not a legal character for the NAME part of the path */
2931 if ((dash = path.find_last_of ('-')) == string::npos) {
2935 prefix = path.substr (slash+1, dash-(slash+1));
2940 path += new_legalized;
2941 path += ".wav"; /* XXX gag me with a spoon */
2945 /* non-destructive file sources have a name of the form:
2947 /path/to/NAME-nnnnn(%[LR])?.wav
2949 the task here is to replace NAME with the new name.
2954 string::size_type slash;
2955 string::size_type dash;
2956 string::size_type postfix;
2958 /* find last slash */
2960 if ((slash = path.find_last_of ('/')) == string::npos) {
2964 dir = path.substr (0, slash+1);
2966 /* '-' is not a legal character for the NAME part of the path */
2968 if ((dash = path.find_last_of ('-')) == string::npos) {
2972 suffix = path.substr (dash+1);
2974 // Suffix is now everything after the dash. Now we need to eliminate
2975 // the nnnnn part, which is done by either finding a '%' or a '.'
2977 postfix = suffix.find_last_of ("%");
2978 if (postfix == string::npos) {
2979 postfix = suffix.find_last_of ('.');
2982 if (postfix != string::npos) {
2983 suffix = suffix.substr (postfix);
2985 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2989 const uint32_t limit = 10000;
2990 char buf[PATH_MAX+1];
2992 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2994 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2996 if (access (buf, F_OK) != 0) {
3004 error << "FATAL ERROR! Could not find a " << endl;
3013 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3017 char buf[PATH_MAX+1];
3018 const uint32_t limit = 10000;
3022 legalized = legalize_for_path (name);
3024 /* find a "version" of the file name that doesn't exist in
3025 any of the possible directories.
3028 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3030 vector<space_and_path>::iterator i;
3031 uint32_t existing = 0;
3033 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3035 SessionDirectory sdir((*i).path);
3037 spath = sdir.sound_path().to_string();
3041 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3042 } else if (nchan == 2) {
3044 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3046 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3048 } else if (nchan < 26) {
3049 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3051 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3060 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3061 } else if (nchan == 2) {
3063 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3065 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3067 } else if (nchan < 26) {
3068 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3070 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3074 if (sys::exists(buf)) {
3080 if (existing == 0) {
3085 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3087 throw failed_constructor();
3091 /* we now have a unique name for the file, but figure out where to
3097 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3099 spath = sdir.sound_path().to_string();
3102 string::size_type pos = foo.find_last_of ('/');
3104 if (pos == string::npos) {
3107 spath += foo.substr (pos + 1);
3113 boost::shared_ptr<AudioFileSource>
3114 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3116 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3117 return boost::dynamic_pointer_cast<AudioFileSource> (
3118 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3121 // FIXME: _terrible_ code duplication
3123 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3126 string old_basename = PBD::basename_nosuffix (oldname);
3127 string new_legalized = legalize_for_path (newname);
3129 /* note: we know (or assume) the old path is already valid */
3133 /* destructive file sources have a name of the form:
3135 /path/to/Tnnnn-NAME(%[LR])?.wav
3137 the task here is to replace NAME with the new name.
3140 /* find last slash */
3144 string::size_type slash;
3145 string::size_type dash;
3147 if ((slash = path.find_last_of ('/')) == string::npos) {
3151 dir = path.substr (0, slash+1);
3153 /* '-' is not a legal character for the NAME part of the path */
3155 if ((dash = path.find_last_of ('-')) == string::npos) {
3159 prefix = path.substr (slash+1, dash-(slash+1));
3164 path += new_legalized;
3165 path += ".mid"; /* XXX gag me with a spoon */
3169 /* non-destructive file sources have a name of the form:
3171 /path/to/NAME-nnnnn(%[LR])?.wav
3173 the task here is to replace NAME with the new name.
3178 string::size_type slash;
3179 string::size_type dash;
3180 string::size_type postfix;
3182 /* find last slash */
3184 if ((slash = path.find_last_of ('/')) == string::npos) {
3188 dir = path.substr (0, slash+1);
3190 /* '-' is not a legal character for the NAME part of the path */
3192 if ((dash = path.find_last_of ('-')) == string::npos) {
3196 suffix = path.substr (dash+1);
3198 // Suffix is now everything after the dash. Now we need to eliminate
3199 // the nnnnn part, which is done by either finding a '%' or a '.'
3201 postfix = suffix.find_last_of ("%");
3202 if (postfix == string::npos) {
3203 postfix = suffix.find_last_of ('.');
3206 if (postfix != string::npos) {
3207 suffix = suffix.substr (postfix);
3209 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3213 const uint32_t limit = 10000;
3214 char buf[PATH_MAX+1];
3216 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3218 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3220 if (access (buf, F_OK) != 0) {
3228 error << "FATAL ERROR! Could not find a " << endl;
3237 Session::midi_path_from_name (string name)
3241 char buf[PATH_MAX+1];
3242 const uint32_t limit = 10000;
3246 legalized = legalize_for_path (name);
3248 /* find a "version" of the file name that doesn't exist in
3249 any of the possible directories.
3252 for (cnt = 1; cnt <= limit; ++cnt) {
3254 vector<space_and_path>::iterator i;
3255 uint32_t existing = 0;
3257 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3259 SessionDirectory sdir((*i).path);
3261 sys::path p = sdir.midi_path();
3265 spath = p.to_string();
3267 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3269 if (sys::exists (buf)) {
3274 if (existing == 0) {
3279 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3280 throw failed_constructor();
3284 /* we now have a unique name for the file, but figure out where to
3290 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3292 spath = sdir.midi_path().to_string();
3295 string::size_type pos = foo.find_last_of ('/');
3297 if (pos == string::npos) {
3300 spath += foo.substr (pos + 1);
3306 boost::shared_ptr<MidiSource>
3307 Session::create_midi_source_for_session (MidiDiskstream& ds)
3309 string mpath = midi_path_from_name (ds.name());
3311 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3315 /* Playlist management */
3317 boost::shared_ptr<Playlist>
3318 Session::playlist_by_name (string name)
3320 Glib::Mutex::Lock lm (playlist_lock);
3321 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3322 if ((*i)->name() == name) {
3326 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3327 if ((*i)->name() == name) {
3332 return boost::shared_ptr<Playlist>();
3336 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3338 if (playlist->hidden()) {
3343 Glib::Mutex::Lock lm (playlist_lock);
3344 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3345 playlists.insert (playlists.begin(), playlist);
3346 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3347 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3353 PlaylistAdded (playlist); /* EMIT SIGNAL */
3357 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3360 Glib::Mutex::Lock lm (playlist_lock);
3361 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3364 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3371 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3373 boost::shared_ptr<Playlist> pl(wpl.lock());
3379 PlaylistList::iterator x;
3382 /* its not supposed to be visible */
3387 Glib::Mutex::Lock lm (playlist_lock);
3391 unused_playlists.insert (pl);
3393 if ((x = playlists.find (pl)) != playlists.end()) {
3394 playlists.erase (x);
3400 playlists.insert (pl);
3402 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3403 unused_playlists.erase (x);
3410 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3412 if (_state_of_the_state & Deletion) {
3416 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3423 Glib::Mutex::Lock lm (playlist_lock);
3425 PlaylistList::iterator i;
3427 i = find (playlists.begin(), playlists.end(), playlist);
3428 if (i != playlists.end()) {
3429 playlists.erase (i);
3432 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3433 if (i != unused_playlists.end()) {
3434 unused_playlists.erase (i);
3441 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3445 Session::set_audition (boost::shared_ptr<Region> r)
3447 pending_audition_region = r;
3448 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3449 schedule_butler_transport_work ();
3453 Session::audition_playlist ()
3455 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3456 ev->region.reset ();
3461 Session::non_realtime_set_audition ()
3463 if (!pending_audition_region) {
3464 auditioner->audition_current_playlist ();
3466 auditioner->audition_region (pending_audition_region);
3467 pending_audition_region.reset ();
3469 AuditionActive (true); /* EMIT SIGNAL */
3473 Session::audition_region (boost::shared_ptr<Region> r)
3475 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3481 Session::cancel_audition ()
3483 if (auditioner->active()) {
3484 auditioner->cancel_audition ();
3485 AuditionActive (false); /* EMIT SIGNAL */
3490 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3492 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3496 Session::remove_empty_sounds ()
3498 vector<string> audio_filenames;
3500 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3502 Glib::Mutex::Lock lm (source_lock);
3504 TapeFileMatcher tape_file_matcher;
3506 remove_if (audio_filenames.begin(), audio_filenames.end(),
3507 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3509 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3511 sys::path audio_file_path (_session_dir->sound_path());
3513 audio_file_path /= *i;
3515 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3519 sys::remove (audio_file_path);
3520 const string peakfile = peak_path (audio_file_path.to_string());
3521 sys::remove (peakfile);
3523 catch (const sys::filesystem_error& err)
3525 error << err.what() << endmsg;
3532 Session::is_auditioning () const
3534 /* can be called before we have an auditioner object */
3536 return auditioner->active();
3543 Session::set_all_solo (bool yn)
3545 shared_ptr<RouteList> r = routes.reader ();
3547 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3548 if (!(*i)->is_hidden()) {
3549 (*i)->set_solo (yn, this);
3557 Session::set_all_mute (bool yn)
3559 shared_ptr<RouteList> r = routes.reader ();
3561 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3562 if (!(*i)->is_hidden()) {
3563 (*i)->set_mute (yn, this);
3571 Session::n_diskstreams () const
3575 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3577 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3578 if (!(*i)->hidden()) {
3586 Session::graph_reordered ()
3588 /* don't do this stuff if we are setting up connections
3589 from a set_state() call or creating new tracks.
3592 if (_state_of_the_state & InitialConnecting) {
3596 /* every track/bus asked for this to be handled but it was deferred because
3597 we were connecting. do it now.
3600 request_input_change_handling ();
3604 /* force all diskstreams to update their capture offset values to
3605 reflect any changes in latencies within the graph.
3608 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3610 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3611 (*i)->set_capture_offset ();
3616 Session::record_disenable_all ()
3618 record_enable_change_all (false);
3622 Session::record_enable_all ()
3624 record_enable_change_all (true);
3628 Session::record_enable_change_all (bool yn)
3630 shared_ptr<RouteList> r = routes.reader ();
3632 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3635 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3636 at->set_record_enable (yn, this);
3640 /* since we don't keep rec-enable state, don't mark session dirty */
3644 Session::add_processor (Processor* processor)
3647 PortInsert* port_insert;
3648 PluginInsert* plugin_insert;
3650 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3651 _port_inserts.insert (_port_inserts.begin(), port_insert);
3652 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3653 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3654 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3655 _sends.insert (_sends.begin(), send);
3657 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3661 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3667 Session::remove_processor (Processor* processor)
3670 PortInsert* port_insert;
3671 PluginInsert* plugin_insert;
3673 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3674 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3675 if (x != _port_inserts.end()) {
3676 insert_bitset[port_insert->bit_slot()] = false;
3677 _port_inserts.erase (x);
3679 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3680 _plugin_inserts.remove (plugin_insert);
3681 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3682 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3683 if (x != _sends.end()) {
3684 send_bitset[send->bit_slot()] = false;
3688 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3696 Session::available_capture_duration ()
3698 float sample_bytes_on_disk = 4.0; // keep gcc happy
3700 switch (Config->get_native_file_data_format()) {
3702 sample_bytes_on_disk = 4.0;
3706 sample_bytes_on_disk = 3.0;
3710 sample_bytes_on_disk = 2.0;
3714 /* impossible, but keep some gcc versions happy */
3715 fatal << string_compose (_("programming error: %1"),
3716 X_("illegal native file data format"))
3721 double scale = 4096.0 / sample_bytes_on_disk;
3723 if (_total_free_4k_blocks * scale > (double) max_frames) {
3727 return (nframes_t) floor (_total_free_4k_blocks * scale);
3731 Session::add_bundle (shared_ptr<Bundle> bundle)
3734 Glib::Mutex::Lock guard (bundle_lock);
3735 _bundles.push_back (bundle);
3738 BundleAdded (bundle); /* EMIT SIGNAL */
3744 Session::remove_bundle (shared_ptr<Bundle> bundle)
3746 bool removed = false;
3749 Glib::Mutex::Lock guard (bundle_lock);
3750 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3752 if (i != _bundles.end()) {
3759 BundleRemoved (bundle); /* EMIT SIGNAL */
3766 Session::bundle_by_name (string name) const
3768 Glib::Mutex::Lock lm (bundle_lock);
3770 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3771 if ((*i)->name() == name) {
3776 return boost::shared_ptr<Bundle> ();
3780 Session::tempo_map_changed (Change ignored)
3784 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3785 (*i)->update_after_tempo_map_change ();
3788 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3789 (*i)->update_after_tempo_map_change ();
3795 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3796 * the given count with the current block size.
3799 Session::ensure_buffers (ChanCount howmany)
3801 if (current_block_size == 0)
3802 return; // too early? (is this ok?)
3804 // We need at least 2 MIDI scratch buffers to mix/merge
3805 if (howmany.n_midi() < 2)
3806 howmany.set_midi(2);
3808 // FIXME: JACK needs to tell us maximum MIDI buffer size
3809 // Using nasty assumption (max # events == nframes) for now
3810 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3811 _mix_buffers->ensure_buffers(howmany, current_block_size);
3812 _silent_buffers->ensure_buffers(howmany, current_block_size);
3814 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3818 Session::next_insert_id ()
3820 /* this doesn't really loop forever. just think about it */
3823 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3824 if (!insert_bitset[n]) {
3825 insert_bitset[n] = true;
3831 /* none available, so resize and try again */
3833 insert_bitset.resize (insert_bitset.size() + 16, false);
3838 Session::next_send_id ()
3840 /* this doesn't really loop forever. just think about it */
3843 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3844 if (!send_bitset[n]) {
3845 send_bitset[n] = true;
3851 /* none available, so resize and try again */
3853 send_bitset.resize (send_bitset.size() + 16, false);
3858 Session::mark_send_id (uint32_t id)
3860 if (id >= send_bitset.size()) {
3861 send_bitset.resize (id+16, false);
3863 if (send_bitset[id]) {
3864 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3866 send_bitset[id] = true;
3870 Session::mark_insert_id (uint32_t id)
3872 if (id >= insert_bitset.size()) {
3873 insert_bitset.resize (id+16, false);
3875 if (insert_bitset[id]) {
3876 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3878 insert_bitset[id] = true;
3881 /* Named Selection management */
3884 Session::named_selection_by_name (string name)
3886 Glib::Mutex::Lock lm (named_selection_lock);
3887 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3888 if ((*i)->name == name) {
3896 Session::add_named_selection (NamedSelection* named_selection)
3899 Glib::Mutex::Lock lm (named_selection_lock);
3900 named_selections.insert (named_selections.begin(), named_selection);
3903 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3909 NamedSelectionAdded (); /* EMIT SIGNAL */
3913 Session::remove_named_selection (NamedSelection* named_selection)
3915 bool removed = false;
3918 Glib::Mutex::Lock lm (named_selection_lock);
3920 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3922 if (i != named_selections.end()) {
3924 named_selections.erase (i);
3931 NamedSelectionRemoved (); /* EMIT SIGNAL */
3936 Session::reset_native_file_format ()
3938 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3940 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3941 (*i)->reset_write_sources (false);
3946 Session::route_name_unique (string n) const
3948 shared_ptr<RouteList> r = routes.reader ();
3950 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3951 if ((*i)->name() == n) {
3960 Session::n_playlists () const
3962 Glib::Mutex::Lock lm (playlist_lock);
3963 return playlists.size();
3967 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3969 if (!force && howmany <= _npan_buffers) {
3973 if (_pan_automation_buffer) {
3975 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3976 delete [] _pan_automation_buffer[i];
3979 delete [] _pan_automation_buffer;
3982 _pan_automation_buffer = new pan_t*[howmany];
3984 for (uint32_t i = 0; i < howmany; ++i) {
3985 _pan_automation_buffer[i] = new pan_t[nframes];
3988 _npan_buffers = howmany;
3992 Session::freeze (InterThreadInfo& itt)
3994 shared_ptr<RouteList> r = routes.reader ();
3996 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4000 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4001 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4012 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
4013 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4016 boost::shared_ptr<Playlist> playlist;
4017 boost::shared_ptr<AudioFileSource> fsource;
4019 char buf[PATH_MAX+1];
4020 ChanCount nchans(track.audio_diskstream()->n_channels());
4022 nframes_t this_chunk;
4025 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4026 const string sound_dir = sdir.sound_path().to_string();
4028 // any bigger than this seems to cause stack overflows in called functions
4029 const nframes_t chunk_size = (128 * 1024)/4;
4031 g_atomic_int_set (&processing_prohibited, 1);
4033 /* call tree *MUST* hold route_lock */
4035 if ((playlist = track.diskstream()->playlist()) == 0) {
4039 /* external redirects will be a problem */
4041 if (track.has_external_redirects()) {
4045 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4047 for (x = 0; x < 99999; ++x) {
4048 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4049 if (access (buf, F_OK) != 0) {
4055 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4060 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4061 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4064 catch (failed_constructor& err) {
4065 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4069 srcs.push_back (fsource);
4072 /* XXX need to flush all redirects */
4077 /* create a set of reasonably-sized buffers */
4078 buffers.ensure_buffers(nchans, chunk_size);
4079 buffers.set_count(nchans);
4081 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4082 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4084 afs->prepare_for_peakfile_writes ();
4087 while (to_do && !itt.cancel) {
4089 this_chunk = min (to_do, chunk_size);
4091 if (track.export_stuff (buffers, start, this_chunk)) {
4096 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4097 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4100 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4106 start += this_chunk;
4107 to_do -= this_chunk;
4109 itt.progress = (float) (1.0 - ((double) to_do / len));
4118 xnow = localtime (&now);
4120 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4121 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4124 afs->update_header (position, *xnow, now);
4125 afs->flush_header ();
4129 /* construct a region to represent the bounced material */
4131 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4132 region_name_from_path (srcs.front()->name(), true));
4139 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4140 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4143 afs->mark_for_remove ();
4146 (*src)->drop_references ();
4150 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4151 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4154 afs->done_with_peakfile_writes ();
4158 g_atomic_int_set (&processing_prohibited, 0);
4164 Session::get_silent_buffers (ChanCount count)
4166 assert(_silent_buffers->available() >= count);
4167 _silent_buffers->set_count(count);
4169 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4170 for (size_t i= 0; i < count.get(*t); ++i) {
4171 _silent_buffers->get(*t, i).clear();
4175 return *_silent_buffers;
4179 Session::get_scratch_buffers (ChanCount count)
4181 assert(_scratch_buffers->available() >= count);
4182 _scratch_buffers->set_count(count);
4183 return *_scratch_buffers;
4187 Session::get_mix_buffers (ChanCount count)
4189 assert(_mix_buffers->available() >= count);
4190 _mix_buffers->set_count(count);
4191 return *_mix_buffers;
4195 Session::ntracks () const
4198 shared_ptr<RouteList> r = routes.reader ();
4200 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4201 if (dynamic_cast<Track*> ((*i).get())) {
4210 Session::nbusses () const
4213 shared_ptr<RouteList> r = routes.reader ();
4215 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4216 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4225 Session::add_automation_list(AutomationList *al)
4227 automation_lists[al->id()] = al;
4231 Session::compute_initial_length ()
4233 return _engine.frame_rate() * 60 * 5;
4237 Session::sync_order_keys ()
4239 if (!Config->get_sync_all_route_ordering()) {
4240 /* leave order keys as they are */
4244 boost::shared_ptr<RouteList> r = routes.reader ();
4246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4247 (*i)->sync_order_keys ();
4250 Route::SyncOrderKeys (); // EMIT SIGNAL
4254 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4256 Glib::Mutex::Lock lm (bundle_lock);
4257 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {