2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
44 #include <pbd/file_utils.h>
46 #include <ardour/analyser.h>
47 #include <ardour/audio_buffer.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audio_track.h>
50 #include <ardour/audioengine.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/auditioner.h>
55 #include <ardour/buffer_set.h>
56 #include <ardour/bundle.h>
57 #include <ardour/click.h>
58 #include <ardour/configuration.h>
59 #include <ardour/crossfade.h>
60 #include <ardour/cycle_timer.h>
61 #include <ardour/data_type.h>
62 #include <ardour/filename_extensions.h>
63 #include <ardour/internal_send.h>
64 #include <ardour/io_processor.h>
65 #include <ardour/midi_diskstream.h>
66 #include <ardour/midi_playlist.h>
67 #include <ardour/midi_region.h>
68 #include <ardour/midi_track.h>
69 #include <ardour/named_selection.h>
70 #include <ardour/playlist.h>
71 #include <ardour/plugin_insert.h>
72 #include <ardour/port_insert.h>
73 #include <ardour/processor.h>
74 #include <ardour/recent_sessions.h>
75 #include <ardour/region_factory.h>
76 #include <ardour/route_group.h>
77 #include <ardour/send.h>
78 #include <ardour/session.h>
79 #include <ardour/session_directory.h>
80 #include <ardour/session_directory.h>
81 #include <ardour/session_metadata.h>
82 #include <ardour/slave.h>
83 #include <ardour/smf_source.h>
84 #include <ardour/source_factory.h>
85 #include <ardour/tape_file_matcher.h>
86 #include <ardour/tempo.h>
87 #include <ardour/utils.h>
92 using namespace ARDOUR;
94 using boost::shared_ptr;
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 sigc::signal<void,std::string> Session::Dialog;
105 sigc::signal<int> Session::AskAboutPendingState;
106 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
107 sigc::signal<void> Session::SendFeedback;
109 sigc::signal<void> Session::SMPTEOffsetChanged;
110 sigc::signal<void> Session::StartTimeChanged;
111 sigc::signal<void> Session::EndTimeChanged;
112 sigc::signal<void> Session::AutoBindingOn;
113 sigc::signal<void> Session::AutoBindingOff;
114 sigc::signal<void, std::string, std::string> Session::Exported;
116 Session::Session (AudioEngine &eng,
117 const string& fullpath,
118 const string& snapshot_name,
122 _requested_return_frame (-1),
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 _bundles (new BundleList),
145 _bundle_xml_node (0),
148 click_emphasis_data (0),
150 _metadata (new SessionMetadata())
155 if (!eng.connected()) {
156 throw failed_constructor();
159 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
161 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
162 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
164 first_stage_init (fullpath, snapshot_name);
166 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
169 if (create (new_session, mix_template, compute_initial_length())) {
171 throw failed_constructor ();
175 if (second_stage_init (new_session)) {
177 throw failed_constructor ();
180 store_recent_sessions(_name, _path);
182 bool was_dirty = dirty();
184 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
186 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
189 DirtyChanged (); /* EMIT SIGNAL */
193 Session::Session (AudioEngine &eng,
195 string snapshot_name,
196 AutoConnectOption input_ac,
197 AutoConnectOption output_ac,
198 uint32_t control_out_channels,
199 uint32_t master_out_channels,
200 uint32_t requested_physical_in,
201 uint32_t requested_physical_out,
202 nframes_t initial_length)
205 _requested_return_frame (-1),
206 _scratch_buffers(new BufferSet()),
207 _silent_buffers(new BufferSet()),
208 _mix_buffers(new BufferSet()),
210 _mmc_port (default_mmc_port),
211 _mtc_port (default_mtc_port),
212 _midi_port (default_midi_port),
213 _midi_clock_port (default_midi_clock_port),
214 _session_dir ( new SessionDirectory(fullpath)),
215 pending_events (2048),
217 butler_mixdown_buffer (0),
218 butler_gain_buffer (0),
219 post_transport_work((PostTransportWork)0),
220 _send_smpte_update (false),
221 midi_thread (pthread_t (0)),
223 diskstreams (new DiskstreamList),
224 routes (new RouteList),
225 auditioner ((Auditioner *) 0),
226 _total_free_4k_blocks (0),
227 _bundles (new BundleList),
228 _bundle_xml_node (0),
229 _click_io ((IO *) 0),
231 click_emphasis_data (0),
233 _metadata (new SessionMetadata())
237 if (!eng.connected()) {
238 throw failed_constructor();
241 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
243 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
244 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
246 if (n_physical_inputs) {
247 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
250 if (n_physical_outputs) {
251 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
254 first_stage_init (fullpath, snapshot_name);
256 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
259 if (create (new_session, string(), initial_length)) {
261 throw failed_constructor ();
266 /* set up Master Out and Control Out if necessary */
271 if (control_out_channels) {
272 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
273 r->set_remote_control_id (control_id++);
278 if (master_out_channels) {
279 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
280 r->set_remote_control_id (control_id);
284 /* prohibit auto-connect to master, because there isn't one */
285 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
289 add_routes (rl, false);
294 Config->set_input_auto_connect (input_ac);
295 Config->set_output_auto_connect (output_ac);
297 if (second_stage_init (new_session)) {
299 throw failed_constructor ();
302 store_recent_sessions (_name, _path);
304 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
306 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
317 /* if we got to here, leaving pending capture state around
321 remove_pending_capture_state ();
323 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
325 _engine.remove_session ();
327 GoingAway (); /* EMIT SIGNAL */
333 /* clear history so that no references to objects are held any more */
337 /* clear state tree so that no references to objects are held any more */
341 terminate_butler_thread ();
342 //terminate_midi_thread ();
344 if (click_data != default_click) {
345 delete [] click_data;
348 if (click_emphasis_data != default_click_emphasis) {
349 delete [] click_emphasis_data;
354 delete _scratch_buffers;
355 delete _silent_buffers;
358 AudioDiskstream::free_working_buffers();
360 Route::SyncOrderKeys.clear();
362 #undef TRACK_DESTRUCTION
363 #ifdef TRACK_DESTRUCTION
364 cerr << "delete named selections\n";
365 #endif /* TRACK_DESTRUCTION */
366 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
367 NamedSelectionList::iterator tmp;
376 #ifdef TRACK_DESTRUCTION
377 cerr << "delete playlists\n";
378 #endif /* TRACK_DESTRUCTION */
379 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
380 PlaylistList::iterator tmp;
385 (*i)->drop_references ();
390 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
391 PlaylistList::iterator tmp;
396 (*i)->drop_references ();
402 unused_playlists.clear ();
404 #ifdef TRACK_DESTRUCTION
405 cerr << "delete regions\n";
406 #endif /* TRACK_DESTRUCTION */
408 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
409 RegionList::iterator tmp;
414 i->second->drop_references ();
421 #ifdef TRACK_DESTRUCTION
422 cerr << "delete routes\n";
423 #endif /* TRACK_DESTRUCTION */
425 RCUWriter<RouteList> writer (routes);
426 boost::shared_ptr<RouteList> r = writer.get_copy ();
427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
428 (*i)->drop_references ();
431 /* writer goes out of scope and updates master */
436 #ifdef TRACK_DESTRUCTION
437 cerr << "delete diskstreams\n";
438 #endif /* TRACK_DESTRUCTION */
440 RCUWriter<DiskstreamList> dwriter (diskstreams);
441 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
442 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
443 (*i)->drop_references ();
447 diskstreams.flush ();
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete audio sources\n";
451 #endif /* TRACK_DESTRUCTION */
452 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
453 SourceMap::iterator tmp;
458 i->second->drop_references ();
464 #ifdef TRACK_DESTRUCTION
465 cerr << "delete mix groups\n";
466 #endif /* TRACK_DESTRUCTION */
467 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
468 list<RouteGroup*>::iterator tmp;
478 #ifdef TRACK_DESTRUCTION
479 cerr << "delete edit groups\n";
480 #endif /* TRACK_DESTRUCTION */
481 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
482 list<RouteGroup*>::iterator tmp;
492 delete [] butler_mixdown_buffer;
493 delete [] butler_gain_buffer;
495 Crossfade::set_buffer_size (0);
501 Session::set_worst_io_latencies ()
503 _worst_output_latency = 0;
504 _worst_input_latency = 0;
506 if (!_engine.connected()) {
510 boost::shared_ptr<RouteList> r = routes.reader ();
512 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
513 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
514 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
519 Session::when_engine_running ()
521 string first_physical_output;
523 /* we don't want to run execute this again */
525 BootMessage (_("Set block size and sample rate"));
527 set_block_size (_engine.frames_per_cycle());
528 set_frame_rate (_engine.frame_rate());
530 BootMessage (_("Using configuration"));
532 Config->map_parameters (mem_fun (*this, &Session::config_changed));
534 /* every time we reconnect, recompute worst case output latencies */
536 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
538 if (synced_to_jack()) {
539 _engine.transport_stop ();
542 if (Config->get_jack_time_master()) {
543 _engine.transport_locate (_transport_frame);
551 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
553 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
555 /* existing state for Click */
557 if (_click_io->set_state (*child->children().front()) == 0) {
559 _clicking = Config->get_clicking ();
563 error << _("could not setup Click I/O") << endmsg;
569 /* default state for Click */
571 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
573 if (first_physical_output.length()) {
574 if (_click_io->add_output_port (first_physical_output, this)) {
575 // relax, even though its an error
577 _clicking = Config->get_clicking ();
583 catch (failed_constructor& err) {
584 error << _("cannot setup Click I/O") << endmsg;
587 BootMessage (_("Compute I/O Latencies"));
589 set_worst_io_latencies ();
592 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
595 BootMessage (_("Set up standard connections"));
597 /* Create a set of Bundle objects that map
598 to the physical I/O currently available. We create both
599 mono and stereo bundles, so that the common cases of mono
600 and stereo tracks get bundles to put in their mixer strip
601 in / out menus. There may be a nicer way of achieving that;
602 it doesn't really scale that well to higher channel counts */
604 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
606 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
608 shared_ptr<Bundle> c (new Bundle (buf, true));
609 c->add_channel (_("mono"));
610 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
615 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
616 if (np + 1 < n_physical_outputs) {
618 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
619 shared_ptr<Bundle> c (new Bundle (buf, true));
620 c->add_channel (_("L"));
621 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
622 c->add_channel (_("R"));
623 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
629 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
631 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
633 shared_ptr<Bundle> c (new Bundle (buf, false));
634 c->add_channel (_("mono"));
635 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
640 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
641 if (np + 1 < n_physical_inputs) {
643 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
645 shared_ptr<Bundle> c (new Bundle (buf, false));
646 c->add_channel (_("L"));
647 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
648 c->add_channel (_("R"));
649 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
657 /* create master/control ports */
662 /* force the master to ignore any later call to this */
664 if (_master_out->pending_state_node) {
665 _master_out->ports_became_legal();
668 /* no panner resets till we are through */
670 _master_out->defer_pan_reset ();
672 while (_master_out->n_inputs().n_audio()
673 < _master_out->input_maximum().n_audio()) {
674 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
675 error << _("cannot setup master inputs")
681 while (_master_out->n_outputs().n_audio()
682 < _master_out->output_maximum().n_audio()) {
683 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
684 error << _("cannot setup master outputs")
691 _master_out->allow_pan_reset ();
696 BootMessage (_("Setup signal flow and plugins"));
700 /* catch up on send+insert cnts */
702 BootMessage (_("Catch up with send/insert state"));
706 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
709 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
710 if (id > insert_cnt) {
718 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
721 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
729 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
731 /* hook us up to the engine */
733 BootMessage (_("Connect to engine"));
735 _engine.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();
963 Session::set_auto_punch_location (Location* location)
967 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
968 auto_punch_start_changed_connection.disconnect();
969 auto_punch_end_changed_connection.disconnect();
970 auto_punch_changed_connection.disconnect();
971 existing->set_auto_punch (false, this);
972 remove_event (existing->start(), Event::PunchIn);
973 clear_events (Event::PunchOut);
974 auto_punch_location_changed (0);
983 if (location->end() <= location->start()) {
984 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
988 auto_punch_start_changed_connection.disconnect();
989 auto_punch_end_changed_connection.disconnect();
990 auto_punch_changed_connection.disconnect();
992 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
993 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
994 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
996 location->set_auto_punch (true, this);
999 auto_punch_changed (location);
1001 auto_punch_location_changed (location);
1005 Session::set_auto_loop_location (Location* location)
1009 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1010 auto_loop_start_changed_connection.disconnect();
1011 auto_loop_end_changed_connection.disconnect();
1012 auto_loop_changed_connection.disconnect();
1013 existing->set_auto_loop (false, this);
1014 remove_event (existing->end(), Event::AutoLoop);
1015 auto_loop_location_changed (0);
1020 if (location == 0) {
1024 if (location->end() <= location->start()) {
1025 error << _("Session: you can't use a mark for auto loop") << endmsg;
1029 last_loopend = location->end();
1031 auto_loop_start_changed_connection.disconnect();
1032 auto_loop_end_changed_connection.disconnect();
1033 auto_loop_changed_connection.disconnect();
1035 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1036 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1037 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1039 location->set_auto_loop (true, this);
1041 /* take care of our stuff first */
1043 auto_loop_changed (location);
1045 /* now tell everyone else */
1047 auto_loop_location_changed (location);
1051 Session::locations_added (Location* ignored)
1057 Session::locations_changed ()
1059 _locations.apply (*this, &Session::handle_locations_changed);
1063 Session::handle_locations_changed (Locations::LocationList& locations)
1065 Locations::LocationList::iterator i;
1067 bool set_loop = false;
1068 bool set_punch = false;
1070 for (i = locations.begin(); i != locations.end(); ++i) {
1074 if (location->is_auto_punch()) {
1075 set_auto_punch_location (location);
1078 if (location->is_auto_loop()) {
1079 set_auto_loop_location (location);
1083 if (location->is_start()) {
1084 start_location = location;
1086 if (location->is_end()) {
1087 end_location = location;
1092 set_auto_loop_location (0);
1095 set_auto_punch_location (0);
1102 Session::enable_record ()
1104 /* XXX really atomic compare+swap here */
1105 if (g_atomic_int_get (&_record_status) != Recording) {
1106 g_atomic_int_set (&_record_status, Recording);
1107 _last_record_location = _transport_frame;
1108 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1110 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1111 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1112 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1113 if ((*i)->record_enabled ()) {
1114 (*i)->monitor_input (true);
1119 RecordStateChanged ();
1124 Session::disable_record (bool rt_context, bool force)
1128 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1130 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1131 g_atomic_int_set (&_record_status, Disabled);
1133 if (rs == Recording) {
1134 g_atomic_int_set (&_record_status, Enabled);
1138 // FIXME: timestamp correct? [DR]
1139 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1140 // does this /need/ to be sent in all cases?
1142 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1144 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1145 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1147 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1148 if ((*i)->record_enabled ()) {
1149 (*i)->monitor_input (false);
1154 RecordStateChanged (); /* emit signal */
1157 remove_pending_capture_state ();
1163 Session::step_back_from_record ()
1165 /* XXX really atomic compare+swap here */
1166 if (g_atomic_int_get (&_record_status) == Recording) {
1167 g_atomic_int_set (&_record_status, Enabled);
1169 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1170 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1172 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1173 if ((*i)->record_enabled ()) {
1174 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1175 (*i)->monitor_input (false);
1183 Session::maybe_enable_record ()
1185 g_atomic_int_set (&_record_status, Enabled);
1187 /* this function is currently called from somewhere other than an RT thread.
1188 this save_state() call therefore doesn't impact anything.
1191 save_state ("", true);
1193 if (_transport_speed) {
1194 if (!Config->get_punch_in()) {
1198 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1199 RecordStateChanged (); /* EMIT SIGNAL */
1206 Session::audible_frame () const
1212 /* the first of these two possible settings for "offset"
1213 mean that the audible frame is stationary until
1214 audio emerges from the latency compensation
1217 the second means that the audible frame is stationary
1218 until audio would emerge from a physical port
1219 in the absence of any plugin latency compensation
1222 offset = _worst_output_latency;
1224 if (offset > current_block_size) {
1225 offset -= current_block_size;
1227 /* XXX is this correct? if we have no external
1228 physical connections and everything is internal
1229 then surely this is zero? still, how
1230 likely is that anyway?
1232 offset = current_block_size;
1235 if (synced_to_jack()) {
1236 tf = _engine.transport_frame();
1238 tf = _transport_frame;
1243 if (!non_realtime_work_pending()) {
1247 /* check to see if we have passed the first guaranteed
1248 audible frame past our last start position. if not,
1249 return that last start point because in terms
1250 of audible frames, we have not moved yet.
1253 if (_transport_speed > 0.0f) {
1255 if (!play_loop || !have_looped) {
1256 if (tf < _last_roll_location + offset) {
1257 return _last_roll_location;
1265 } else if (_transport_speed < 0.0f) {
1267 /* XXX wot? no backward looping? */
1269 if (tf > _last_roll_location - offset) {
1270 return _last_roll_location;
1282 Session::set_frame_rate (nframes_t frames_per_second)
1284 /** \fn void Session::set_frame_size(nframes_t)
1285 the AudioEngine object that calls this guarantees
1286 that it will not be called while we are also in
1287 ::process(). Its fine to do things that block
1291 _base_frame_rate = frames_per_second;
1295 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1299 // XXX we need some equivalent to this, somehow
1300 // SndFileSource::setup_standard_crossfades (frames_per_second);
1304 /* XXX need to reset/reinstantiate all LADSPA plugins */
1308 Session::set_block_size (nframes_t nframes)
1310 /* the AudioEngine guarantees
1311 that it will not be called while we are also in
1312 ::process(). It is therefore fine to do things that block
1318 current_block_size = nframes;
1320 ensure_buffers(_scratch_buffers->available());
1322 delete [] _gain_automation_buffer;
1323 _gain_automation_buffer = new gain_t[nframes];
1325 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1327 boost::shared_ptr<RouteList> r = routes.reader ();
1329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1330 (*i)->set_block_size (nframes);
1333 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1334 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1335 (*i)->set_block_size (nframes);
1338 set_worst_io_latencies ();
1343 Session::set_default_fade (float steepness, float fade_msecs)
1346 nframes_t fade_frames;
1348 /* Don't allow fade of less 1 frame */
1350 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1357 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1361 default_fade_msecs = fade_msecs;
1362 default_fade_steepness = steepness;
1365 // jlc, WTF is this!
1366 Glib::RWLock::ReaderLock lm (route_lock);
1367 AudioRegion::set_default_fade (steepness, fade_frames);
1372 /* XXX have to do this at some point */
1373 /* foreach region using default fade, reset, then
1374 refill_all_diskstream_buffers ();
1379 struct RouteSorter {
1380 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1381 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1383 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1386 if (r1->fed_by.empty()) {
1387 if (r2->fed_by.empty()) {
1388 /* no ardour-based connections inbound to either route. just use signal order */
1389 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1391 /* r2 has connections, r1 does not; run r1 early */
1395 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1402 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1404 shared_ptr<Route> r2;
1406 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1407 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1411 /* make a copy of the existing list of routes that feed r1 */
1413 set<shared_ptr<Route> > existing = r1->fed_by;
1415 /* for each route that feeds r1, recurse, marking it as feeding
1419 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1422 /* r2 is a route that feeds r1 which somehow feeds base. mark
1423 base as being fed by r2
1426 rbase->fed_by.insert (r2);
1430 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1434 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1438 /* now recurse, so that we can mark base as being fed by
1439 all routes that feed r2
1442 trace_terminal (r2, rbase);
1449 Session::resort_routes ()
1451 /* don't do anything here with signals emitted
1452 by Routes while we are being destroyed.
1455 if (_state_of_the_state & Deletion) {
1462 RCUWriter<RouteList> writer (routes);
1463 shared_ptr<RouteList> r = writer.get_copy ();
1464 resort_routes_using (r);
1465 /* writer goes out of scope and forces update */
1470 Session::resort_routes_using (shared_ptr<RouteList> r)
1472 RouteList::iterator i, j;
1474 for (i = r->begin(); i != r->end(); ++i) {
1476 (*i)->fed_by.clear ();
1478 for (j = r->begin(); j != r->end(); ++j) {
1480 /* although routes can feed themselves, it will
1481 cause an endless recursive descent if we
1482 detect it. so don't bother checking for
1490 if ((*j)->feeds (*i)) {
1491 (*i)->fed_by.insert (*j);
1496 for (i = r->begin(); i != r->end(); ++i) {
1497 trace_terminal (*i, *i);
1504 cerr << "finished route resort\n";
1506 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1507 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1514 list<boost::shared_ptr<MidiTrack> >
1515 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1517 char track_name[32];
1518 uint32_t track_id = 0;
1521 RouteList new_routes;
1522 list<boost::shared_ptr<MidiTrack> > ret;
1523 //uint32_t control_id;
1525 // FIXME: need physical I/O and autoconnect stuff for MIDI
1527 /* count existing midi tracks */
1530 shared_ptr<RouteList> r = routes.reader ();
1532 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1533 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1534 if (!(*i)->is_hidden()) {
1536 //channels_used += (*i)->n_inputs().n_midi();
1542 vector<string> physinputs;
1543 vector<string> physoutputs;
1545 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1546 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1548 // control_id = ntracks() + nbusses();
1552 /* check for duplicate route names, since we might have pre-existing
1553 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1554 save, close,restart,add new route - first named route is now
1562 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1564 if (route_by_name (track_name) == 0) {
1568 } while (track_id < (UINT_MAX-1));
1570 shared_ptr<MidiTrack> track;
1573 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1575 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1576 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1582 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1586 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1587 port = physinputs[(channels_used+x)%nphysical_in];
1590 if (port.length() && track->connect_input (track->input (x), port, this)) {
1596 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1600 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1601 port = physoutputs[(channels_used+x)%nphysical_out];
1602 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1604 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1608 if (port.length() && track->connect_output (track->output (x), port, this)) {
1613 channels_used += track->n_inputs ().n_midi();
1617 track->midi_diskstream()->non_realtime_input_change();
1619 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1620 //track->set_remote_control_id (control_id);
1622 new_routes.push_back (track);
1623 ret.push_back (track);
1626 catch (failed_constructor &err) {
1627 error << _("Session: could not create new midi track.") << endmsg;
1630 /* we need to get rid of this, since the track failed to be created */
1631 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1634 RCUWriter<DiskstreamList> writer (diskstreams);
1635 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1636 ds->remove (track->midi_diskstream());
1643 catch (AudioEngine::PortRegistrationFailure& pfe) {
1645 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;
1648 /* we need to get rid of this, since the track failed to be created */
1649 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1652 RCUWriter<DiskstreamList> writer (diskstreams);
1653 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1654 ds->remove (track->midi_diskstream());
1665 if (!new_routes.empty()) {
1666 add_routes (new_routes, false);
1667 save_state (_current_snapshot_name);
1673 list<boost::shared_ptr<AudioTrack> >
1674 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1676 char track_name[32];
1677 uint32_t track_id = 0;
1679 uint32_t channels_used = 0;
1681 RouteList new_routes;
1682 list<boost::shared_ptr<AudioTrack> > ret;
1683 uint32_t control_id;
1685 /* count existing audio tracks */
1688 shared_ptr<RouteList> r = routes.reader ();
1690 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1691 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1692 if (!(*i)->is_hidden()) {
1694 channels_used += (*i)->n_inputs().n_audio();
1700 vector<string> physinputs;
1701 vector<string> physoutputs;
1703 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1704 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1706 control_id = ntracks() + nbusses() + 1;
1710 /* check for duplicate route names, since we might have pre-existing
1711 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1712 save, close,restart,add new route - first named route is now
1720 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1722 if (route_by_name (track_name) == 0) {
1726 } while (track_id < (UINT_MAX-1));
1728 shared_ptr<AudioTrack> track;
1731 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1733 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1734 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1735 input_channels, output_channels)
1740 if (!physinputs.empty()) {
1741 uint32_t nphysical_in = physinputs.size();
1743 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1747 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1748 port = physinputs[(channels_used+x)%nphysical_in];
1751 if (port.length() && track->connect_input (track->input (x), port, this)) {
1757 if (!physoutputs.empty()) {
1758 uint32_t nphysical_out = physoutputs.size();
1760 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1764 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1765 port = physoutputs[(channels_used+x)%nphysical_out];
1766 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1768 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1772 if (port.length() && track->connect_output (track->output (x), port, this)) {
1778 channels_used += track->n_inputs ().n_audio();
1780 track->audio_diskstream()->non_realtime_input_change();
1782 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1783 track->set_remote_control_id (control_id);
1786 new_routes.push_back (track);
1787 ret.push_back (track);
1790 catch (failed_constructor &err) {
1791 error << _("Session: could not create new audio track.") << endmsg;
1794 /* we need to get rid of this, since the track failed to be created */
1795 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1798 RCUWriter<DiskstreamList> writer (diskstreams);
1799 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1800 ds->remove (track->audio_diskstream());
1807 catch (AudioEngine::PortRegistrationFailure& pfe) {
1809 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;
1812 /* we need to get rid of this, since the track failed to be created */
1813 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1816 RCUWriter<DiskstreamList> writer (diskstreams);
1817 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1818 ds->remove (track->audio_diskstream());
1829 if (!new_routes.empty()) {
1830 add_routes (new_routes, true);
1837 Session::set_remote_control_ids ()
1839 RemoteModel m = Config->get_remote_model();
1841 shared_ptr<RouteList> r = routes.reader ();
1843 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1844 if ( MixerOrdered == m) {
1845 long order = (*i)->order_key(N_("signal"));
1846 (*i)->set_remote_control_id( order+1 );
1847 } else if ( EditorOrdered == m) {
1848 long order = (*i)->order_key(N_("editor"));
1849 (*i)->set_remote_control_id( order+1 );
1850 } else if ( UserOrdered == m) {
1851 //do nothing ... only changes to remote id's are initiated by user
1858 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1861 uint32_t bus_id = 1;
1863 uint32_t channels_used = 0;
1866 uint32_t control_id;
1868 /* count existing audio busses */
1871 shared_ptr<RouteList> r = routes.reader ();
1873 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1874 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1876 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1879 channels_used += (*i)->n_inputs().n_audio();
1885 vector<string> physinputs;
1886 vector<string> physoutputs;
1888 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1889 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1891 n_physical_audio_outputs = physoutputs.size();
1892 n_physical_audio_inputs = physinputs.size();
1894 control_id = ntracks() + nbusses() + 1;
1899 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1903 if (route_by_name (bus_name) == 0) {
1907 } while (bus_id < (UINT_MAX-1));
1910 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1912 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1913 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1914 input_channels, output_channels)
1922 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1926 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1927 port = physinputs[((n+x)%n_physical_audio_inputs)];
1930 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1936 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1939 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1940 port = physoutputs[((n+x)%n_physical_outputs)];
1941 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1943 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1947 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1952 channels_used += bus->n_inputs ().n_audio();
1954 bus->set_remote_control_id (control_id);
1957 ret.push_back (bus);
1961 catch (failed_constructor &err) {
1962 error << _("Session: could not create new audio route.") << endmsg;
1966 catch (AudioEngine::PortRegistrationFailure& pfe) {
1967 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;
1977 add_routes (ret, true);
1985 Session::add_routes (RouteList& new_routes, bool save)
1988 RCUWriter<RouteList> writer (routes);
1989 shared_ptr<RouteList> r = writer.get_copy ();
1990 r->insert (r->end(), new_routes.begin(), new_routes.end());
1991 resort_routes_using (r);
1994 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1996 boost::weak_ptr<Route> wpr (*x);
1998 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1999 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2000 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2001 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2003 if ((*x)->is_master()) {
2007 if ((*x)->is_control()) {
2008 _control_out = (*x);
2012 if (_control_out && IO::connecting_legal) {
2014 vector<string> cports;
2015 uint32_t ni = _control_out->n_inputs().n_audio();
2017 for (uint32_t n = 0; n < ni; ++n) {
2018 cports.push_back (_control_out->input(n)->name());
2021 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2022 (*x)->set_control_outs (cports);
2029 save_state (_current_snapshot_name);
2032 RouteAdded (new_routes); /* EMIT SIGNAL */
2036 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2038 /* need to do this in case we're rolling at the time, to prevent false underruns */
2039 dstream->do_refill_with_alloc ();
2041 dstream->set_block_size (current_block_size);
2044 RCUWriter<DiskstreamList> writer (diskstreams);
2045 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2046 ds->push_back (dstream);
2047 /* writer goes out of scope, copies ds back to main */
2050 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2051 /* this will connect to future changes, and check the current length */
2052 diskstream_playlist_changed (dstream);
2054 dstream->prepare ();
2059 Session::remove_route (shared_ptr<Route> route)
2062 RCUWriter<RouteList> writer (routes);
2063 shared_ptr<RouteList> rs = writer.get_copy ();
2067 /* deleting the master out seems like a dumb
2068 idea, but its more of a UI policy issue
2072 if (route == _master_out) {
2073 _master_out = shared_ptr<Route> ();
2076 if (route == _control_out) {
2077 _control_out = shared_ptr<Route> ();
2079 /* cancel control outs for all routes */
2081 vector<string> empty;
2083 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2084 (*r)->set_control_outs (empty);
2088 update_route_solo_state ();
2090 /* writer goes out of scope, forces route list update */
2094 boost::shared_ptr<Diskstream> ds;
2096 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2097 ds = t->diskstream();
2103 RCUWriter<DiskstreamList> dsl (diskstreams);
2104 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2109 find_current_end ();
2111 // We need to disconnect the routes inputs and outputs
2113 route->disconnect_inputs (0);
2114 route->disconnect_outputs (0);
2116 update_latency_compensation (false, false);
2119 /* get rid of it from the dead wood collection in the route list manager */
2121 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2125 /* try to cause everyone to drop their references */
2127 route->drop_references ();
2129 sync_order_keys (N_("session"));
2131 /* save the new state of the world */
2133 if (save_state (_current_snapshot_name)) {
2134 save_history (_current_snapshot_name);
2139 Session::route_mute_changed (void* src)
2145 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2147 if (solo_update_disabled) {
2153 boost::shared_ptr<Route> route = wpr.lock ();
2156 /* should not happen */
2157 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2161 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2163 shared_ptr<RouteList> r = routes.reader ();
2165 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2167 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2171 /* don't mess with busses */
2173 if (dynamic_cast<Track*>((*i).get()) == 0) {
2179 /* don't mess with tracks */
2181 if (dynamic_cast<Track*>((*i).get()) != 0) {
2186 if ((*i) != route &&
2187 ((*i)->mix_group () == 0 ||
2188 (*i)->mix_group () != route->mix_group () ||
2189 !route->mix_group ()->is_active())) {
2191 if ((*i)->soloed()) {
2193 /* if its already soloed, and solo latching is enabled,
2194 then leave it as it is.
2197 if (Config->get_solo_latched()) {
2204 solo_update_disabled = true;
2205 (*i)->set_solo (false, src);
2206 solo_update_disabled = false;
2210 bool something_soloed = false;
2211 bool same_thing_soloed = false;
2212 bool signal = false;
2214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2215 if ((*i)->soloed()) {
2216 something_soloed = true;
2217 if (dynamic_cast<Track*>((*i).get())) {
2219 same_thing_soloed = true;
2224 same_thing_soloed = true;
2232 if (something_soloed != currently_soloing) {
2234 currently_soloing = something_soloed;
2237 modify_solo_mute (is_track, same_thing_soloed);
2240 SoloActive (currently_soloing); /* EMIT SIGNAL */
2243 SoloChanged (); /* EMIT SIGNAL */
2249 Session::update_route_solo_state ()
2252 bool is_track = false;
2253 bool signal = false;
2255 /* this is where we actually implement solo by changing
2256 the solo mute setting of each track.
2259 shared_ptr<RouteList> r = routes.reader ();
2261 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2262 if ((*i)->soloed()) {
2264 if (dynamic_cast<Track*>((*i).get())) {
2271 if (mute != currently_soloing) {
2273 currently_soloing = mute;
2276 if (!is_track && !mute) {
2278 /* nothing is soloed */
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 (*i)->set_solo_mute (false);
2291 modify_solo_mute (is_track, mute);
2294 SoloActive (currently_soloing);
2299 Session::modify_solo_mute (bool is_track, bool mute)
2301 shared_ptr<RouteList> r = routes.reader ();
2303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2307 /* only alter track solo mute */
2309 if (dynamic_cast<Track*>((*i).get())) {
2310 if ((*i)->soloed()) {
2311 (*i)->set_solo_mute (!mute);
2313 (*i)->set_solo_mute (mute);
2319 /* only alter bus solo mute */
2321 if (!dynamic_cast<Track*>((*i).get())) {
2323 if ((*i)->soloed()) {
2325 (*i)->set_solo_mute (false);
2329 /* don't mute master or control outs
2330 in response to another bus solo
2333 if ((*i) != _master_out &&
2334 (*i) != _control_out) {
2335 (*i)->set_solo_mute (mute);
2346 Session::catch_up_on_solo ()
2348 /* this is called after set_state() to catch the full solo
2349 state, which can't be correctly determined on a per-route
2350 basis, but needs the global overview that only the session
2353 update_route_solo_state();
2357 Session::catch_up_on_solo_mute_override ()
2359 if (Config->get_solo_model() != InverseMute) {
2363 /* this is called whenever the param solo-mute-override is
2366 shared_ptr<RouteList> r = routes.reader ();
2368 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2369 (*i)->catch_up_on_solo_mute_override ();
2374 Session::route_by_name (string name)
2376 shared_ptr<RouteList> r = routes.reader ();
2378 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2379 if ((*i)->name() == name) {
2384 return shared_ptr<Route> ((Route*) 0);
2388 Session::route_by_id (PBD::ID id)
2390 shared_ptr<RouteList> r = routes.reader ();
2392 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2393 if ((*i)->id() == id) {
2398 return shared_ptr<Route> ((Route*) 0);
2402 Session::route_by_remote_id (uint32_t id)
2404 shared_ptr<RouteList> r = routes.reader ();
2406 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2407 if ((*i)->remote_control_id() == id) {
2412 return shared_ptr<Route> ((Route*) 0);
2416 Session::find_current_end ()
2418 if (_state_of_the_state & Loading) {
2422 nframes_t max = get_maximum_extent ();
2424 if (max > end_location->end()) {
2425 end_location->set_end (max);
2427 DurationChanged(); /* EMIT SIGNAL */
2432 Session::get_maximum_extent () const
2437 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2439 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2440 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2442 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2443 if ((me = pl->get_maximum_extent()) > max) {
2451 boost::shared_ptr<Diskstream>
2452 Session::diskstream_by_name (string name)
2454 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2456 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2457 if ((*i)->name() == name) {
2462 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2465 boost::shared_ptr<Diskstream>
2466 Session::diskstream_by_id (const PBD::ID& id)
2468 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2470 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2471 if ((*i)->id() == id) {
2476 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2479 /* Region management */
2482 Session::new_region_name (string old)
2484 string::size_type last_period;
2486 string::size_type len = old.length() + 64;
2489 if ((last_period = old.find_last_of ('.')) == string::npos) {
2491 /* no period present - add one explicitly */
2494 last_period = old.length() - 1;
2499 number = atoi (old.substr (last_period+1).c_str());
2503 while (number < (UINT_MAX-1)) {
2505 RegionList::const_iterator i;
2510 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2513 for (i = regions.begin(); i != regions.end(); ++i) {
2514 if (i->second->name() == sbuf) {
2519 if (i == regions.end()) {
2524 if (number != (UINT_MAX-1)) {
2528 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2533 Session::region_name (string& result, string base, bool newlevel)
2538 assert(base.find("/") == string::npos);
2542 Glib::Mutex::Lock lm (region_lock);
2544 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2553 string::size_type pos;
2555 pos = base.find_last_of ('.');
2557 /* pos may be npos, but then we just use entire base */
2559 subbase = base.substr (0, pos);
2564 Glib::Mutex::Lock lm (region_lock);
2566 map<string,uint32_t>::iterator x;
2570 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2572 region_name_map[subbase] = 1;
2575 snprintf (buf, sizeof (buf), ".%d", x->second);
2586 Session::add_region (boost::shared_ptr<Region> region)
2588 vector<boost::shared_ptr<Region> > v;
2589 v.push_back (region);
2594 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2599 Glib::Mutex::Lock lm (region_lock);
2601 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2603 boost::shared_ptr<Region> region = *ii;
2607 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2611 RegionList::iterator x;
2613 for (x = regions.begin(); x != regions.end(); ++x) {
2615 if (region->region_list_equivalent (x->second)) {
2620 if (x == regions.end()) {
2622 pair<RegionList::key_type,RegionList::mapped_type> entry;
2624 entry.first = region->id();
2625 entry.second = region;
2627 pair<RegionList::iterator,bool> x = regions.insert (entry);
2639 /* mark dirty because something has changed even if we didn't
2640 add the region to the region list.
2647 vector<boost::weak_ptr<Region> > v;
2648 boost::shared_ptr<Region> first_r;
2650 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2652 boost::shared_ptr<Region> region = *ii;
2656 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2659 v.push_back (region);
2666 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2667 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2669 update_region_name_map (region);
2673 RegionsAdded (v); /* EMIT SIGNAL */
2679 Session::update_region_name_map (boost::shared_ptr<Region> region)
2681 string::size_type last_period = region->name().find_last_of ('.');
2683 if (last_period != string::npos && last_period < region->name().length() - 1) {
2685 string base = region->name().substr (0, last_period);
2686 string number = region->name().substr (last_period+1);
2687 map<string,uint32_t>::iterator x;
2689 /* note that if there is no number, we get zero from atoi,
2693 region_name_map[base] = atoi (number);
2698 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2700 boost::shared_ptr<Region> region (weak_region.lock ());
2706 if (what_changed & Region::HiddenChanged) {
2707 /* relay hidden changes */
2708 RegionHiddenChange (region);
2711 if (what_changed & NameChanged) {
2712 update_region_name_map (region);
2717 Session::remove_region (boost::weak_ptr<Region> weak_region)
2719 RegionList::iterator i;
2720 boost::shared_ptr<Region> region (weak_region.lock ());
2726 bool removed = false;
2729 Glib::Mutex::Lock lm (region_lock);
2731 if ((i = regions.find (region->id())) != regions.end()) {
2737 /* mark dirty because something has changed even if we didn't
2738 remove the region from the region list.
2744 RegionRemoved(region); /* EMIT SIGNAL */
2748 boost::shared_ptr<Region>
2749 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2751 RegionList::iterator i;
2752 boost::shared_ptr<Region> region;
2754 Glib::Mutex::Lock lm (region_lock);
2756 for (i = regions.begin(); i != regions.end(); ++i) {
2760 if (region->whole_file()) {
2762 if (child->source_equivalent (region)) {
2768 return boost::shared_ptr<Region> ();
2772 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2774 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2775 (*i)->get_region_list_equivalent_regions (region, result);
2779 Session::destroy_region (boost::shared_ptr<Region> region)
2781 vector<boost::shared_ptr<Source> > srcs;
2784 if (region->playlist()) {
2785 region->playlist()->destroy_region (region);
2788 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2789 srcs.push_back (region->source (n));
2793 region->drop_references ();
2795 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2797 (*i)->mark_for_remove ();
2798 (*i)->drop_references ();
2800 cerr << "source was not used by any playlist\n";
2807 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2809 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2810 destroy_region (*i);
2816 Session::remove_last_capture ()
2818 list<boost::shared_ptr<Region> > r;
2820 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2822 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2823 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2826 r.insert (r.end(), l.begin(), l.end());
2831 destroy_regions (r);
2833 save_state (_current_snapshot_name);
2839 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2845 /* Source Management */
2847 Session::add_source (boost::shared_ptr<Source> source)
2849 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2850 pair<SourceMap::iterator,bool> result;
2852 entry.first = source->id();
2853 entry.second = source;
2856 Glib::Mutex::Lock lm (source_lock);
2857 result = sources.insert (entry);
2860 if (result.second) {
2861 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2865 boost::shared_ptr<AudioFileSource> afs;
2867 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2868 if (Config->get_auto_analyse_audio()) {
2869 Analyser::queue_source_for_analysis (source, false);
2875 Session::remove_source (boost::weak_ptr<Source> src)
2877 SourceMap::iterator i;
2878 boost::shared_ptr<Source> source = src.lock();
2885 Glib::Mutex::Lock lm (source_lock);
2887 if ((i = sources.find (source->id())) != sources.end()) {
2892 if (!_state_of_the_state & InCleanup) {
2894 /* save state so we don't end up with a session file
2895 referring to non-existent sources.
2898 save_state (_current_snapshot_name);
2902 boost::shared_ptr<Source>
2903 Session::source_by_id (const PBD::ID& id)
2905 Glib::Mutex::Lock lm (source_lock);
2906 SourceMap::iterator i;
2907 boost::shared_ptr<Source> source;
2909 if ((i = sources.find (id)) != sources.end()) {
2917 boost::shared_ptr<Source>
2918 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2920 Glib::Mutex::Lock lm (source_lock);
2922 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2923 cerr << "comparing " << path << " with " << i->second->name() << endl;
2924 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2926 if (afs && afs->path() == path && chn == afs->channel()) {
2931 return boost::shared_ptr<Source>();
2935 Session::peak_path (Glib::ustring base) const
2937 sys::path peakfile_path(_session_dir->peak_path());
2938 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2939 return peakfile_path.to_string();
2943 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2946 string old_basename = PBD::basename_nosuffix (oldname);
2947 string new_legalized = legalize_for_path (newname);
2949 /* note: we know (or assume) the old path is already valid */
2953 /* destructive file sources have a name of the form:
2955 /path/to/Tnnnn-NAME(%[LR])?.wav
2957 the task here is to replace NAME with the new name.
2960 /* find last slash */
2964 string::size_type slash;
2965 string::size_type dash;
2967 if ((slash = path.find_last_of ('/')) == string::npos) {
2971 dir = path.substr (0, slash+1);
2973 /* '-' is not a legal character for the NAME part of the path */
2975 if ((dash = path.find_last_of ('-')) == string::npos) {
2979 prefix = path.substr (slash+1, dash-(slash+1));
2984 path += new_legalized;
2985 path += ".wav"; /* XXX gag me with a spoon */
2989 /* non-destructive file sources have a name of the form:
2991 /path/to/NAME-nnnnn(%[LR])?.wav
2993 the task here is to replace NAME with the new name.
2998 string::size_type slash;
2999 string::size_type dash;
3000 string::size_type postfix;
3002 /* find last slash */
3004 if ((slash = path.find_last_of ('/')) == string::npos) {
3008 dir = path.substr (0, slash+1);
3010 /* '-' is not a legal character for the NAME part of the path */
3012 if ((dash = path.find_last_of ('-')) == string::npos) {
3016 suffix = path.substr (dash+1);
3018 // Suffix is now everything after the dash. Now we need to eliminate
3019 // the nnnnn part, which is done by either finding a '%' or a '.'
3021 postfix = suffix.find_last_of ("%");
3022 if (postfix == string::npos) {
3023 postfix = suffix.find_last_of ('.');
3026 if (postfix != string::npos) {
3027 suffix = suffix.substr (postfix);
3029 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3033 const uint32_t limit = 10000;
3034 char buf[PATH_MAX+1];
3036 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3038 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3040 if (access (buf, F_OK) != 0) {
3048 error << "FATAL ERROR! Could not find a " << endl;
3057 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3061 char buf[PATH_MAX+1];
3062 const uint32_t limit = 10000;
3066 legalized = legalize_for_path (name);
3068 /* find a "version" of the file name that doesn't exist in
3069 any of the possible directories.
3072 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3074 vector<space_and_path>::iterator i;
3075 uint32_t existing = 0;
3077 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3079 SessionDirectory sdir((*i).path);
3081 spath = sdir.sound_path().to_string();
3085 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3086 } else if (nchan == 2) {
3088 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3090 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3092 } else if (nchan < 26) {
3093 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3095 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3104 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3105 } else if (nchan == 2) {
3107 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3109 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3111 } else if (nchan < 26) {
3112 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3114 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3118 if (sys::exists(buf)) {
3124 if (existing == 0) {
3129 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3131 throw failed_constructor();
3135 /* we now have a unique name for the file, but figure out where to
3141 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3143 spath = sdir.sound_path().to_string();
3146 string::size_type pos = foo.find_last_of ('/');
3148 if (pos == string::npos) {
3151 spath += foo.substr (pos + 1);
3157 boost::shared_ptr<AudioFileSource>
3158 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3160 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3161 return boost::dynamic_pointer_cast<AudioFileSource> (
3162 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3165 // FIXME: _terrible_ code duplication
3167 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3170 string old_basename = PBD::basename_nosuffix (oldname);
3171 string new_legalized = legalize_for_path (newname);
3173 /* note: we know (or assume) the old path is already valid */
3177 /* destructive file sources have a name of the form:
3179 /path/to/Tnnnn-NAME(%[LR])?.wav
3181 the task here is to replace NAME with the new name.
3184 /* find last slash */
3188 string::size_type slash;
3189 string::size_type dash;
3191 if ((slash = path.find_last_of ('/')) == string::npos) {
3195 dir = path.substr (0, slash+1);
3197 /* '-' is not a legal character for the NAME part of the path */
3199 if ((dash = path.find_last_of ('-')) == string::npos) {
3203 prefix = path.substr (slash+1, dash-(slash+1));
3208 path += new_legalized;
3209 path += ".mid"; /* XXX gag me with a spoon */
3213 /* non-destructive file sources have a name of the form:
3215 /path/to/NAME-nnnnn(%[LR])?.wav
3217 the task here is to replace NAME with the new name.
3222 string::size_type slash;
3223 string::size_type dash;
3224 string::size_type postfix;
3226 /* find last slash */
3228 if ((slash = path.find_last_of ('/')) == string::npos) {
3232 dir = path.substr (0, slash+1);
3234 /* '-' is not a legal character for the NAME part of the path */
3236 if ((dash = path.find_last_of ('-')) == string::npos) {
3240 suffix = path.substr (dash+1);
3242 // Suffix is now everything after the dash. Now we need to eliminate
3243 // the nnnnn part, which is done by either finding a '%' or a '.'
3245 postfix = suffix.find_last_of ("%");
3246 if (postfix == string::npos) {
3247 postfix = suffix.find_last_of ('.');
3250 if (postfix != string::npos) {
3251 suffix = suffix.substr (postfix);
3253 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3257 const uint32_t limit = 10000;
3258 char buf[PATH_MAX+1];
3260 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3262 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3264 if (access (buf, F_OK) != 0) {
3272 error << "FATAL ERROR! Could not find a " << endl;
3281 Session::midi_path_from_name (string name)
3285 char buf[PATH_MAX+1];
3286 const uint32_t limit = 10000;
3290 legalized = legalize_for_path (name);
3292 /* find a "version" of the file name that doesn't exist in
3293 any of the possible directories.
3296 for (cnt = 1; cnt <= limit; ++cnt) {
3298 vector<space_and_path>::iterator i;
3299 uint32_t existing = 0;
3301 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3303 SessionDirectory sdir((*i).path);
3305 sys::path p = sdir.midi_path();
3309 spath = p.to_string();
3311 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3313 if (sys::exists (buf)) {
3318 if (existing == 0) {
3323 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3324 throw failed_constructor();
3328 /* we now have a unique name for the file, but figure out where to
3334 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3336 spath = sdir.midi_path().to_string();
3339 string::size_type pos = foo.find_last_of ('/');
3341 if (pos == string::npos) {
3344 spath += foo.substr (pos + 1);
3350 boost::shared_ptr<MidiSource>
3351 Session::create_midi_source_for_session (MidiDiskstream& ds)
3353 string mpath = midi_path_from_name (ds.name());
3355 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3359 /* Playlist management */
3361 boost::shared_ptr<Playlist>
3362 Session::playlist_by_name (string name)
3364 Glib::Mutex::Lock lm (playlist_lock);
3365 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3366 if ((*i)->name() == name) {
3370 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3371 if ((*i)->name() == name) {
3376 return boost::shared_ptr<Playlist>();
3380 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3382 Glib::Mutex::Lock lm (playlist_lock);
3383 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3384 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3385 list.push_back (*i);
3388 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3389 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3390 list.push_back (*i);
3396 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3398 if (playlist->hidden()) {
3403 Glib::Mutex::Lock lm (playlist_lock);
3404 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3405 playlists.insert (playlists.begin(), playlist);
3406 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3407 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3412 playlist->release();
3417 PlaylistAdded (playlist); /* EMIT SIGNAL */
3421 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3424 Glib::Mutex::Lock lm (playlist_lock);
3425 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3428 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3435 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3437 boost::shared_ptr<Playlist> pl(wpl.lock());
3443 PlaylistList::iterator x;
3446 /* its not supposed to be visible */
3451 Glib::Mutex::Lock lm (playlist_lock);
3455 unused_playlists.insert (pl);
3457 if ((x = playlists.find (pl)) != playlists.end()) {
3458 playlists.erase (x);
3464 playlists.insert (pl);
3466 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3467 unused_playlists.erase (x);
3474 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3476 if (_state_of_the_state & Deletion) {
3480 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3487 Glib::Mutex::Lock lm (playlist_lock);
3489 PlaylistList::iterator i;
3491 i = find (playlists.begin(), playlists.end(), playlist);
3492 if (i != playlists.end()) {
3493 playlists.erase (i);
3496 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3497 if (i != unused_playlists.end()) {
3498 unused_playlists.erase (i);
3505 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3509 Session::set_audition (boost::shared_ptr<Region> r)
3511 pending_audition_region = r;
3512 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3513 schedule_butler_transport_work ();
3517 Session::audition_playlist ()
3519 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3520 ev->region.reset ();
3525 Session::non_realtime_set_audition ()
3527 if (!pending_audition_region) {
3528 auditioner->audition_current_playlist ();
3530 auditioner->audition_region (pending_audition_region);
3531 pending_audition_region.reset ();
3533 AuditionActive (true); /* EMIT SIGNAL */
3537 Session::audition_region (boost::shared_ptr<Region> r)
3539 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3545 Session::cancel_audition ()
3547 if (auditioner->active()) {
3548 auditioner->cancel_audition ();
3549 AuditionActive (false); /* EMIT SIGNAL */
3554 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3556 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3560 Session::remove_empty_sounds ()
3562 vector<string> audio_filenames;
3564 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3566 Glib::Mutex::Lock lm (source_lock);
3568 TapeFileMatcher tape_file_matcher;
3570 remove_if (audio_filenames.begin(), audio_filenames.end(),
3571 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3573 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3575 sys::path audio_file_path (_session_dir->sound_path());
3577 audio_file_path /= *i;
3579 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3583 sys::remove (audio_file_path);
3584 const string peakfile = peak_path (audio_file_path.to_string());
3585 sys::remove (peakfile);
3587 catch (const sys::filesystem_error& err)
3589 error << err.what() << endmsg;
3596 Session::is_auditioning () const
3598 /* can be called before we have an auditioner object */
3600 return auditioner->active();
3607 Session::set_all_solo (bool yn)
3609 shared_ptr<RouteList> r = routes.reader ();
3611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3612 if (!(*i)->is_hidden()) {
3613 (*i)->set_solo (yn, this);
3621 Session::set_all_mute (bool yn)
3623 shared_ptr<RouteList> r = routes.reader ();
3625 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3626 if (!(*i)->is_hidden()) {
3627 (*i)->set_mute (yn, this);
3635 Session::n_diskstreams () const
3639 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3641 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3642 if (!(*i)->hidden()) {
3650 Session::graph_reordered ()
3652 /* don't do this stuff if we are setting up connections
3653 from a set_state() call or creating new tracks.
3656 if (_state_of_the_state & InitialConnecting) {
3660 /* every track/bus asked for this to be handled but it was deferred because
3661 we were connecting. do it now.
3664 request_input_change_handling ();
3668 /* force all diskstreams to update their capture offset values to
3669 reflect any changes in latencies within the graph.
3672 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3674 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3675 (*i)->set_capture_offset ();
3680 Session::record_disenable_all ()
3682 record_enable_change_all (false);
3686 Session::record_enable_all ()
3688 record_enable_change_all (true);
3692 Session::record_enable_change_all (bool yn)
3694 shared_ptr<RouteList> r = routes.reader ();
3696 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3699 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3700 at->set_record_enable (yn, this);
3704 /* since we don't keep rec-enable state, don't mark session dirty */
3708 Session::add_processor (Processor* processor)
3711 PortInsert* port_insert;
3712 PluginInsert* plugin_insert;
3714 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3715 _port_inserts.insert (_port_inserts.begin(), port_insert);
3716 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3717 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3718 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3719 _sends.insert (_sends.begin(), send);
3720 } else if (dynamic_cast<InternalSend *> (processor) != 0) {
3723 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3727 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3733 Session::remove_processor (Processor* processor)
3736 PortInsert* port_insert;
3737 PluginInsert* plugin_insert;
3739 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3740 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3741 if (x != _port_inserts.end()) {
3742 insert_bitset[port_insert->bit_slot()] = false;
3743 _port_inserts.erase (x);
3745 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3746 _plugin_inserts.remove (plugin_insert);
3747 } else if (dynamic_cast<InternalSend *> (processor) != 0) {
3749 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3750 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3751 if (x != _sends.end()) {
3752 send_bitset[send->bit_slot()] = false;
3756 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3764 Session::available_capture_duration ()
3766 float sample_bytes_on_disk = 4.0; // keep gcc happy
3768 switch (Config->get_native_file_data_format()) {
3770 sample_bytes_on_disk = 4.0;
3774 sample_bytes_on_disk = 3.0;
3778 sample_bytes_on_disk = 2.0;
3782 /* impossible, but keep some gcc versions happy */
3783 fatal << string_compose (_("programming error: %1"),
3784 X_("illegal native file data format"))
3789 double scale = 4096.0 / sample_bytes_on_disk;
3791 if (_total_free_4k_blocks * scale > (double) max_frames) {
3795 return (nframes_t) floor (_total_free_4k_blocks * scale);
3799 Session::add_bundle (shared_ptr<Bundle> bundle)
3802 RCUWriter<BundleList> writer (_bundles);
3803 boost::shared_ptr<BundleList> b = writer.get_copy ();
3804 b->push_back (bundle);
3807 BundleAdded (bundle); /* EMIT SIGNAL */
3813 Session::remove_bundle (shared_ptr<Bundle> bundle)
3815 bool removed = false;
3818 RCUWriter<BundleList> writer (_bundles);
3819 boost::shared_ptr<BundleList> b = writer.get_copy ();
3820 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3822 if (i != b->end()) {
3829 BundleRemoved (bundle); /* EMIT SIGNAL */
3836 Session::bundle_by_name (string name) const
3838 boost::shared_ptr<BundleList> b = _bundles.reader ();
3840 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3841 if ((*i)->name() == name) {
3846 return boost::shared_ptr<Bundle> ();
3850 Session::tempo_map_changed (Change ignored)
3854 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3855 (*i)->update_after_tempo_map_change ();
3858 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3859 (*i)->update_after_tempo_map_change ();
3865 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3866 * the given count with the current block size.
3869 Session::ensure_buffers (ChanCount howmany)
3871 if (current_block_size == 0)
3872 return; // too early? (is this ok?)
3874 // We need at least 2 MIDI scratch buffers to mix/merge
3875 if (howmany.n_midi() < 2)
3876 howmany.set_midi(2);
3878 // FIXME: JACK needs to tell us maximum MIDI buffer size
3879 // Using nasty assumption (max # events == nframes) for now
3880 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3881 _mix_buffers->ensure_buffers(howmany, current_block_size);
3882 _silent_buffers->ensure_buffers(howmany, current_block_size);
3884 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3888 Session::next_insert_id ()
3890 /* this doesn't really loop forever. just think about it */
3893 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3894 if (!insert_bitset[n]) {
3895 insert_bitset[n] = true;
3901 /* none available, so resize and try again */
3903 insert_bitset.resize (insert_bitset.size() + 16, false);
3908 Session::next_send_id ()
3910 /* this doesn't really loop forever. just think about it */
3913 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3914 if (!send_bitset[n]) {
3915 send_bitset[n] = true;
3921 /* none available, so resize and try again */
3923 send_bitset.resize (send_bitset.size() + 16, false);
3928 Session::mark_send_id (uint32_t id)
3930 if (id >= send_bitset.size()) {
3931 send_bitset.resize (id+16, false);
3933 if (send_bitset[id]) {
3934 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3936 send_bitset[id] = true;
3940 Session::mark_insert_id (uint32_t id)
3942 if (id >= insert_bitset.size()) {
3943 insert_bitset.resize (id+16, false);
3945 if (insert_bitset[id]) {
3946 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3948 insert_bitset[id] = true;
3951 /* Named Selection management */
3954 Session::named_selection_by_name (string name)
3956 Glib::Mutex::Lock lm (named_selection_lock);
3957 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3958 if ((*i)->name == name) {
3966 Session::add_named_selection (NamedSelection* named_selection)
3969 Glib::Mutex::Lock lm (named_selection_lock);
3970 named_selections.insert (named_selections.begin(), named_selection);
3973 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3979 NamedSelectionAdded (); /* EMIT SIGNAL */
3983 Session::remove_named_selection (NamedSelection* named_selection)
3985 bool removed = false;
3988 Glib::Mutex::Lock lm (named_selection_lock);
3990 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3992 if (i != named_selections.end()) {
3994 named_selections.erase (i);
4001 NamedSelectionRemoved (); /* EMIT SIGNAL */
4006 Session::reset_native_file_format ()
4008 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4010 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4011 (*i)->reset_write_sources (false);
4016 Session::route_name_unique (string n) const
4018 shared_ptr<RouteList> r = routes.reader ();
4020 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4021 if ((*i)->name() == n) {
4030 Session::n_playlists () const
4032 Glib::Mutex::Lock lm (playlist_lock);
4033 return playlists.size();
4037 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4039 if (!force && howmany <= _npan_buffers) {
4043 if (_pan_automation_buffer) {
4045 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4046 delete [] _pan_automation_buffer[i];
4049 delete [] _pan_automation_buffer;
4052 _pan_automation_buffer = new pan_t*[howmany];
4054 for (uint32_t i = 0; i < howmany; ++i) {
4055 _pan_automation_buffer[i] = new pan_t[nframes];
4058 _npan_buffers = howmany;
4062 Session::freeze (InterThreadInfo& itt)
4064 shared_ptr<RouteList> r = routes.reader ();
4066 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4070 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4071 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4081 boost::shared_ptr<Region>
4082 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4083 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4085 boost::shared_ptr<Region> result;
4086 boost::shared_ptr<Playlist> playlist;
4087 boost::shared_ptr<AudioFileSource> fsource;
4089 char buf[PATH_MAX+1];
4090 ChanCount nchans(track.audio_diskstream()->n_channels());
4092 nframes_t this_chunk;
4095 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4096 const string sound_dir = sdir.sound_path().to_string();
4097 nframes_t len = end - start;
4100 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4101 end, start) << endmsg;
4105 // any bigger than this seems to cause stack overflows in called functions
4106 const nframes_t chunk_size = (128 * 1024)/4;
4108 g_atomic_int_set (&processing_prohibited, 1);
4110 /* call tree *MUST* hold route_lock */
4112 if ((playlist = track.diskstream()->playlist()) == 0) {
4116 /* external redirects will be a problem */
4118 if (track.has_external_redirects()) {
4122 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4124 for (x = 0; x < 99999; ++x) {
4125 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4126 if (access (buf, F_OK) != 0) {
4132 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4137 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4138 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4141 catch (failed_constructor& err) {
4142 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4146 srcs.push_back (fsource);
4149 /* XXX need to flush all redirects */
4154 /* create a set of reasonably-sized buffers */
4155 buffers.ensure_buffers(nchans, chunk_size);
4156 buffers.set_count(nchans);
4158 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4159 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4161 afs->prepare_for_peakfile_writes ();
4164 while (to_do && !itt.cancel) {
4166 this_chunk = min (to_do, chunk_size);
4168 if (track.export_stuff (buffers, start, this_chunk)) {
4173 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4174 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4177 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4183 start += this_chunk;
4184 to_do -= this_chunk;
4186 itt.progress = (float) (1.0 - ((double) to_do / len));
4195 xnow = localtime (&now);
4197 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4198 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4201 afs->update_header (position, *xnow, now);
4202 afs->flush_header ();
4206 /* construct a region to represent the bounced material */
4208 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4209 region_name_from_path (srcs.front()->name(), true));
4214 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4215 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4218 afs->mark_for_remove ();
4221 (*src)->drop_references ();
4225 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4226 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4229 afs->done_with_peakfile_writes ();
4233 g_atomic_int_set (&processing_prohibited, 0);
4239 Session::get_silent_buffers (ChanCount count)
4241 assert(_silent_buffers->available() >= count);
4242 _silent_buffers->set_count(count);
4244 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4245 for (size_t i= 0; i < count.get(*t); ++i) {
4246 _silent_buffers->get(*t, i).clear();
4250 return *_silent_buffers;
4254 Session::get_scratch_buffers (ChanCount count)
4256 if (count != ChanCount::ZERO) {
4257 assert(_scratch_buffers->available() >= count);
4258 _scratch_buffers->set_count(count);
4260 _scratch_buffers->set_count (_scratch_buffers->available());
4263 return *_scratch_buffers;
4267 Session::get_mix_buffers (ChanCount count)
4269 assert(_mix_buffers->available() >= count);
4270 _mix_buffers->set_count(count);
4271 return *_mix_buffers;
4275 Session::ntracks () const
4278 shared_ptr<RouteList> r = routes.reader ();
4280 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4281 if (dynamic_cast<Track*> ((*i).get())) {
4290 Session::nbusses () const
4293 shared_ptr<RouteList> r = routes.reader ();
4295 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4296 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4305 Session::add_automation_list(AutomationList *al)
4307 automation_lists[al->id()] = al;
4311 Session::compute_initial_length ()
4313 return _engine.frame_rate() * 60 * 5;
4317 Session::sync_order_keys (const char* base)
4319 if (!Config->get_sync_all_route_ordering()) {
4320 /* leave order keys as they are */
4324 boost::shared_ptr<RouteList> r = routes.reader ();
4326 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4327 (*i)->sync_order_keys (base);
4330 Route::SyncOrderKeys (base); // EMIT SIGNAL