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/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/butler.h"
60 #include "ardour/click.h"
61 #include "ardour/configuration.h"
62 #include "ardour/crossfade.h"
63 #include "ardour/cycle_timer.h"
64 #include "ardour/data_type.h"
65 #include "ardour/filename_extensions.h"
66 #include "ardour/internal_send.h"
67 #include "ardour/io_processor.h"
68 #include "ardour/midi_diskstream.h"
69 #include "ardour/midi_playlist.h"
70 #include "ardour/midi_region.h"
71 #include "ardour/midi_track.h"
72 #include "ardour/named_selection.h"
73 #include "ardour/playlist.h"
74 #include "ardour/plugin_insert.h"
75 #include "ardour/port_insert.h"
76 #include "ardour/processor.h"
77 #include "ardour/rc_configuration.h"
78 #include "ardour/recent_sessions.h"
79 #include "ardour/region_factory.h"
80 #include "ardour/return.h"
81 #include "ardour/route_group.h"
82 #include "ardour/send.h"
83 #include "ardour/session.h"
84 #include "ardour/session_directory.h"
85 #include "ardour/session_directory.h"
86 #include "ardour/session_metadata.h"
87 #include "ardour/slave.h"
88 #include "ardour/smf_source.h"
89 #include "ardour/source_factory.h"
90 #include "ardour/tape_file_matcher.h"
91 #include "ardour/tempo.h"
92 #include "ardour/utils.h"
97 using namespace ARDOUR;
99 using boost::shared_ptr;
101 bool Session::_disable_all_loaded_plugins = false;
103 sigc::signal<void,std::string> Session::Dialog;
104 sigc::signal<int> Session::AskAboutPendingState;
105 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
106 sigc::signal<void> Session::SendFeedback;
108 sigc::signal<void> Session::TimecodeOffsetChanged;
109 sigc::signal<void> Session::StartTimeChanged;
110 sigc::signal<void> Session::EndTimeChanged;
111 sigc::signal<void> Session::AutoBindingOn;
112 sigc::signal<void> Session::AutoBindingOff;
113 sigc::signal<void, std::string, std::string> Session::Exported;
115 Session::Session (AudioEngine &eng,
116 const string& fullpath,
117 const string& snapshot_name,
121 _target_transport_speed (0.0),
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 (new Butler (this)),
135 post_transport_work((PostTransportWork)0),
136 _send_timecode_update (false),
137 midi_thread (pthread_t (0)),
138 midi_requests (128), // the size of this should match the midi request pool size
139 diskstreams (new DiskstreamList),
140 routes (new RouteList),
141 _total_free_4k_blocks (0),
142 _bundles (new BundleList),
143 _bundle_xml_node (0),
146 click_emphasis_data (0),
148 _metadata (new SessionMetadata()),
149 _have_rec_enabled_diskstream (false)
154 interpolation.add_channel_to (0, 0);
156 if (!eng.connected()) {
157 throw failed_constructor();
160 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
162 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
163 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
165 first_stage_init (fullpath, snapshot_name);
167 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
170 if (create (new_session, mix_template, compute_initial_length())) {
172 throw failed_constructor ();
176 if (second_stage_init (new_session)) {
178 throw failed_constructor ();
181 store_recent_sessions(_name, _path);
183 bool was_dirty = dirty();
185 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
187 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
188 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
191 DirtyChanged (); /* EMIT SIGNAL */
195 Session::Session (AudioEngine &eng,
197 string snapshot_name,
198 AutoConnectOption input_ac,
199 AutoConnectOption output_ac,
200 uint32_t control_out_channels,
201 uint32_t master_out_channels,
202 uint32_t requested_physical_in,
203 uint32_t requested_physical_out,
204 nframes_t initial_length)
207 _target_transport_speed (0.0),
208 _requested_return_frame (-1),
209 _scratch_buffers(new BufferSet()),
210 _silent_buffers(new BufferSet()),
211 _mix_buffers(new BufferSet()),
213 _mmc_port (default_mmc_port),
214 _mtc_port (default_mtc_port),
215 _midi_port (default_midi_port),
216 _midi_clock_port (default_midi_clock_port),
217 _session_dir ( new SessionDirectory(fullpath)),
218 pending_events (2048),
220 _butler (new Butler (this)),
221 post_transport_work((PostTransportWork)0),
222 _send_timecode_update (false),
223 midi_thread (pthread_t (0)),
225 diskstreams (new DiskstreamList),
226 routes (new RouteList),
227 _total_free_4k_blocks (0),
228 _bundles (new BundleList),
229 _bundle_xml_node (0),
230 _click_io ((IO *) 0),
232 click_emphasis_data (0),
234 _metadata (new SessionMetadata()),
235 _have_rec_enabled_diskstream (false)
239 interpolation.add_channel_to (0, 0);
241 if (!eng.connected()) {
242 throw failed_constructor();
245 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
247 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
248 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
250 if (n_physical_inputs) {
251 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
254 if (n_physical_outputs) {
255 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
258 first_stage_init (fullpath, snapshot_name);
260 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
263 if (create (new_session, string(), initial_length)) {
265 throw failed_constructor ();
270 /* set up Master Out and Control Out if necessary */
275 if (master_out_channels) {
276 ChanCount count(DataType::AUDIO, master_out_channels);
277 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
278 r->input()->ensure_io (count, false, this);
279 r->output()->ensure_io (count, false, this);
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);
288 if (control_out_channels) {
289 ChanCount count(DataType::AUDIO, control_out_channels);
290 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
291 r->input()->ensure_io (count, false, this);
292 r->output()->ensure_io (count, false, this);
293 r->set_remote_control_id (control_id++);
299 add_routes (rl, false);
304 if (no_auto_connect()) {
305 input_ac = AutoConnectOption (0);
306 output_ac = AutoConnectOption (0);
309 Config->set_input_auto_connect (input_ac);
310 Config->set_output_auto_connect (output_ac);
312 if (second_stage_init (new_session)) {
314 throw failed_constructor ();
317 store_recent_sessions (_name, _path);
319 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
321 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
332 /* if we got to here, leaving pending capture state around
336 remove_pending_capture_state ();
338 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
340 _engine.remove_session ();
342 GoingAway (); /* EMIT SIGNAL */
348 /* clear history so that no references to objects are held any more */
352 /* clear state tree so that no references to objects are held any more */
356 /* reset dynamic state version back to default */
358 Stateful::loading_state_version = 0;
360 _butler->terminate_thread ();
361 //terminate_midi_thread ();
363 if (click_data != default_click) {
364 delete [] click_data;
367 if (click_emphasis_data != default_click_emphasis) {
368 delete [] click_emphasis_data;
373 delete _scratch_buffers;
374 delete _silent_buffers;
377 AudioDiskstream::free_working_buffers();
379 Route::SyncOrderKeys.clear();
381 #undef TRACK_DESTRUCTION
382 #ifdef TRACK_DESTRUCTION
383 cerr << "delete named selections\n";
384 #endif /* TRACK_DESTRUCTION */
385 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
386 NamedSelectionList::iterator tmp;
395 #ifdef TRACK_DESTRUCTION
396 cerr << "delete playlists\n";
397 #endif /* TRACK_DESTRUCTION */
398 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
399 PlaylistList::iterator tmp;
404 (*i)->drop_references ();
409 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
410 PlaylistList::iterator tmp;
415 (*i)->drop_references ();
421 unused_playlists.clear ();
423 #ifdef TRACK_DESTRUCTION
424 cerr << "delete regions\n";
425 #endif /* TRACK_DESTRUCTION */
427 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
428 RegionList::iterator tmp;
433 i->second->drop_references ();
440 #ifdef TRACK_DESTRUCTION
441 cerr << "delete routes\n";
442 #endif /* TRACK_DESTRUCTION */
444 RCUWriter<RouteList> writer (routes);
445 boost::shared_ptr<RouteList> r = writer.get_copy ();
446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
447 (*i)->drop_references ();
450 /* writer goes out of scope and updates master */
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete diskstreams\n";
457 #endif /* TRACK_DESTRUCTION */
459 RCUWriter<DiskstreamList> dwriter (diskstreams);
460 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
461 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
462 (*i)->drop_references ();
466 diskstreams.flush ();
468 #ifdef TRACK_DESTRUCTION
469 cerr << "delete audio sources\n";
470 #endif /* TRACK_DESTRUCTION */
471 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
472 SourceMap::iterator tmp;
477 i->second->drop_references ();
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete route groups\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
491 Crossfade::set_buffer_size (0);
497 Session::set_worst_io_latencies ()
499 _worst_output_latency = 0;
500 _worst_input_latency = 0;
502 if (!_engine.connected()) {
506 boost::shared_ptr<RouteList> r = routes.reader ();
508 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
509 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
510 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
515 Session::when_engine_running ()
517 string first_physical_output;
519 BootMessage (_("Set block size and sample rate"));
521 set_block_size (_engine.frames_per_cycle());
522 set_frame_rate (_engine.frame_rate());
524 BootMessage (_("Using configuration"));
526 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
528 /* every time we reconnect, recompute worst case output latencies */
530 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
532 if (synced_to_jack()) {
533 _engine.transport_stop ();
536 if (config.get_jack_time_master()) {
537 _engine.transport_locate (_transport_frame);
545 _click_io.reset (new ClickIO (*this, "click"));
547 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
549 /* existing state for Click */
552 if (Stateful::loading_state_version < 3000) {
553 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
555 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
560 _clicking = Config->get_clicking ();
564 error << _("could not setup Click I/O") << endmsg;
571 /* default state for Click: dual-mono to first 2 physical outputs */
573 for (int physport = 0; physport < 2; ++physport) {
574 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
576 if (physical_output.length()) {
577 if (_click_io->add_port (physical_output, this)) {
578 // relax, even though its an error
583 if (_click_io->n_ports () > ChanCount::ZERO) {
584 _clicking = Config->get_clicking ();
589 catch (failed_constructor& err) {
590 error << _("cannot setup Click I/O") << endmsg;
593 BootMessage (_("Compute I/O Latencies"));
595 set_worst_io_latencies ();
598 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
601 BootMessage (_("Set up standard connections"));
603 /* Create a set of Bundle objects that map
604 to the physical I/O currently available. We create both
605 mono and stereo bundles, so that the common cases of mono
606 and stereo tracks get bundles to put in their mixer strip
607 in / out menus. There may be a nicer way of achieving that;
608 it doesn't really scale that well to higher channel counts
611 /* mono output bundles */
613 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
615 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
617 shared_ptr<Bundle> c (new Bundle (buf, true));
618 c->add_channel (_("mono"));
619 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
624 /* stereo output bundles */
626 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
627 if (np + 1 < n_physical_outputs) {
629 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
630 shared_ptr<Bundle> c (new Bundle (buf, true));
631 c->add_channel (_("L"));
632 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
633 c->add_channel (_("R"));
634 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
640 /* mono input bundles */
642 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
644 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
646 shared_ptr<Bundle> c (new Bundle (buf, false));
647 c->add_channel (_("mono"));
648 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
653 /* stereo input bundles */
655 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
656 if (np + 1 < n_physical_inputs) {
658 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
660 shared_ptr<Bundle> c (new Bundle (buf, false));
661 c->add_channel (_("L"));
662 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
663 c->add_channel (_("R"));
664 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
670 BootMessage (_("Setup signal flow and plugins"));
674 if (!no_auto_connect()) {
676 if (_master_out && Config->get_auto_connect_standard_busses()) {
678 /* if requested auto-connect the outputs to the first N physical ports.
681 uint32_t limit = _master_out->n_outputs().n_total();
683 for (uint32_t n = 0; n < limit; ++n) {
684 Port* p = _master_out->output()->nth (n);
685 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
687 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
688 if (_master_out->output()->connect (p, connect_to, this)) {
689 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
699 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
700 are undefined, at best.
703 /* control out listens to master bus (but ignores it
704 under some conditions)
707 uint32_t limit = _control_out->n_inputs().n_audio();
710 for (uint32_t n = 0; n < limit; ++n) {
711 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
712 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
715 string connect_to = o->name();
716 if (_control_out->input()->connect (p, connect_to, this)) {
717 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
725 /* if control out is not connected,
726 connect control out to physical outs, but use ones after the master if possible
729 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
731 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
733 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
736 _control_out->output()->connect_ports_to_bundle (b, this);
738 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
739 Config->get_monitor_bus_preferred_bundle())
745 /* XXX this logic is wrong for mixed port types */
747 uint32_t shift = _master_out->n_outputs().n_audio();
748 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
749 limit = _control_out->n_outputs().n_audio();
751 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
753 for (uint32_t n = 0; n < limit; ++n) {
755 Port* p = _control_out->output()->nth (n);
756 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
758 if (!connect_to.empty()) {
759 if (_control_out->output()->connect (p, connect_to, this)) {
760 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
771 /* catch up on send+insert cnts */
773 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
775 /* hook us up to the engine */
777 BootMessage (_("Connect to engine"));
779 _engine.set_session (this);
783 Session::hookup_io ()
785 /* stop graph reordering notifications from
786 causing resorts, etc.
789 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
794 /* we delay creating the auditioner till now because
795 it makes its own connections to ports.
796 the engine has to be running for this to work.
800 auditioner.reset (new Auditioner (*this));
803 catch (failed_constructor& err) {
804 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
808 /* load bundles, which we may have postponed earlier on */
809 if (_bundle_xml_node) {
810 load_bundles (*_bundle_xml_node);
811 delete _bundle_xml_node;
814 /* Tell all IO objects to connect themselves together */
816 IO::enable_connecting ();
818 /* Now reset all panners */
820 Delivery::reset_panners ();
822 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
826 boost::shared_ptr<RouteList> r = routes.reader ();
828 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
830 if ((*x)->is_control() || (*x)->is_master()) {
834 (*x)->listen_via (_control_out,
835 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
840 /* Anyone who cares about input state, wake up and do something */
842 IOConnectionsComplete (); /* EMIT SIGNAL */
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
846 /* now handle the whole enchilada as if it was one
852 /* update the full solo state, which can't be
853 correctly determined on a per-route basis, but
854 needs the global overview that only the session
858 update_route_solo_state ();
862 Session::playlist_length_changed ()
864 /* we can't just increase end_location->end() if pl->get_maximum_extent()
865 if larger. if the playlist used to be the longest playlist,
866 and its now shorter, we have to decrease end_location->end(). hence,
867 we have to iterate over all diskstreams and check the
868 playlists currently in use.
874 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
876 boost::shared_ptr<Playlist> playlist;
878 if ((playlist = dstream->playlist()) != 0) {
879 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
882 /* see comment in playlist_length_changed () */
887 Session::record_enabling_legal () const
889 /* this used to be in here, but survey says.... we don't need to restrict it */
890 // if (record_status() == Recording) {
894 if (Config->get_all_safe()) {
901 Session::reset_input_monitor_state ()
903 if (transport_rolling()) {
905 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
907 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
908 if ((*i)->record_enabled ()) {
909 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
910 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
914 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
916 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
917 if ((*i)->record_enabled ()) {
918 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
919 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
926 Session::auto_punch_start_changed (Location* location)
928 replace_event (Event::PunchIn, location->start());
930 if (get_record_enabled() && config.get_punch_in()) {
931 /* capture start has been changed, so save new pending state */
932 save_state ("", true);
937 Session::auto_punch_end_changed (Location* location)
939 nframes_t when_to_stop = location->end();
940 // when_to_stop += _worst_output_latency + _worst_input_latency;
941 replace_event (Event::PunchOut, when_to_stop);
945 Session::auto_punch_changed (Location* location)
947 nframes_t when_to_stop = location->end();
949 replace_event (Event::PunchIn, location->start());
950 //when_to_stop += _worst_output_latency + _worst_input_latency;
951 replace_event (Event::PunchOut, when_to_stop);
955 Session::auto_loop_changed (Location* location)
957 replace_event (Event::AutoLoop, location->end(), location->start());
959 if (transport_rolling() && play_loop) {
961 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
963 if (_transport_frame > location->end()) {
964 // relocate to beginning of loop
965 clear_events (Event::LocateRoll);
967 request_locate (location->start(), true);
970 else if (Config->get_seamless_loop() && !loop_changing) {
972 // schedule a locate-roll to refill the diskstreams at the
974 loop_changing = true;
976 if (location->end() > last_loopend) {
977 clear_events (Event::LocateRoll);
978 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
985 last_loopend = location->end();
989 Session::set_auto_punch_location (Location* location)
993 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
994 auto_punch_start_changed_connection.disconnect();
995 auto_punch_end_changed_connection.disconnect();
996 auto_punch_changed_connection.disconnect();
997 existing->set_auto_punch (false, this);
998 remove_event (existing->start(), Event::PunchIn);
999 clear_events (Event::PunchOut);
1000 auto_punch_location_changed (0);
1005 if (location == 0) {
1009 if (location->end() <= location->start()) {
1010 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1014 auto_punch_start_changed_connection.disconnect();
1015 auto_punch_end_changed_connection.disconnect();
1016 auto_punch_changed_connection.disconnect();
1018 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1019 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1020 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1022 location->set_auto_punch (true, this);
1025 auto_punch_changed (location);
1027 auto_punch_location_changed (location);
1031 Session::set_auto_loop_location (Location* location)
1035 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1036 auto_loop_start_changed_connection.disconnect();
1037 auto_loop_end_changed_connection.disconnect();
1038 auto_loop_changed_connection.disconnect();
1039 existing->set_auto_loop (false, this);
1040 remove_event (existing->end(), Event::AutoLoop);
1041 auto_loop_location_changed (0);
1046 if (location == 0) {
1050 if (location->end() <= location->start()) {
1051 error << _("Session: you can't use a mark for auto loop") << endmsg;
1055 last_loopend = location->end();
1057 auto_loop_start_changed_connection.disconnect();
1058 auto_loop_end_changed_connection.disconnect();
1059 auto_loop_changed_connection.disconnect();
1061 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1062 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1063 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1065 location->set_auto_loop (true, this);
1067 /* take care of our stuff first */
1069 auto_loop_changed (location);
1071 /* now tell everyone else */
1073 auto_loop_location_changed (location);
1077 Session::locations_added (Location *)
1083 Session::locations_changed ()
1085 _locations.apply (*this, &Session::handle_locations_changed);
1089 Session::handle_locations_changed (Locations::LocationList& locations)
1091 Locations::LocationList::iterator i;
1093 bool set_loop = false;
1094 bool set_punch = false;
1096 for (i = locations.begin(); i != locations.end(); ++i) {
1100 if (location->is_auto_punch()) {
1101 set_auto_punch_location (location);
1104 if (location->is_auto_loop()) {
1105 set_auto_loop_location (location);
1109 if (location->is_start()) {
1110 start_location = location;
1112 if (location->is_end()) {
1113 end_location = location;
1118 set_auto_loop_location (0);
1121 set_auto_punch_location (0);
1128 Session::enable_record ()
1130 /* XXX really atomic compare+swap here */
1131 if (g_atomic_int_get (&_record_status) != Recording) {
1132 g_atomic_int_set (&_record_status, Recording);
1133 _last_record_location = _transport_frame;
1134 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1136 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1137 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1138 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1139 if ((*i)->record_enabled ()) {
1140 (*i)->monitor_input (true);
1145 RecordStateChanged ();
1150 Session::disable_record (bool rt_context, bool force)
1154 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1156 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1157 g_atomic_int_set (&_record_status, Disabled);
1159 if (rs == Recording) {
1160 g_atomic_int_set (&_record_status, Enabled);
1164 // FIXME: timestamp correct? [DR]
1165 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1166 // does this /need/ to be sent in all cases?
1168 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1170 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1171 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1173 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1174 if ((*i)->record_enabled ()) {
1175 (*i)->monitor_input (false);
1180 RecordStateChanged (); /* emit signal */
1183 remove_pending_capture_state ();
1189 Session::step_back_from_record ()
1191 /* XXX really atomic compare+swap here */
1192 if (g_atomic_int_get (&_record_status) == Recording) {
1193 g_atomic_int_set (&_record_status, Enabled);
1195 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1196 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1198 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1199 if ((*i)->record_enabled ()) {
1200 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1201 (*i)->monitor_input (false);
1209 Session::maybe_enable_record ()
1211 g_atomic_int_set (&_record_status, Enabled);
1213 /* this function is currently called from somewhere other than an RT thread.
1214 this save_state() call therefore doesn't impact anything.
1217 save_state ("", true);
1219 if (_transport_speed) {
1220 if (!config.get_punch_in()) {
1224 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1225 RecordStateChanged (); /* EMIT SIGNAL */
1232 Session::audible_frame () const
1238 /* the first of these two possible settings for "offset"
1239 mean that the audible frame is stationary until
1240 audio emerges from the latency compensation
1243 the second means that the audible frame is stationary
1244 until audio would emerge from a physical port
1245 in the absence of any plugin latency compensation
1248 offset = _worst_output_latency;
1250 if (offset > current_block_size) {
1251 offset -= current_block_size;
1253 /* XXX is this correct? if we have no external
1254 physical connections and everything is internal
1255 then surely this is zero? still, how
1256 likely is that anyway?
1258 offset = current_block_size;
1261 if (synced_to_jack()) {
1262 tf = _engine.transport_frame();
1264 tf = _transport_frame;
1269 if (!non_realtime_work_pending()) {
1273 /* check to see if we have passed the first guaranteed
1274 audible frame past our last start position. if not,
1275 return that last start point because in terms
1276 of audible frames, we have not moved yet.
1279 if (_transport_speed > 0.0f) {
1281 if (!play_loop || !have_looped) {
1282 if (tf < _last_roll_location + offset) {
1283 return _last_roll_location;
1291 } else if (_transport_speed < 0.0f) {
1293 /* XXX wot? no backward looping? */
1295 if (tf > _last_roll_location - offset) {
1296 return _last_roll_location;
1308 Session::set_frame_rate (nframes_t frames_per_second)
1310 /** \fn void Session::set_frame_size(nframes_t)
1311 the AudioEngine object that calls this guarantees
1312 that it will not be called while we are also in
1313 ::process(). Its fine to do things that block
1317 _base_frame_rate = frames_per_second;
1321 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1325 // XXX we need some equivalent to this, somehow
1326 // SndFileSource::setup_standard_crossfades (frames_per_second);
1330 /* XXX need to reset/reinstantiate all LADSPA plugins */
1334 Session::set_block_size (nframes_t nframes)
1336 /* the AudioEngine guarantees
1337 that it will not be called while we are also in
1338 ::process(). It is therefore fine to do things that block
1343 current_block_size = nframes;
1345 ensure_buffers(_scratch_buffers->available());
1347 delete [] _gain_automation_buffer;
1348 _gain_automation_buffer = new gain_t[nframes];
1350 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1352 boost::shared_ptr<RouteList> r = routes.reader ();
1354 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1355 (*i)->set_block_size (nframes);
1358 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1359 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1360 (*i)->set_block_size (nframes);
1363 set_worst_io_latencies ();
1368 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1371 nframes_t fade_frames;
1373 /* Don't allow fade of less 1 frame */
1375 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1382 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1386 default_fade_msecs = fade_msecs;
1387 default_fade_steepness = steepness;
1390 // jlc, WTF is this!
1391 Glib::RWLock::ReaderLock lm (route_lock);
1392 AudioRegion::set_default_fade (steepness, fade_frames);
1397 /* XXX have to do this at some point */
1398 /* foreach region using default fade, reset, then
1399 refill_all_diskstream_buffers ();
1404 struct RouteSorter {
1405 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1406 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1408 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1411 if (r1->fed_by.empty()) {
1412 if (r2->fed_by.empty()) {
1413 /* no ardour-based connections inbound to either route. just use signal order */
1414 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1416 /* r2 has connections, r1 does not; run r1 early */
1420 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1427 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1429 shared_ptr<Route> r2;
1431 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1432 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1436 /* make a copy of the existing list of routes that feed r1 */
1438 set<shared_ptr<Route> > existing = r1->fed_by;
1440 /* for each route that feeds r1, recurse, marking it as feeding
1444 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1447 /* r2 is a route that feeds r1 which somehow feeds base. mark
1448 base as being fed by r2
1451 rbase->fed_by.insert (r2);
1455 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1459 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1463 /* now recurse, so that we can mark base as being fed by
1464 all routes that feed r2
1467 trace_terminal (r2, rbase);
1474 Session::resort_routes ()
1476 /* don't do anything here with signals emitted
1477 by Routes while we are being destroyed.
1480 if (_state_of_the_state & Deletion) {
1487 RCUWriter<RouteList> writer (routes);
1488 shared_ptr<RouteList> r = writer.get_copy ();
1489 resort_routes_using (r);
1490 /* writer goes out of scope and forces update */
1495 Session::resort_routes_using (shared_ptr<RouteList> r)
1497 RouteList::iterator i, j;
1499 for (i = r->begin(); i != r->end(); ++i) {
1501 (*i)->fed_by.clear ();
1503 for (j = r->begin(); j != r->end(); ++j) {
1505 /* although routes can feed themselves, it will
1506 cause an endless recursive descent if we
1507 detect it. so don't bother checking for
1515 if ((*j)->feeds (*i)) {
1516 (*i)->fed_by.insert (*j);
1521 for (i = r->begin(); i != r->end(); ++i) {
1522 trace_terminal (*i, *i);
1529 cerr << "finished route resort\n";
1531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1532 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1539 list<boost::shared_ptr<MidiTrack> >
1540 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1542 char track_name[32];
1543 uint32_t track_id = 0;
1546 RouteList new_routes;
1547 list<boost::shared_ptr<MidiTrack> > ret;
1548 //uint32_t control_id;
1550 // FIXME: need physical I/O and autoconnect stuff for MIDI
1552 /* count existing midi tracks */
1555 shared_ptr<RouteList> r = routes.reader ();
1557 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1558 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1559 if (!(*i)->is_hidden()) {
1561 //channels_used += (*i)->n_inputs().n_midi();
1567 vector<string> physinputs;
1568 vector<string> physoutputs;
1570 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1571 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1573 // control_id = ntracks() + nbusses();
1577 /* check for duplicate route names, since we might have pre-existing
1578 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1579 save, close,restart,add new route - first named route is now
1587 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1589 if (route_by_name (track_name) == 0) {
1593 } while (track_id < (UINT_MAX-1));
1595 shared_ptr<MidiTrack> track;
1598 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1600 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1601 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1606 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1607 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1613 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1617 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1618 port = physinputs[(channels_used+x)%nphysical_in];
1621 if (port.length() && track->connect_input (track->input (x), port, this)) {
1627 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1631 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1632 port = physoutputs[(channels_used+x)%nphysical_out];
1633 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1635 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1639 if (port.length() && track->connect_output (track->output (x), port, this)) {
1644 channels_used += track->n_inputs ().n_midi();
1648 track->midi_diskstream()->non_realtime_input_change();
1649 track->set_route_group (route_group, 0);
1651 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1652 //track->set_remote_control_id (control_id);
1654 new_routes.push_back (track);
1655 ret.push_back (track);
1658 catch (failed_constructor &err) {
1659 error << _("Session: could not create new midi track.") << endmsg;
1662 /* we need to get rid of this, since the track failed to be created */
1663 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1666 RCUWriter<DiskstreamList> writer (diskstreams);
1667 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1668 ds->remove (track->midi_diskstream());
1675 catch (AudioEngine::PortRegistrationFailure& pfe) {
1677 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;
1680 /* we need to get rid of this, since the track failed to be created */
1681 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1684 RCUWriter<DiskstreamList> writer (diskstreams);
1685 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1686 ds->remove (track->midi_diskstream());
1697 if (!new_routes.empty()) {
1698 add_routes (new_routes, false);
1699 save_state (_current_snapshot_name);
1705 list<boost::shared_ptr<AudioTrack> >
1706 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1708 char track_name[32];
1709 uint32_t track_id = 0;
1711 uint32_t channels_used = 0;
1713 RouteList new_routes;
1714 list<boost::shared_ptr<AudioTrack> > ret;
1715 uint32_t control_id;
1717 /* count existing audio tracks */
1720 shared_ptr<RouteList> r = routes.reader ();
1722 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1723 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1724 if (!(*i)->is_hidden()) {
1726 channels_used += (*i)->n_inputs().n_audio();
1732 vector<string> physinputs;
1733 vector<string> physoutputs;
1735 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1736 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1738 control_id = ntracks() + nbusses() + 1;
1742 /* check for duplicate route names, since we might have pre-existing
1743 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1744 save, close,restart,add new route - first named route is now
1752 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1754 if (route_by_name (track_name) == 0) {
1758 } while (track_id < (UINT_MAX-1));
1760 shared_ptr<AudioTrack> track;
1763 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1765 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1766 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1767 input_channels, output_channels)
1772 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1773 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1774 input_channels, output_channels)
1779 if (!physinputs.empty()) {
1780 uint32_t nphysical_in = physinputs.size();
1782 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1786 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1787 port = physinputs[(channels_used+x)%nphysical_in];
1790 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1796 if (!physoutputs.empty()) {
1797 uint32_t nphysical_out = physoutputs.size();
1799 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1802 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1803 port = physoutputs[(channels_used+x)%nphysical_out];
1804 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1805 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1806 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1810 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1816 channels_used += track->n_inputs ().n_audio();
1818 track->set_route_group (route_group, 0);
1820 track->audio_diskstream()->non_realtime_input_change();
1822 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1823 track->set_remote_control_id (control_id);
1826 new_routes.push_back (track);
1827 ret.push_back (track);
1830 catch (failed_constructor &err) {
1831 error << _("Session: could not create new audio track.") << endmsg;
1834 /* we need to get rid of this, since the track failed to be created */
1835 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1838 RCUWriter<DiskstreamList> writer (diskstreams);
1839 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1840 ds->remove (track->audio_diskstream());
1847 catch (AudioEngine::PortRegistrationFailure& pfe) {
1849 error << pfe.what() << endmsg;
1852 /* we need to get rid of this, since the track failed to be created */
1853 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1856 RCUWriter<DiskstreamList> writer (diskstreams);
1857 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1858 ds->remove (track->audio_diskstream());
1869 if (!new_routes.empty()) {
1870 add_routes (new_routes, true);
1877 Session::set_remote_control_ids ()
1879 RemoteModel m = Config->get_remote_model();
1881 shared_ptr<RouteList> r = routes.reader ();
1883 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1884 if ( MixerOrdered == m) {
1885 long order = (*i)->order_key(N_("signal"));
1886 (*i)->set_remote_control_id( order+1 );
1887 } else if ( EditorOrdered == m) {
1888 long order = (*i)->order_key(N_("editor"));
1889 (*i)->set_remote_control_id( order+1 );
1890 } else if ( UserOrdered == m) {
1891 //do nothing ... only changes to remote id's are initiated by user
1898 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1901 uint32_t bus_id = 1;
1903 uint32_t channels_used = 0;
1906 uint32_t control_id;
1908 /* count existing audio busses */
1911 shared_ptr<RouteList> r = routes.reader ();
1913 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1914 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1916 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1919 channels_used += (*i)->n_inputs().n_audio();
1925 vector<string> physinputs;
1926 vector<string> physoutputs;
1928 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1929 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1931 n_physical_audio_outputs = physoutputs.size();
1932 n_physical_audio_inputs = physinputs.size();
1934 control_id = ntracks() + nbusses() + 1;
1939 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1943 if (route_by_name (bus_name) == 0) {
1947 } while (bus_id < (UINT_MAX-1));
1950 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1952 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1953 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1954 input_channels, output_channels)
1960 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1961 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1962 input_channels, output_channels)
1967 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1970 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1971 port = physinputs[((n+x)%n_physical_audio_inputs)];
1974 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1979 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1982 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1983 port = physoutputs[((n+x)%n_physical_outputs)];
1984 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1986 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1990 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1995 channels_used += bus->n_inputs ().n_audio();
1997 bus->set_route_group (route_group, 0);
1998 bus->set_remote_control_id (control_id);
2001 ret.push_back (bus);
2005 catch (failed_constructor &err) {
2006 error << _("Session: could not create new audio route.") << endmsg;
2010 catch (AudioEngine::PortRegistrationFailure& pfe) {
2011 error << pfe.what() << endmsg;
2021 add_routes (ret, true);
2029 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2033 uint32_t control_id;
2035 uint32_t number = 1;
2037 if (!tree.read (template_path.c_str())) {
2041 XMLNode* node = tree.root();
2043 control_id = ntracks() + nbusses() + 1;
2047 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2049 std::string node_name = IO::name_from_state (*node_copy.children().front());
2051 /* generate a new name by adding a number to the end of the template name */
2054 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2058 if (route_by_name (name) == 0) {
2062 } while (number < UINT_MAX);
2064 if (number == UINT_MAX) {
2065 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2069 IO::set_name_in_state (*node_copy.children().front(), name);
2071 Track::zero_diskstream_id_in_xml (node_copy);
2074 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2077 error << _("Session: cannot create track/bus from template description") << endmsg;
2081 if (boost::dynamic_pointer_cast<Track>(route)) {
2082 /* force input/output change signals so that the new diskstream
2083 picks up the configuration of the route. During session
2084 loading this normally happens in a different way.
2086 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2087 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2090 route->set_remote_control_id (control_id);
2093 ret.push_back (route);
2096 catch (failed_constructor &err) {
2097 error << _("Session: could not create new route from template") << endmsg;
2101 catch (AudioEngine::PortRegistrationFailure& pfe) {
2102 error << pfe.what() << endmsg;
2111 add_routes (ret, true);
2118 Session::add_routes (RouteList& new_routes, bool save)
2121 RCUWriter<RouteList> writer (routes);
2122 shared_ptr<RouteList> r = writer.get_copy ();
2123 r->insert (r->end(), new_routes.begin(), new_routes.end());
2126 /* if there is no control out and we're not in the middle of loading,
2127 resort the graph here. if there is a control out, we will resort
2128 toward the end of this method. if we are in the middle of loading,
2129 we will resort when done.
2132 if (!_control_out && IO::connecting_legal) {
2133 resort_routes_using (r);
2137 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2139 boost::weak_ptr<Route> wpr (*x);
2141 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2142 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2143 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2144 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2145 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2146 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2148 if ((*x)->is_master()) {
2152 if ((*x)->is_control()) {
2153 _control_out = (*x);
2157 if (_control_out && IO::connecting_legal) {
2159 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2160 if ((*x)->is_control() || (*x)->is_master()) {
2163 (*x)->listen_via (_control_out,
2164 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2174 save_state (_current_snapshot_name);
2177 RouteAdded (new_routes); /* EMIT SIGNAL */
2181 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2183 boost::shared_ptr<RouteList> r = routes.reader ();
2184 boost::shared_ptr<Send> s;
2188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2189 if (boost::dynamic_pointer_cast<Track>(*i)) {
2190 if ((s = (*i)->internal_send_for (dest)) != 0) {
2191 s->amp()->gain_control()->set_value (0.0);
2198 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2200 boost::shared_ptr<RouteList> r = routes.reader ();
2201 boost::shared_ptr<Send> s;
2205 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2206 if (boost::dynamic_pointer_cast<Track>(*i)) {
2207 if ((s = (*i)->internal_send_for (dest)) != 0) {
2208 s->amp()->gain_control()->set_value (1.0);
2215 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2217 boost::shared_ptr<RouteList> r = routes.reader ();
2218 boost::shared_ptr<Send> s;
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2223 if (boost::dynamic_pointer_cast<Track>(*i)) {
2224 if ((s = (*i)->internal_send_for (dest)) != 0) {
2225 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2232 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2234 boost::shared_ptr<RouteList> r = routes.reader ();
2235 boost::shared_ptr<RouteList> t (new RouteList);
2237 /* only send tracks */
2239 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2240 if (boost::dynamic_pointer_cast<Track>(*i)) {
2245 add_internal_sends (dest, p, t);
2250 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2252 if (dest->is_control() || dest->is_master()) {
2256 if (!dest->internal_return()) {
2257 dest->add_internal_return();
2260 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2262 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2266 (*i)->listen_via (dest, p, true, true);
2271 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2273 /* need to do this in case we're rolling at the time, to prevent false underruns */
2274 dstream->do_refill_with_alloc ();
2276 dstream->set_block_size (current_block_size);
2279 RCUWriter<DiskstreamList> writer (diskstreams);
2280 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2281 ds->push_back (dstream);
2282 /* writer goes out of scope, copies ds back to main */
2285 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2286 /* this will connect to future changes, and check the current length */
2287 diskstream_playlist_changed (dstream);
2289 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2291 dstream->prepare ();
2296 Session::remove_route (shared_ptr<Route> route)
2299 RCUWriter<RouteList> writer (routes);
2300 shared_ptr<RouteList> rs = writer.get_copy ();
2304 /* deleting the master out seems like a dumb
2305 idea, but its more of a UI policy issue
2309 if (route == _master_out) {
2310 _master_out = shared_ptr<Route> ();
2313 if (route == _control_out) {
2315 /* cancel control outs for all routes */
2317 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2318 (*r)->drop_listen (_control_out);
2321 _control_out.reset ();
2324 update_route_solo_state ();
2326 /* writer goes out of scope, forces route list update */
2329 boost::shared_ptr<Track> t;
2330 boost::shared_ptr<Diskstream> ds;
2332 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2333 ds = t->diskstream();
2339 RCUWriter<DiskstreamList> dsl (diskstreams);
2340 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2345 find_current_end ();
2347 // We need to disconnect the routes inputs and outputs
2349 route->input()->disconnect (0);
2350 route->output()->disconnect (0);
2352 update_latency_compensation (false, false);
2355 /* get rid of it from the dead wood collection in the route list manager */
2357 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2361 /* try to cause everyone to drop their references */
2363 route->drop_references ();
2365 sync_order_keys (N_("session"));
2367 /* save the new state of the world */
2369 if (save_state (_current_snapshot_name)) {
2370 save_history (_current_snapshot_name);
2375 Session::route_mute_changed (void* /*src*/)
2381 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2383 boost::shared_ptr<Route> route = wpr.lock();
2385 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2389 if (route->listening()) {
2391 } else if (_listen_cnt > 0) {
2397 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2399 if (solo_update_disabled) {
2404 boost::shared_ptr<Route> route = wpr.lock ();
2407 /* should not happen */
2408 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2412 shared_ptr<RouteList> r = routes.reader ();
2415 if (route->soloed()) {
2421 /* now mod the solo level of all other routes except master & control outs
2422 so that they will be silent if appropriate.
2425 solo_update_disabled = true;
2426 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2428 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2430 (*i)->mod_solo_level (delta);
2434 /* make sure master is never muted by solo */
2436 if (_master_out && route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2437 _master_out->mod_solo_level (1);
2440 /* ditto for control outs make sure master is never muted by solo */
2442 if (_control_out && route != _control_out && _control_out && _control_out->solo_level() == 0) {
2443 _control_out->mod_solo_level (1);
2446 solo_update_disabled = false;
2447 update_route_solo_state (r);
2448 SoloChanged (); /* EMIT SIGNAL */
2453 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2455 /* now figure out if anything that matters is soloed */
2457 bool something_soloed = false;
2460 r = routes.reader();
2463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2464 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2465 something_soloed = true;
2470 if (something_soloed != _non_soloed_outs_muted) {
2471 _non_soloed_outs_muted = something_soloed;
2472 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2477 Session::route_by_name (string name)
2479 shared_ptr<RouteList> r = routes.reader ();
2481 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2482 if ((*i)->name() == name) {
2487 return shared_ptr<Route> ((Route*) 0);
2491 Session::route_by_id (PBD::ID id)
2493 shared_ptr<RouteList> r = routes.reader ();
2495 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2496 if ((*i)->id() == id) {
2501 return shared_ptr<Route> ((Route*) 0);
2505 Session::route_by_remote_id (uint32_t id)
2507 shared_ptr<RouteList> r = routes.reader ();
2509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2510 if ((*i)->remote_control_id() == id) {
2515 return shared_ptr<Route> ((Route*) 0);
2519 Session::find_current_end ()
2521 if (_state_of_the_state & Loading) {
2525 nframes_t max = get_maximum_extent ();
2527 if (max > end_location->end()) {
2528 end_location->set_end (max);
2530 DurationChanged(); /* EMIT SIGNAL */
2535 Session::get_maximum_extent () const
2540 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2542 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2543 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2545 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2546 if ((me = pl->get_maximum_extent()) > max) {
2554 boost::shared_ptr<Diskstream>
2555 Session::diskstream_by_name (string name)
2557 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2559 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2560 if ((*i)->name() == name) {
2565 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2568 boost::shared_ptr<Diskstream>
2569 Session::diskstream_by_id (const PBD::ID& id)
2571 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2573 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2574 if ((*i)->id() == id) {
2579 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2582 /* Region management */
2585 Session::new_region_name (string old)
2587 string::size_type last_period;
2589 string::size_type len = old.length() + 64;
2592 if ((last_period = old.find_last_of ('.')) == string::npos) {
2594 /* no period present - add one explicitly */
2597 last_period = old.length() - 1;
2602 number = atoi (old.substr (last_period+1).c_str());
2606 while (number < (UINT_MAX-1)) {
2608 RegionList::const_iterator i;
2613 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2616 for (i = regions.begin(); i != regions.end(); ++i) {
2617 if (i->second->name() == sbuf) {
2622 if (i == regions.end()) {
2627 if (number != (UINT_MAX-1)) {
2631 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2636 Session::region_name (string& result, string base, bool newlevel)
2641 if (base.find("/") != string::npos) {
2642 base = base.substr(base.find_last_of("/") + 1);
2647 Glib::Mutex::Lock lm (region_lock);
2649 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2658 string::size_type pos;
2660 pos = base.find_last_of ('.');
2662 /* pos may be npos, but then we just use entire base */
2664 subbase = base.substr (0, pos);
2669 Glib::Mutex::Lock lm (region_lock);
2671 map<string,uint32_t>::iterator x;
2675 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2677 region_name_map[subbase] = 1;
2680 snprintf (buf, sizeof (buf), ".%d", x->second);
2691 Session::add_region (boost::shared_ptr<Region> region)
2693 vector<boost::shared_ptr<Region> > v;
2694 v.push_back (region);
2699 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2704 Glib::Mutex::Lock lm (region_lock);
2706 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2708 boost::shared_ptr<Region> region = *ii;
2712 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2716 RegionList::iterator x;
2718 for (x = regions.begin(); x != regions.end(); ++x) {
2720 if (region->region_list_equivalent (x->second)) {
2725 if (x == regions.end()) {
2727 pair<RegionList::key_type,RegionList::mapped_type> entry;
2729 entry.first = region->id();
2730 entry.second = region;
2732 pair<RegionList::iterator,bool> x = regions.insert (entry);
2744 /* mark dirty because something has changed even if we didn't
2745 add the region to the region list.
2752 vector<boost::weak_ptr<Region> > v;
2753 boost::shared_ptr<Region> first_r;
2755 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2757 boost::shared_ptr<Region> region = *ii;
2761 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2764 v.push_back (region);
2771 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2772 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2774 update_region_name_map (region);
2778 RegionsAdded (v); /* EMIT SIGNAL */
2784 Session::update_region_name_map (boost::shared_ptr<Region> region)
2786 string::size_type last_period = region->name().find_last_of ('.');
2788 if (last_period != string::npos && last_period < region->name().length() - 1) {
2790 string base = region->name().substr (0, last_period);
2791 string number = region->name().substr (last_period+1);
2792 map<string,uint32_t>::iterator x;
2794 /* note that if there is no number, we get zero from atoi,
2798 region_name_map[base] = atoi (number);
2803 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2805 boost::shared_ptr<Region> region (weak_region.lock ());
2811 if (what_changed & Region::HiddenChanged) {
2812 /* relay hidden changes */
2813 RegionHiddenChange (region);
2816 if (what_changed & NameChanged) {
2817 update_region_name_map (region);
2822 Session::remove_region (boost::weak_ptr<Region> weak_region)
2824 RegionList::iterator i;
2825 boost::shared_ptr<Region> region (weak_region.lock ());
2831 bool removed = false;
2834 Glib::Mutex::Lock lm (region_lock);
2836 if ((i = regions.find (region->id())) != regions.end()) {
2842 /* mark dirty because something has changed even if we didn't
2843 remove the region from the region list.
2849 RegionRemoved(region); /* EMIT SIGNAL */
2853 boost::shared_ptr<Region>
2854 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2856 RegionList::iterator i;
2857 boost::shared_ptr<Region> region;
2859 Glib::Mutex::Lock lm (region_lock);
2861 for (i = regions.begin(); i != regions.end(); ++i) {
2865 if (region->whole_file()) {
2867 if (child->source_equivalent (region)) {
2873 return boost::shared_ptr<Region> ();
2877 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2879 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2880 (*i)->get_region_list_equivalent_regions (region, result);
2884 Session::destroy_region (boost::shared_ptr<Region> region)
2886 vector<boost::shared_ptr<Source> > srcs;
2889 if (region->playlist()) {
2890 region->playlist()->destroy_region (region);
2893 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2894 srcs.push_back (region->source (n));
2898 region->drop_references ();
2900 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2902 (*i)->mark_for_remove ();
2903 (*i)->drop_references ();
2905 cerr << "source was not used by any playlist\n";
2912 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2914 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2915 destroy_region (*i);
2921 Session::remove_last_capture ()
2923 list<boost::shared_ptr<Region> > r;
2925 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2927 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2928 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2931 r.insert (r.end(), l.begin(), l.end());
2936 destroy_regions (r);
2938 save_state (_current_snapshot_name);
2944 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2950 /* Source Management */
2953 Session::add_source (boost::shared_ptr<Source> source)
2955 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2956 pair<SourceMap::iterator,bool> result;
2958 entry.first = source->id();
2959 entry.second = source;
2962 Glib::Mutex::Lock lm (source_lock);
2963 result = sources.insert (entry);
2966 if (result.second) {
2967 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2971 boost::shared_ptr<AudioFileSource> afs;
2973 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2974 if (Config->get_auto_analyse_audio()) {
2975 Analyser::queue_source_for_analysis (source, false);
2981 Session::remove_source (boost::weak_ptr<Source> src)
2983 SourceMap::iterator i;
2984 boost::shared_ptr<Source> source = src.lock();
2991 Glib::Mutex::Lock lm (source_lock);
2993 if ((i = sources.find (source->id())) != sources.end()) {
2998 if (!_state_of_the_state & InCleanup) {
3000 /* save state so we don't end up with a session file
3001 referring to non-existent sources.
3004 save_state (_current_snapshot_name);
3008 /** Return the number of playlists (not regions) that contain @a src */
3010 Session::source_use_count (boost::shared_ptr<const Source> src) const
3013 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3014 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3015 r != (*p)->region_list().end(); ++r) {
3016 if ((*r)->uses_source(src)) {
3025 boost::shared_ptr<Source>
3026 Session::source_by_id (const PBD::ID& id)
3028 Glib::Mutex::Lock lm (source_lock);
3029 SourceMap::iterator i;
3030 boost::shared_ptr<Source> source;
3032 if ((i = sources.find (id)) != sources.end()) {
3039 boost::shared_ptr<Source>
3040 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3042 Glib::Mutex::Lock lm (source_lock);
3044 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3045 cerr << "comparing " << path << " with " << i->second->name() << endl;
3046 boost::shared_ptr<AudioFileSource> afs
3047 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3049 if (afs && afs->path() == path && chn == afs->channel()) {
3053 return boost::shared_ptr<Source>();
3058 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3061 string old_basename = PBD::basename_nosuffix (oldname);
3062 string new_legalized = legalize_for_path (newname);
3064 /* note: we know (or assume) the old path is already valid */
3068 /* destructive file sources have a name of the form:
3070 /path/to/Tnnnn-NAME(%[LR])?.wav
3072 the task here is to replace NAME with the new name.
3075 /* find last slash */
3079 string::size_type slash;
3080 string::size_type dash;
3082 if ((slash = path.find_last_of ('/')) == string::npos) {
3086 dir = path.substr (0, slash+1);
3088 /* '-' is not a legal character for the NAME part of the path */
3090 if ((dash = path.find_last_of ('-')) == string::npos) {
3094 prefix = path.substr (slash+1, dash-(slash+1));
3099 path += new_legalized;
3100 path += ".wav"; /* XXX gag me with a spoon */
3104 /* non-destructive file sources have a name of the form:
3106 /path/to/NAME-nnnnn(%[LR])?.ext
3108 the task here is to replace NAME with the new name.
3113 string::size_type slash;
3114 string::size_type dash;
3115 string::size_type postfix;
3117 /* find last slash */
3119 if ((slash = path.find_last_of ('/')) == string::npos) {
3123 dir = path.substr (0, slash+1);
3125 /* '-' is not a legal character for the NAME part of the path */
3127 if ((dash = path.find_last_of ('-')) == string::npos) {
3131 suffix = path.substr (dash+1);
3133 // Suffix is now everything after the dash. Now we need to eliminate
3134 // the nnnnn part, which is done by either finding a '%' or a '.'
3136 postfix = suffix.find_last_of ("%");
3137 if (postfix == string::npos) {
3138 postfix = suffix.find_last_of ('.');
3141 if (postfix != string::npos) {
3142 suffix = suffix.substr (postfix);
3144 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3148 const uint32_t limit = 10000;
3149 char buf[PATH_MAX+1];
3151 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3153 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3155 if (access (buf, F_OK) != 0) {
3163 error << "FATAL ERROR! Could not find a " << endl;
3171 /** Return the full path (in some session directory) for a new embedded source.
3172 * \a name must be a session-unique name that does not contain slashes
3173 * (e.g. as returned by new_*_source_name)
3176 Session::new_source_path_from_name (DataType type, const string& name)
3178 assert(name.find("/") == string::npos);
3180 SessionDirectory sdir(get_best_session_directory_for_new_source());
3183 if (type == DataType::AUDIO) {
3184 p = sdir.sound_path();
3185 } else if (type == DataType::MIDI) {
3186 p = sdir.midi_path();
3188 error << "Unknown source type, unable to create file path" << endmsg;
3193 return p.to_string();
3197 Session::peak_path (Glib::ustring base) const
3199 sys::path peakfile_path(_session_dir->peak_path());
3200 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3201 return peakfile_path.to_string();
3204 /** Return a unique name based on \a base for a new internal audio source */
3206 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3210 char buf[PATH_MAX+1];
3211 const uint32_t limit = 10000;
3215 legalized = legalize_for_path (base);
3217 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3218 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3220 vector<space_and_path>::iterator i;
3221 uint32_t existing = 0;
3223 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3225 SessionDirectory sdir((*i).path);
3227 spath = sdir.sound_path().to_string();
3232 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3233 spath.c_str(), cnt, legalized.c_str());
3234 } else if (nchan == 2) {
3236 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3237 spath.c_str(), cnt, legalized.c_str());
3239 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3240 spath.c_str(), cnt, legalized.c_str());
3242 } else if (nchan < 26) {
3243 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3244 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3246 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3247 spath.c_str(), cnt, legalized.c_str());
3256 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3257 } else if (nchan == 2) {
3259 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3261 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3263 } else if (nchan < 26) {
3264 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3266 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3270 if (sys::exists(buf)) {
3276 if (existing == 0) {
3281 error << string_compose(
3282 _("There are already %1 recordings for %2, which I consider too many."),
3283 limit, base) << endmsg;
3285 throw failed_constructor();
3289 return Glib::path_get_basename(buf);
3292 /** Create a new embedded audio source */
3293 boost::shared_ptr<AudioFileSource>
3294 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3296 const size_t n_chans = ds.n_channels().n_audio();
3297 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3298 const string path = new_source_path_from_name(DataType::AUDIO, name);
3299 return boost::dynamic_pointer_cast<AudioFileSource> (
3300 SourceFactory::createWritable (
3301 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3304 /** Return a unique name based on \a base for a new internal MIDI source */
3306 Session::new_midi_source_name (const string& base)
3309 char buf[PATH_MAX+1];
3310 const uint32_t limit = 10000;
3314 legalized = legalize_for_path (base);
3316 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3317 for (cnt = 1; cnt <= limit; ++cnt) {
3319 vector<space_and_path>::iterator i;
3320 uint32_t existing = 0;
3322 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3324 SessionDirectory sdir((*i).path);
3326 sys::path p = sdir.midi_path();
3329 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3331 if (sys::exists (buf)) {
3336 if (existing == 0) {
3341 error << string_compose(
3342 _("There are already %1 recordings for %2, which I consider too many."),
3343 limit, base) << endmsg;
3345 throw failed_constructor();
3349 return Glib::path_get_basename(buf);
3353 /** Create a new embedded MIDI source */
3354 boost::shared_ptr<MidiSource>
3355 Session::create_midi_source_for_session (MidiDiskstream& ds)
3357 const string name = new_midi_source_name (ds.name());
3358 const string path = new_source_path_from_name (DataType::MIDI, name);
3360 return boost::dynamic_pointer_cast<SMFSource> (
3361 SourceFactory::createWritable (
3362 DataType::MIDI, *this, path, true, false, frame_rate()));
3366 /* Playlist management */
3368 boost::shared_ptr<Playlist>
3369 Session::playlist_by_name (string name)
3371 Glib::Mutex::Lock lm (playlist_lock);
3372 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3373 if ((*i)->name() == name) {
3377 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3378 if ((*i)->name() == name) {
3383 return boost::shared_ptr<Playlist>();
3387 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3389 Glib::Mutex::Lock lm (playlist_lock);
3390 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3391 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3392 list.push_back (*i);
3395 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3396 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3397 list.push_back (*i);
3403 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3405 if (playlist->hidden()) {
3410 Glib::Mutex::Lock lm (playlist_lock);
3411 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3412 playlists.insert (playlists.begin(), playlist);
3413 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3414 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3419 playlist->release();
3424 PlaylistAdded (playlist); /* EMIT SIGNAL */
3428 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3431 Glib::Mutex::Lock lm (playlist_lock);
3432 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3435 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3442 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3444 boost::shared_ptr<Playlist> pl(wpl.lock());
3450 PlaylistList::iterator x;
3453 /* its not supposed to be visible */
3458 Glib::Mutex::Lock lm (playlist_lock);
3462 unused_playlists.insert (pl);
3464 if ((x = playlists.find (pl)) != playlists.end()) {
3465 playlists.erase (x);
3471 playlists.insert (pl);
3473 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3474 unused_playlists.erase (x);
3481 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3483 if (_state_of_the_state & Deletion) {
3487 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3494 Glib::Mutex::Lock lm (playlist_lock);
3496 PlaylistList::iterator i;
3498 i = find (playlists.begin(), playlists.end(), playlist);
3499 if (i != playlists.end()) {
3500 playlists.erase (i);
3503 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3504 if (i != unused_playlists.end()) {
3505 unused_playlists.erase (i);
3512 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3516 Session::set_audition (boost::shared_ptr<Region> r)
3518 pending_audition_region = r;
3519 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3520 _butler->schedule_transport_work ();
3524 Session::audition_playlist ()
3526 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3527 ev->region.reset ();
3532 Session::non_realtime_set_audition ()
3534 if (!pending_audition_region) {
3535 auditioner->audition_current_playlist ();
3537 auditioner->audition_region (pending_audition_region);
3538 pending_audition_region.reset ();
3540 AuditionActive (true); /* EMIT SIGNAL */
3544 Session::audition_region (boost::shared_ptr<Region> r)
3546 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3552 Session::cancel_audition ()
3554 if (auditioner->active()) {
3555 auditioner->cancel_audition ();
3556 AuditionActive (false); /* EMIT SIGNAL */
3561 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3563 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3567 Session::remove_empty_sounds ()
3569 vector<string> audio_filenames;
3571 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3573 Glib::Mutex::Lock lm (source_lock);
3575 TapeFileMatcher tape_file_matcher;
3577 remove_if (audio_filenames.begin(), audio_filenames.end(),
3578 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3580 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3582 sys::path audio_file_path (_session_dir->sound_path());
3584 audio_file_path /= *i;
3586 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3590 sys::remove (audio_file_path);
3591 const string peakfile = peak_path (audio_file_path.to_string());
3592 sys::remove (peakfile);
3594 catch (const sys::filesystem_error& err)
3596 error << err.what() << endmsg;
3603 Session::is_auditioning () const
3605 /* can be called before we have an auditioner object */
3607 return auditioner->active();
3614 Session::set_all_solo (bool yn)
3616 shared_ptr<RouteList> r = routes.reader ();
3618 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3619 if (!(*i)->is_hidden()) {
3620 (*i)->set_solo (yn, this);
3628 Session::set_all_listen (bool yn)
3630 shared_ptr<RouteList> r = routes.reader ();
3632 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3633 if (!(*i)->is_hidden()) {
3634 (*i)->set_listen (yn, this);
3642 Session::set_all_mute (bool yn)
3644 shared_ptr<RouteList> r = routes.reader ();
3646 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3647 if (!(*i)->is_hidden()) {
3648 (*i)->set_mute (yn, this);
3656 Session::n_diskstreams () const
3660 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3662 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3663 if (!(*i)->hidden()) {
3671 Session::graph_reordered ()
3673 /* don't do this stuff if we are setting up connections
3674 from a set_state() call or creating new tracks.
3677 if (_state_of_the_state & InitialConnecting) {
3681 /* every track/bus asked for this to be handled but it was deferred because
3682 we were connecting. do it now.
3685 request_input_change_handling ();
3689 /* force all diskstreams to update their capture offset values to
3690 reflect any changes in latencies within the graph.
3693 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3695 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3696 (*i)->set_capture_offset ();
3701 Session::record_disenable_all ()
3703 record_enable_change_all (false);
3707 Session::record_enable_all ()
3709 record_enable_change_all (true);
3713 Session::record_enable_change_all (bool yn)
3715 shared_ptr<RouteList> r = routes.reader ();
3717 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3718 boost::shared_ptr<Track> t;
3720 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3721 t->set_record_enable (yn, this);
3725 /* since we don't keep rec-enable state, don't mark session dirty */
3729 Session::add_processor (Processor* processor)
3731 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3736 Session::remove_processor (Processor* processor)
3740 PortInsert* port_insert;
3742 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3743 insert_bitset[port_insert->bit_slot()] = false;
3744 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3745 send_bitset[send->bit_slot()] = false;
3746 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3747 return_bitset[send->bit_slot()] = false;
3754 Session::available_capture_duration ()
3756 float sample_bytes_on_disk = 4.0; // keep gcc happy
3758 switch (config.get_native_file_data_format()) {
3760 sample_bytes_on_disk = 4.0;
3764 sample_bytes_on_disk = 3.0;
3768 sample_bytes_on_disk = 2.0;
3772 /* impossible, but keep some gcc versions happy */
3773 fatal << string_compose (_("programming error: %1"),
3774 X_("illegal native file data format"))
3779 double scale = 4096.0 / sample_bytes_on_disk;
3781 if (_total_free_4k_blocks * scale > (double) max_frames) {
3785 return (nframes_t) floor (_total_free_4k_blocks * scale);
3789 Session::add_bundle (shared_ptr<Bundle> bundle)
3792 RCUWriter<BundleList> writer (_bundles);
3793 boost::shared_ptr<BundleList> b = writer.get_copy ();
3794 b->push_back (bundle);
3797 BundleAdded (bundle); /* EMIT SIGNAL */
3803 Session::remove_bundle (shared_ptr<Bundle> bundle)
3805 bool removed = false;
3808 RCUWriter<BundleList> writer (_bundles);
3809 boost::shared_ptr<BundleList> b = writer.get_copy ();
3810 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3812 if (i != b->end()) {
3819 BundleRemoved (bundle); /* EMIT SIGNAL */
3826 Session::bundle_by_name (string name) const
3828 boost::shared_ptr<BundleList> b = _bundles.reader ();
3830 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3831 if ((*i)->name() == name) {
3836 return boost::shared_ptr<Bundle> ();
3840 Session::tempo_map_changed (Change)
3844 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3845 (*i)->update_after_tempo_map_change ();
3848 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3849 (*i)->update_after_tempo_map_change ();
3855 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3856 * the given count with the current block size.
3859 Session::ensure_buffers (ChanCount howmany)
3861 if (current_block_size == 0) {
3862 return; // too early? (is this ok?)
3865 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3866 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3867 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3868 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3869 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3872 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3876 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3878 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3879 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3884 Session::next_insert_id ()
3886 /* this doesn't really loop forever. just think about it */
3889 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3890 if (!insert_bitset[n]) {
3891 insert_bitset[n] = true;
3897 /* none available, so resize and try again */
3899 insert_bitset.resize (insert_bitset.size() + 16, false);
3904 Session::next_send_id ()
3906 /* this doesn't really loop forever. just think about it */
3909 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3910 if (!send_bitset[n]) {
3911 send_bitset[n] = true;
3917 /* none available, so resize and try again */
3919 send_bitset.resize (send_bitset.size() + 16, false);
3924 Session::next_return_id ()
3926 /* this doesn't really loop forever. just think about it */
3929 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3930 if (!return_bitset[n]) {
3931 return_bitset[n] = true;
3937 /* none available, so resize and try again */
3939 return_bitset.resize (return_bitset.size() + 16, false);
3944 Session::mark_send_id (uint32_t id)
3946 if (id >= send_bitset.size()) {
3947 send_bitset.resize (id+16, false);
3949 if (send_bitset[id]) {
3950 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3952 send_bitset[id] = true;
3956 Session::mark_return_id (uint32_t id)
3958 if (id >= return_bitset.size()) {
3959 return_bitset.resize (id+16, false);
3961 if (return_bitset[id]) {
3962 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3964 return_bitset[id] = true;
3968 Session::mark_insert_id (uint32_t id)
3970 if (id >= insert_bitset.size()) {
3971 insert_bitset.resize (id+16, false);
3973 if (insert_bitset[id]) {
3974 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3976 insert_bitset[id] = true;
3979 /* Named Selection management */
3982 Session::named_selection_by_name (string name)
3984 Glib::Mutex::Lock lm (named_selection_lock);
3985 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3986 if ((*i)->name == name) {
3994 Session::add_named_selection (NamedSelection* named_selection)
3997 Glib::Mutex::Lock lm (named_selection_lock);
3998 named_selections.insert (named_selections.begin(), named_selection);
4001 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4007 NamedSelectionAdded (); /* EMIT SIGNAL */
4011 Session::remove_named_selection (NamedSelection* named_selection)
4013 bool removed = false;
4016 Glib::Mutex::Lock lm (named_selection_lock);
4018 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4020 if (i != named_selections.end()) {
4022 named_selections.erase (i);
4029 NamedSelectionRemoved (); /* EMIT SIGNAL */
4034 Session::reset_native_file_format ()
4036 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4038 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4039 (*i)->reset_write_sources (false);
4044 Session::route_name_unique (string n) const
4046 shared_ptr<RouteList> r = routes.reader ();
4048 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4049 if ((*i)->name() == n) {
4058 Session::route_name_internal (string n) const
4060 if (auditioner && auditioner->name() == n) {
4064 if (_click_io && _click_io->name() == n) {
4072 Session::n_playlists () const
4074 Glib::Mutex::Lock lm (playlist_lock);
4075 return playlists.size();
4079 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4081 if (!force && howmany <= _npan_buffers) {
4085 if (_pan_automation_buffer) {
4087 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4088 delete [] _pan_automation_buffer[i];
4091 delete [] _pan_automation_buffer;
4094 _pan_automation_buffer = new pan_t*[howmany];
4096 for (uint32_t i = 0; i < howmany; ++i) {
4097 _pan_automation_buffer[i] = new pan_t[nframes];
4100 _npan_buffers = howmany;
4104 Session::freeze (InterThreadInfo& itt)
4106 shared_ptr<RouteList> r = routes.reader ();
4108 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4110 boost::shared_ptr<Track> t;
4112 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4113 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4123 boost::shared_ptr<Region>
4124 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4125 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4126 InterThreadInfo& itt, bool enable_processing)
4128 boost::shared_ptr<Region> result;
4129 boost::shared_ptr<Playlist> playlist;
4130 boost::shared_ptr<AudioFileSource> fsource;
4132 char buf[PATH_MAX+1];
4133 ChanCount nchans(track.audio_diskstream()->n_channels());
4135 nframes_t this_chunk;
4138 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4139 const string sound_dir = sdir.sound_path().to_string();
4140 nframes_t len = end - start;
4143 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4144 end, start) << endmsg;
4148 // any bigger than this seems to cause stack overflows in called functions
4149 const nframes_t chunk_size = (128 * 1024)/4;
4151 // block all process callback handling
4153 block_processing ();
4155 /* call tree *MUST* hold route_lock */
4157 if ((playlist = track.diskstream()->playlist()) == 0) {
4161 /* external redirects will be a problem */
4163 if (track.has_external_redirects()) {
4167 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4169 for (x = 0; x < 99999; ++x) {
4170 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4171 if (access (buf, F_OK) != 0) {
4177 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4182 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4183 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4186 catch (failed_constructor& err) {
4187 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4191 srcs.push_back (fsource);
4194 /* XXX need to flush all redirects */
4199 /* create a set of reasonably-sized buffers */
4200 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4201 buffers.set_count(nchans);
4203 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4204 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4206 afs->prepare_for_peakfile_writes ();
4209 while (to_do && !itt.cancel) {
4211 this_chunk = min (to_do, chunk_size);
4213 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4218 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4219 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4222 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4228 start += this_chunk;
4229 to_do -= this_chunk;
4231 itt.progress = (float) (1.0 - ((double) to_do / len));
4240 xnow = localtime (&now);
4242 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4243 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4246 afs->update_header (position, *xnow, now);
4247 afs->flush_header ();
4251 /* construct a region to represent the bounced material */
4253 result = RegionFactory::create (srcs, 0,
4254 srcs.front()->length(srcs.front()->timeline_position()),
4255 region_name_from_path (srcs.front()->name(), true));
4260 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4261 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4264 afs->mark_for_remove ();
4267 (*src)->drop_references ();
4271 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4272 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4275 afs->done_with_peakfile_writes ();
4279 unblock_processing ();
4285 Session::get_silent_buffers (ChanCount count)
4287 assert(_silent_buffers->available() >= count);
4288 _silent_buffers->set_count(count);
4290 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4291 for (size_t i= 0; i < count.get(*t); ++i) {
4292 _silent_buffers->get(*t, i).clear();
4296 return *_silent_buffers;
4300 Session::get_scratch_buffers (ChanCount count)
4302 if (count != ChanCount::ZERO) {
4303 assert(_scratch_buffers->available() >= count);
4304 _scratch_buffers->set_count(count);
4306 _scratch_buffers->set_count (_scratch_buffers->available());
4309 return *_scratch_buffers;
4313 Session::get_mix_buffers (ChanCount count)
4315 assert(_mix_buffers->available() >= count);
4316 _mix_buffers->set_count(count);
4317 return *_mix_buffers;
4321 Session::ntracks () const
4324 shared_ptr<RouteList> r = routes.reader ();
4326 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4327 if (boost::dynamic_pointer_cast<Track> (*i)) {
4336 Session::nbusses () const
4339 shared_ptr<RouteList> r = routes.reader ();
4341 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4342 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4351 Session::add_automation_list(AutomationList *al)
4353 automation_lists[al->id()] = al;
4357 Session::compute_initial_length ()
4359 return _engine.frame_rate() * 60 * 5;
4363 Session::sync_order_keys (std::string const & base)
4365 if (!Config->get_sync_all_route_ordering()) {
4366 /* leave order keys as they are */
4370 boost::shared_ptr<RouteList> r = routes.reader ();
4372 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4373 (*i)->sync_order_keys (base);
4376 Route::SyncOrderKeys (base); // EMIT SIGNAL
4380 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4382 Session::have_rec_enabled_diskstream () const
4384 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4387 /** Update the state of our rec-enabled diskstreams flag */
4389 Session::update_have_rec_enabled_diskstream ()
4391 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4392 DiskstreamList::iterator i = dsl->begin ();
4393 while (i != dsl->end () && (*i)->record_enabled () == false) {
4397 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4399 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4401 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4402 RecordStateChanged (); /* EMIT SIGNAL */
4407 Session::listen_position_changed ()
4411 switch (Config->get_listen_position()) {
4412 case AfterFaderListen:
4416 case PreFaderListen:
4421 boost::shared_ptr<RouteList> r = routes.reader ();
4423 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4424 (*i)->put_control_outs_at (p);
4429 Session::solo_control_mode_changed ()
4431 /* cancel all solo or all listen when solo control mode changes */
4433 if (Config->get_solo_control_is_listen_control()) {
4434 set_all_solo (false);
4436 set_all_listen (false);
4441 Session::route_group_changed ()
4443 RouteGroupChanged (); /* EMIT SIGNAL */