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) {
962 // if (_transport_frame > location->end()) {
964 if (_transport_frame < location->start() || _transport_frame > location->end()) {
965 // relocate to beginning of loop
966 clear_events (Event::LocateRoll);
968 request_locate (location->start(), true);
971 else if (Config->get_seamless_loop() && !loop_changing) {
973 // schedule a locate-roll to refill the diskstreams at the
975 loop_changing = true;
977 if (location->end() > last_loopend) {
978 clear_events (Event::LocateRoll);
979 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
986 last_loopend = location->end();
990 Session::set_auto_punch_location (Location* location)
994 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
995 auto_punch_start_changed_connection.disconnect();
996 auto_punch_end_changed_connection.disconnect();
997 auto_punch_changed_connection.disconnect();
998 existing->set_auto_punch (false, this);
999 remove_event (existing->start(), Event::PunchIn);
1000 clear_events (Event::PunchOut);
1001 auto_punch_location_changed (0);
1006 if (location == 0) {
1010 if (location->end() <= location->start()) {
1011 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1015 auto_punch_start_changed_connection.disconnect();
1016 auto_punch_end_changed_connection.disconnect();
1017 auto_punch_changed_connection.disconnect();
1019 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1020 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1021 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1023 location->set_auto_punch (true, this);
1026 auto_punch_changed (location);
1028 auto_punch_location_changed (location);
1032 Session::set_auto_loop_location (Location* location)
1036 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1037 auto_loop_start_changed_connection.disconnect();
1038 auto_loop_end_changed_connection.disconnect();
1039 auto_loop_changed_connection.disconnect();
1040 existing->set_auto_loop (false, this);
1041 remove_event (existing->end(), Event::AutoLoop);
1042 auto_loop_location_changed (0);
1047 if (location == 0) {
1051 if (location->end() <= location->start()) {
1052 error << _("Session: you can't use a mark for auto loop") << endmsg;
1056 last_loopend = location->end();
1058 auto_loop_start_changed_connection.disconnect();
1059 auto_loop_end_changed_connection.disconnect();
1060 auto_loop_changed_connection.disconnect();
1062 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1063 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1064 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1066 location->set_auto_loop (true, this);
1068 /* take care of our stuff first */
1070 auto_loop_changed (location);
1072 /* now tell everyone else */
1074 auto_loop_location_changed (location);
1078 Session::locations_added (Location *)
1084 Session::locations_changed ()
1086 _locations.apply (*this, &Session::handle_locations_changed);
1090 Session::handle_locations_changed (Locations::LocationList& locations)
1092 Locations::LocationList::iterator i;
1094 bool set_loop = false;
1095 bool set_punch = false;
1097 for (i = locations.begin(); i != locations.end(); ++i) {
1101 if (location->is_auto_punch()) {
1102 set_auto_punch_location (location);
1105 if (location->is_auto_loop()) {
1106 set_auto_loop_location (location);
1110 if (location->is_start()) {
1111 start_location = location;
1113 if (location->is_end()) {
1114 end_location = location;
1119 set_auto_loop_location (0);
1122 set_auto_punch_location (0);
1129 Session::enable_record ()
1131 /* XXX really atomic compare+swap here */
1132 if (g_atomic_int_get (&_record_status) != Recording) {
1133 g_atomic_int_set (&_record_status, Recording);
1134 _last_record_location = _transport_frame;
1135 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1137 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1138 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1139 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1140 if ((*i)->record_enabled ()) {
1141 (*i)->monitor_input (true);
1146 RecordStateChanged ();
1151 Session::disable_record (bool rt_context, bool force)
1155 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1157 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1158 g_atomic_int_set (&_record_status, Disabled);
1160 if (rs == Recording) {
1161 g_atomic_int_set (&_record_status, Enabled);
1165 // FIXME: timestamp correct? [DR]
1166 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1167 // does this /need/ to be sent in all cases?
1169 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1171 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1172 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1174 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1175 if ((*i)->record_enabled ()) {
1176 (*i)->monitor_input (false);
1181 RecordStateChanged (); /* emit signal */
1184 remove_pending_capture_state ();
1190 Session::step_back_from_record ()
1192 /* XXX really atomic compare+swap here */
1193 if (g_atomic_int_get (&_record_status) == Recording) {
1194 g_atomic_int_set (&_record_status, Enabled);
1196 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1197 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1199 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1200 if ((*i)->record_enabled ()) {
1201 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1202 (*i)->monitor_input (false);
1210 Session::maybe_enable_record ()
1212 g_atomic_int_set (&_record_status, Enabled);
1214 /* this function is currently called from somewhere other than an RT thread.
1215 this save_state() call therefore doesn't impact anything.
1218 save_state ("", true);
1220 if (_transport_speed) {
1221 if (!config.get_punch_in()) {
1225 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1226 RecordStateChanged (); /* EMIT SIGNAL */
1233 Session::audible_frame () const
1239 /* the first of these two possible settings for "offset"
1240 mean that the audible frame is stationary until
1241 audio emerges from the latency compensation
1244 the second means that the audible frame is stationary
1245 until audio would emerge from a physical port
1246 in the absence of any plugin latency compensation
1249 offset = _worst_output_latency;
1251 if (offset > current_block_size) {
1252 offset -= current_block_size;
1254 /* XXX is this correct? if we have no external
1255 physical connections and everything is internal
1256 then surely this is zero? still, how
1257 likely is that anyway?
1259 offset = current_block_size;
1262 if (synced_to_jack()) {
1263 tf = _engine.transport_frame();
1265 tf = _transport_frame;
1270 if (!non_realtime_work_pending()) {
1274 /* check to see if we have passed the first guaranteed
1275 audible frame past our last start position. if not,
1276 return that last start point because in terms
1277 of audible frames, we have not moved yet.
1280 if (_transport_speed > 0.0f) {
1282 if (!play_loop || !have_looped) {
1283 if (tf < _last_roll_location + offset) {
1284 return _last_roll_location;
1292 } else if (_transport_speed < 0.0f) {
1294 /* XXX wot? no backward looping? */
1296 if (tf > _last_roll_location - offset) {
1297 return _last_roll_location;
1309 Session::set_frame_rate (nframes_t frames_per_second)
1311 /** \fn void Session::set_frame_size(nframes_t)
1312 the AudioEngine object that calls this guarantees
1313 that it will not be called while we are also in
1314 ::process(). Its fine to do things that block
1318 _base_frame_rate = frames_per_second;
1322 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1326 // XXX we need some equivalent to this, somehow
1327 // SndFileSource::setup_standard_crossfades (frames_per_second);
1331 /* XXX need to reset/reinstantiate all LADSPA plugins */
1335 Session::set_block_size (nframes_t nframes)
1337 /* the AudioEngine guarantees
1338 that it will not be called while we are also in
1339 ::process(). It is therefore fine to do things that block
1344 current_block_size = nframes;
1346 ensure_buffers(_scratch_buffers->available());
1348 delete [] _gain_automation_buffer;
1349 _gain_automation_buffer = new gain_t[nframes];
1351 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1353 boost::shared_ptr<RouteList> r = routes.reader ();
1355 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1356 (*i)->set_block_size (nframes);
1359 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1360 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1361 (*i)->set_block_size (nframes);
1364 set_worst_io_latencies ();
1369 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1372 nframes_t fade_frames;
1374 /* Don't allow fade of less 1 frame */
1376 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1383 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1387 default_fade_msecs = fade_msecs;
1388 default_fade_steepness = steepness;
1391 // jlc, WTF is this!
1392 Glib::RWLock::ReaderLock lm (route_lock);
1393 AudioRegion::set_default_fade (steepness, fade_frames);
1398 /* XXX have to do this at some point */
1399 /* foreach region using default fade, reset, then
1400 refill_all_diskstream_buffers ();
1405 struct RouteSorter {
1406 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1407 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1409 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1412 if (r1->fed_by.empty()) {
1413 if (r2->fed_by.empty()) {
1414 /* no ardour-based connections inbound to either route. just use signal order */
1415 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1417 /* r2 has connections, r1 does not; run r1 early */
1421 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1428 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1430 shared_ptr<Route> r2;
1432 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1433 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1437 /* make a copy of the existing list of routes that feed r1 */
1439 set<shared_ptr<Route> > existing = r1->fed_by;
1441 /* for each route that feeds r1, recurse, marking it as feeding
1445 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1448 /* r2 is a route that feeds r1 which somehow feeds base. mark
1449 base as being fed by r2
1452 rbase->fed_by.insert (r2);
1456 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1460 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1464 /* now recurse, so that we can mark base as being fed by
1465 all routes that feed r2
1468 trace_terminal (r2, rbase);
1475 Session::resort_routes ()
1477 /* don't do anything here with signals emitted
1478 by Routes while we are being destroyed.
1481 if (_state_of_the_state & Deletion) {
1488 RCUWriter<RouteList> writer (routes);
1489 shared_ptr<RouteList> r = writer.get_copy ();
1490 resort_routes_using (r);
1491 /* writer goes out of scope and forces update */
1496 Session::resort_routes_using (shared_ptr<RouteList> r)
1498 RouteList::iterator i, j;
1500 for (i = r->begin(); i != r->end(); ++i) {
1502 (*i)->fed_by.clear ();
1504 for (j = r->begin(); j != r->end(); ++j) {
1506 /* although routes can feed themselves, it will
1507 cause an endless recursive descent if we
1508 detect it. so don't bother checking for
1516 if ((*j)->feeds (*i)) {
1517 (*i)->fed_by.insert (*j);
1522 for (i = r->begin(); i != r->end(); ++i) {
1523 trace_terminal (*i, *i);
1530 cerr << "finished route resort\n";
1532 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1533 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1540 list<boost::shared_ptr<MidiTrack> >
1541 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1543 char track_name[32];
1544 uint32_t track_id = 0;
1547 RouteList new_routes;
1548 list<boost::shared_ptr<MidiTrack> > ret;
1549 //uint32_t control_id;
1551 // FIXME: need physical I/O and autoconnect stuff for MIDI
1553 /* count existing midi tracks */
1556 shared_ptr<RouteList> r = routes.reader ();
1558 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1559 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1560 if (!(*i)->is_hidden()) {
1562 //channels_used += (*i)->n_inputs().n_midi();
1568 vector<string> physinputs;
1569 vector<string> physoutputs;
1571 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1572 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1574 // control_id = ntracks() + nbusses();
1578 /* check for duplicate route names, since we might have pre-existing
1579 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1580 save, close,restart,add new route - first named route is now
1588 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1590 if (route_by_name (track_name) == 0) {
1594 } while (track_id < (UINT_MAX-1));
1596 shared_ptr<MidiTrack> track;
1599 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1601 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1602 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1607 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1608 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1614 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1618 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1619 port = physinputs[(channels_used+x)%nphysical_in];
1622 if (port.length() && track->connect_input (track->input (x), port, this)) {
1628 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1632 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1633 port = physoutputs[(channels_used+x)%nphysical_out];
1634 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1636 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1640 if (port.length() && track->connect_output (track->output (x), port, this)) {
1645 channels_used += track->n_inputs ().n_midi();
1649 track->midi_diskstream()->non_realtime_input_change();
1650 track->set_route_group (route_group, 0);
1652 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1653 //track->set_remote_control_id (control_id);
1655 new_routes.push_back (track);
1656 ret.push_back (track);
1659 catch (failed_constructor &err) {
1660 error << _("Session: could not create new midi track.") << endmsg;
1663 /* we need to get rid of this, since the track failed to be created */
1664 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1667 RCUWriter<DiskstreamList> writer (diskstreams);
1668 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1669 ds->remove (track->midi_diskstream());
1676 catch (AudioEngine::PortRegistrationFailure& pfe) {
1678 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;
1681 /* we need to get rid of this, since the track failed to be created */
1682 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1685 RCUWriter<DiskstreamList> writer (diskstreams);
1686 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1687 ds->remove (track->midi_diskstream());
1698 if (!new_routes.empty()) {
1699 add_routes (new_routes, false);
1700 save_state (_current_snapshot_name);
1706 list<boost::shared_ptr<AudioTrack> >
1707 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1709 char track_name[32];
1710 uint32_t track_id = 0;
1712 uint32_t channels_used = 0;
1714 RouteList new_routes;
1715 list<boost::shared_ptr<AudioTrack> > ret;
1716 uint32_t control_id;
1718 /* count existing audio tracks */
1721 shared_ptr<RouteList> r = routes.reader ();
1723 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1724 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1725 if (!(*i)->is_hidden()) {
1727 channels_used += (*i)->n_inputs().n_audio();
1733 vector<string> physinputs;
1734 vector<string> physoutputs;
1736 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1737 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1739 control_id = ntracks() + nbusses() + 1;
1743 /* check for duplicate route names, since we might have pre-existing
1744 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1745 save, close,restart,add new route - first named route is now
1753 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1755 if (route_by_name (track_name) == 0) {
1759 } while (track_id < (UINT_MAX-1));
1761 shared_ptr<AudioTrack> track;
1764 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1766 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1767 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1768 input_channels, output_channels)
1773 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1774 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1775 input_channels, output_channels)
1780 if (!physinputs.empty()) {
1781 uint32_t nphysical_in = physinputs.size();
1783 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1787 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1788 port = physinputs[(channels_used+x)%nphysical_in];
1791 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1797 if (!physoutputs.empty()) {
1798 uint32_t nphysical_out = physoutputs.size();
1800 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1803 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1804 port = physoutputs[(channels_used+x)%nphysical_out];
1805 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1806 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1807 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1811 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1817 channels_used += track->n_inputs ().n_audio();
1819 track->set_route_group (route_group, 0);
1821 track->audio_diskstream()->non_realtime_input_change();
1823 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1824 track->set_remote_control_id (control_id);
1827 new_routes.push_back (track);
1828 ret.push_back (track);
1831 catch (failed_constructor &err) {
1832 error << _("Session: could not create new audio track.") << endmsg;
1835 /* we need to get rid of this, since the track failed to be created */
1836 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1839 RCUWriter<DiskstreamList> writer (diskstreams);
1840 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1841 ds->remove (track->audio_diskstream());
1848 catch (AudioEngine::PortRegistrationFailure& pfe) {
1850 error << pfe.what() << endmsg;
1853 /* we need to get rid of this, since the track failed to be created */
1854 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1857 RCUWriter<DiskstreamList> writer (diskstreams);
1858 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1859 ds->remove (track->audio_diskstream());
1870 if (!new_routes.empty()) {
1871 add_routes (new_routes, true);
1878 Session::set_remote_control_ids ()
1880 RemoteModel m = Config->get_remote_model();
1882 shared_ptr<RouteList> r = routes.reader ();
1884 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1885 if ( MixerOrdered == m) {
1886 long order = (*i)->order_key(N_("signal"));
1887 (*i)->set_remote_control_id( order+1 );
1888 } else if ( EditorOrdered == m) {
1889 long order = (*i)->order_key(N_("editor"));
1890 (*i)->set_remote_control_id( order+1 );
1891 } else if ( UserOrdered == m) {
1892 //do nothing ... only changes to remote id's are initiated by user
1899 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1902 uint32_t bus_id = 1;
1904 uint32_t channels_used = 0;
1907 uint32_t control_id;
1909 /* count existing audio busses */
1912 shared_ptr<RouteList> r = routes.reader ();
1914 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1915 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1917 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1920 channels_used += (*i)->n_inputs().n_audio();
1926 vector<string> physinputs;
1927 vector<string> physoutputs;
1929 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1930 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1932 n_physical_audio_outputs = physoutputs.size();
1933 n_physical_audio_inputs = physinputs.size();
1935 control_id = ntracks() + nbusses() + 1;
1940 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1944 if (route_by_name (bus_name) == 0) {
1948 } while (bus_id < (UINT_MAX-1));
1951 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1953 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1954 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1955 input_channels, output_channels)
1961 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1962 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1963 input_channels, output_channels)
1968 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1971 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1972 port = physinputs[((n+x)%n_physical_audio_inputs)];
1975 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1980 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1983 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1984 port = physoutputs[((n+x)%n_physical_outputs)];
1985 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1987 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1991 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1996 channels_used += bus->n_inputs ().n_audio();
1998 bus->set_route_group (route_group, 0);
1999 bus->set_remote_control_id (control_id);
2002 ret.push_back (bus);
2006 catch (failed_constructor &err) {
2007 error << _("Session: could not create new audio route.") << endmsg;
2011 catch (AudioEngine::PortRegistrationFailure& pfe) {
2012 error << pfe.what() << endmsg;
2022 add_routes (ret, true);
2030 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2034 uint32_t control_id;
2036 uint32_t number = 1;
2038 if (!tree.read (template_path.c_str())) {
2042 XMLNode* node = tree.root();
2044 control_id = ntracks() + nbusses() + 1;
2048 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2050 std::string node_name = IO::name_from_state (*node_copy.children().front());
2052 /* generate a new name by adding a number to the end of the template name */
2055 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2059 if (route_by_name (name) == 0) {
2063 } while (number < UINT_MAX);
2065 if (number == UINT_MAX) {
2066 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2070 IO::set_name_in_state (*node_copy.children().front(), name);
2072 Track::zero_diskstream_id_in_xml (node_copy);
2075 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2078 error << _("Session: cannot create track/bus from template description") << endmsg;
2082 if (boost::dynamic_pointer_cast<Track>(route)) {
2083 /* force input/output change signals so that the new diskstream
2084 picks up the configuration of the route. During session
2085 loading this normally happens in a different way.
2087 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2088 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2091 route->set_remote_control_id (control_id);
2094 ret.push_back (route);
2097 catch (failed_constructor &err) {
2098 error << _("Session: could not create new route from template") << endmsg;
2102 catch (AudioEngine::PortRegistrationFailure& pfe) {
2103 error << pfe.what() << endmsg;
2112 add_routes (ret, true);
2119 Session::add_routes (RouteList& new_routes, bool save)
2122 RCUWriter<RouteList> writer (routes);
2123 shared_ptr<RouteList> r = writer.get_copy ();
2124 r->insert (r->end(), new_routes.begin(), new_routes.end());
2127 /* if there is no control out and we're not in the middle of loading,
2128 resort the graph here. if there is a control out, we will resort
2129 toward the end of this method. if we are in the middle of loading,
2130 we will resort when done.
2133 if (!_control_out && IO::connecting_legal) {
2134 resort_routes_using (r);
2138 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2140 boost::weak_ptr<Route> wpr (*x);
2142 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2143 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2144 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2145 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2146 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2147 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2149 if ((*x)->is_master()) {
2153 if ((*x)->is_control()) {
2154 _control_out = (*x);
2158 if (_control_out && IO::connecting_legal) {
2160 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2161 if ((*x)->is_control() || (*x)->is_master()) {
2164 (*x)->listen_via (_control_out,
2165 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2175 save_state (_current_snapshot_name);
2178 RouteAdded (new_routes); /* EMIT SIGNAL */
2182 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2184 boost::shared_ptr<RouteList> r = routes.reader ();
2185 boost::shared_ptr<Send> s;
2189 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2190 if (boost::dynamic_pointer_cast<Track>(*i)) {
2191 if ((s = (*i)->internal_send_for (dest)) != 0) {
2192 s->amp()->gain_control()->set_value (0.0);
2199 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2201 boost::shared_ptr<RouteList> r = routes.reader ();
2202 boost::shared_ptr<Send> s;
2206 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2207 if (boost::dynamic_pointer_cast<Track>(*i)) {
2208 if ((s = (*i)->internal_send_for (dest)) != 0) {
2209 s->amp()->gain_control()->set_value (1.0);
2216 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2218 boost::shared_ptr<RouteList> r = routes.reader ();
2219 boost::shared_ptr<Send> s;
2223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2224 if (boost::dynamic_pointer_cast<Track>(*i)) {
2225 if ((s = (*i)->internal_send_for (dest)) != 0) {
2226 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2233 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2235 boost::shared_ptr<RouteList> r = routes.reader ();
2236 boost::shared_ptr<RouteList> t (new RouteList);
2238 /* only send tracks */
2240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2241 if (boost::dynamic_pointer_cast<Track>(*i)) {
2246 add_internal_sends (dest, p, t);
2251 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2253 if (dest->is_control() || dest->is_master()) {
2257 if (!dest->internal_return()) {
2258 dest->add_internal_return();
2261 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2263 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2267 (*i)->listen_via (dest, p, true, true);
2272 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2274 /* need to do this in case we're rolling at the time, to prevent false underruns */
2275 dstream->do_refill_with_alloc ();
2277 dstream->set_block_size (current_block_size);
2280 RCUWriter<DiskstreamList> writer (diskstreams);
2281 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2282 ds->push_back (dstream);
2283 /* writer goes out of scope, copies ds back to main */
2286 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2287 /* this will connect to future changes, and check the current length */
2288 diskstream_playlist_changed (dstream);
2290 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2292 dstream->prepare ();
2297 Session::remove_route (shared_ptr<Route> route)
2300 RCUWriter<RouteList> writer (routes);
2301 shared_ptr<RouteList> rs = writer.get_copy ();
2305 /* deleting the master out seems like a dumb
2306 idea, but its more of a UI policy issue
2310 if (route == _master_out) {
2311 _master_out = shared_ptr<Route> ();
2314 if (route == _control_out) {
2316 /* cancel control outs for all routes */
2318 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2319 (*r)->drop_listen (_control_out);
2322 _control_out.reset ();
2325 update_route_solo_state ();
2327 /* writer goes out of scope, forces route list update */
2330 boost::shared_ptr<Track> t;
2331 boost::shared_ptr<Diskstream> ds;
2333 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2334 ds = t->diskstream();
2340 RCUWriter<DiskstreamList> dsl (diskstreams);
2341 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2346 find_current_end ();
2348 // We need to disconnect the routes inputs and outputs
2350 route->input()->disconnect (0);
2351 route->output()->disconnect (0);
2353 update_latency_compensation (false, false);
2356 /* get rid of it from the dead wood collection in the route list manager */
2358 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2362 /* try to cause everyone to drop their references */
2364 route->drop_references ();
2366 sync_order_keys (N_("session"));
2368 /* save the new state of the world */
2370 if (save_state (_current_snapshot_name)) {
2371 save_history (_current_snapshot_name);
2376 Session::route_mute_changed (void* /*src*/)
2382 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2384 boost::shared_ptr<Route> route = wpr.lock();
2386 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2390 if (route->listening()) {
2392 } else if (_listen_cnt > 0) {
2398 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2400 if (solo_update_disabled) {
2405 boost::shared_ptr<Route> route = wpr.lock ();
2408 /* should not happen */
2409 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2413 shared_ptr<RouteList> r = routes.reader ();
2416 if (route->soloed()) {
2422 /* now mod the solo level of all other routes except master & control outs
2423 so that they will be silent if appropriate.
2426 solo_update_disabled = true;
2427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2429 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2431 (*i)->mod_solo_level (delta);
2435 /* make sure master is never muted by solo */
2437 if (_master_out && route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2438 _master_out->mod_solo_level (1);
2441 /* ditto for control outs make sure master is never muted by solo */
2443 if (_control_out && route != _control_out && _control_out && _control_out->solo_level() == 0) {
2444 _control_out->mod_solo_level (1);
2447 solo_update_disabled = false;
2448 update_route_solo_state (r);
2449 SoloChanged (); /* EMIT SIGNAL */
2454 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2456 /* now figure out if anything that matters is soloed */
2458 bool something_soloed = false;
2461 r = routes.reader();
2464 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2465 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2466 something_soloed = true;
2471 if (something_soloed != _non_soloed_outs_muted) {
2472 _non_soloed_outs_muted = something_soloed;
2473 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2478 Session::route_by_name (string name)
2480 shared_ptr<RouteList> r = routes.reader ();
2482 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2483 if ((*i)->name() == name) {
2488 return shared_ptr<Route> ((Route*) 0);
2492 Session::route_by_id (PBD::ID id)
2494 shared_ptr<RouteList> r = routes.reader ();
2496 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2497 if ((*i)->id() == id) {
2502 return shared_ptr<Route> ((Route*) 0);
2506 Session::route_by_remote_id (uint32_t id)
2508 shared_ptr<RouteList> r = routes.reader ();
2510 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2511 if ((*i)->remote_control_id() == id) {
2516 return shared_ptr<Route> ((Route*) 0);
2520 Session::find_current_end ()
2522 if (_state_of_the_state & Loading) {
2526 nframes_t max = get_maximum_extent ();
2528 if (max > end_location->end()) {
2529 end_location->set_end (max);
2531 DurationChanged(); /* EMIT SIGNAL */
2536 Session::get_maximum_extent () const
2541 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2543 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2544 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2546 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2547 if ((me = pl->get_maximum_extent()) > max) {
2555 boost::shared_ptr<Diskstream>
2556 Session::diskstream_by_name (string name)
2558 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2560 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2561 if ((*i)->name() == name) {
2566 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2569 boost::shared_ptr<Diskstream>
2570 Session::diskstream_by_id (const PBD::ID& id)
2572 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2574 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2575 if ((*i)->id() == id) {
2580 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2583 /* Region management */
2586 Session::new_region_name (string old)
2588 string::size_type last_period;
2590 string::size_type len = old.length() + 64;
2593 if ((last_period = old.find_last_of ('.')) == string::npos) {
2595 /* no period present - add one explicitly */
2598 last_period = old.length() - 1;
2603 number = atoi (old.substr (last_period+1).c_str());
2607 while (number < (UINT_MAX-1)) {
2609 RegionList::const_iterator i;
2614 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2617 for (i = regions.begin(); i != regions.end(); ++i) {
2618 if (i->second->name() == sbuf) {
2623 if (i == regions.end()) {
2628 if (number != (UINT_MAX-1)) {
2632 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2637 Session::region_name (string& result, string base, bool newlevel)
2642 if (base.find("/") != string::npos) {
2643 base = base.substr(base.find_last_of("/") + 1);
2648 Glib::Mutex::Lock lm (region_lock);
2650 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2659 string::size_type pos;
2661 pos = base.find_last_of ('.');
2663 /* pos may be npos, but then we just use entire base */
2665 subbase = base.substr (0, pos);
2670 Glib::Mutex::Lock lm (region_lock);
2672 map<string,uint32_t>::iterator x;
2676 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2678 region_name_map[subbase] = 1;
2681 snprintf (buf, sizeof (buf), ".%d", x->second);
2692 Session::add_region (boost::shared_ptr<Region> region)
2694 vector<boost::shared_ptr<Region> > v;
2695 v.push_back (region);
2700 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2705 Glib::Mutex::Lock lm (region_lock);
2707 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2709 boost::shared_ptr<Region> region = *ii;
2713 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2717 RegionList::iterator x;
2719 for (x = regions.begin(); x != regions.end(); ++x) {
2721 if (region->region_list_equivalent (x->second)) {
2726 if (x == regions.end()) {
2728 pair<RegionList::key_type,RegionList::mapped_type> entry;
2730 entry.first = region->id();
2731 entry.second = region;
2733 pair<RegionList::iterator,bool> x = regions.insert (entry);
2745 /* mark dirty because something has changed even if we didn't
2746 add the region to the region list.
2753 vector<boost::weak_ptr<Region> > v;
2754 boost::shared_ptr<Region> first_r;
2756 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2758 boost::shared_ptr<Region> region = *ii;
2762 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2765 v.push_back (region);
2772 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2773 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2775 update_region_name_map (region);
2779 RegionsAdded (v); /* EMIT SIGNAL */
2785 Session::update_region_name_map (boost::shared_ptr<Region> region)
2787 string::size_type last_period = region->name().find_last_of ('.');
2789 if (last_period != string::npos && last_period < region->name().length() - 1) {
2791 string base = region->name().substr (0, last_period);
2792 string number = region->name().substr (last_period+1);
2793 map<string,uint32_t>::iterator x;
2795 /* note that if there is no number, we get zero from atoi,
2799 region_name_map[base] = atoi (number);
2804 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2806 boost::shared_ptr<Region> region (weak_region.lock ());
2812 if (what_changed & Region::HiddenChanged) {
2813 /* relay hidden changes */
2814 RegionHiddenChange (region);
2817 if (what_changed & NameChanged) {
2818 update_region_name_map (region);
2823 Session::remove_region (boost::weak_ptr<Region> weak_region)
2825 RegionList::iterator i;
2826 boost::shared_ptr<Region> region (weak_region.lock ());
2832 bool removed = false;
2835 Glib::Mutex::Lock lm (region_lock);
2837 if ((i = regions.find (region->id())) != regions.end()) {
2843 /* mark dirty because something has changed even if we didn't
2844 remove the region from the region list.
2850 RegionRemoved(region); /* EMIT SIGNAL */
2854 boost::shared_ptr<Region>
2855 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2857 RegionList::iterator i;
2858 boost::shared_ptr<Region> region;
2860 Glib::Mutex::Lock lm (region_lock);
2862 for (i = regions.begin(); i != regions.end(); ++i) {
2866 if (region->whole_file()) {
2868 if (child->source_equivalent (region)) {
2874 return boost::shared_ptr<Region> ();
2878 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2880 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2881 (*i)->get_region_list_equivalent_regions (region, result);
2885 Session::destroy_region (boost::shared_ptr<Region> region)
2887 vector<boost::shared_ptr<Source> > srcs;
2890 if (region->playlist()) {
2891 region->playlist()->destroy_region (region);
2894 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2895 srcs.push_back (region->source (n));
2899 region->drop_references ();
2901 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2903 (*i)->mark_for_remove ();
2904 (*i)->drop_references ();
2906 cerr << "source was not used by any playlist\n";
2913 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2915 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2916 destroy_region (*i);
2922 Session::remove_last_capture ()
2924 list<boost::shared_ptr<Region> > r;
2926 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2928 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2929 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2932 r.insert (r.end(), l.begin(), l.end());
2937 destroy_regions (r);
2939 save_state (_current_snapshot_name);
2945 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2951 /* Source Management */
2954 Session::add_source (boost::shared_ptr<Source> source)
2956 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2957 pair<SourceMap::iterator,bool> result;
2959 entry.first = source->id();
2960 entry.second = source;
2963 Glib::Mutex::Lock lm (source_lock);
2964 result = sources.insert (entry);
2967 if (result.second) {
2968 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2972 boost::shared_ptr<AudioFileSource> afs;
2974 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2975 if (Config->get_auto_analyse_audio()) {
2976 Analyser::queue_source_for_analysis (source, false);
2982 Session::remove_source (boost::weak_ptr<Source> src)
2984 SourceMap::iterator i;
2985 boost::shared_ptr<Source> source = src.lock();
2992 Glib::Mutex::Lock lm (source_lock);
2994 if ((i = sources.find (source->id())) != sources.end()) {
2999 if (!_state_of_the_state & InCleanup) {
3001 /* save state so we don't end up with a session file
3002 referring to non-existent sources.
3005 save_state (_current_snapshot_name);
3009 /** Return the number of playlists (not regions) that contain @a src */
3011 Session::source_use_count (boost::shared_ptr<const Source> src) const
3014 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3015 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3016 r != (*p)->region_list().end(); ++r) {
3017 if ((*r)->uses_source(src)) {
3026 boost::shared_ptr<Source>
3027 Session::source_by_id (const PBD::ID& id)
3029 Glib::Mutex::Lock lm (source_lock);
3030 SourceMap::iterator i;
3031 boost::shared_ptr<Source> source;
3033 if ((i = sources.find (id)) != sources.end()) {
3040 boost::shared_ptr<Source>
3041 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3043 Glib::Mutex::Lock lm (source_lock);
3045 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3046 cerr << "comparing " << path << " with " << i->second->name() << endl;
3047 boost::shared_ptr<AudioFileSource> afs
3048 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3050 if (afs && afs->path() == path && chn == afs->channel()) {
3054 return boost::shared_ptr<Source>();
3059 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3062 string old_basename = PBD::basename_nosuffix (oldname);
3063 string new_legalized = legalize_for_path (newname);
3065 /* note: we know (or assume) the old path is already valid */
3069 /* destructive file sources have a name of the form:
3071 /path/to/Tnnnn-NAME(%[LR])?.wav
3073 the task here is to replace NAME with the new name.
3076 /* find last slash */
3080 string::size_type slash;
3081 string::size_type dash;
3083 if ((slash = path.find_last_of ('/')) == string::npos) {
3087 dir = path.substr (0, slash+1);
3089 /* '-' is not a legal character for the NAME part of the path */
3091 if ((dash = path.find_last_of ('-')) == string::npos) {
3095 prefix = path.substr (slash+1, dash-(slash+1));
3100 path += new_legalized;
3101 path += ".wav"; /* XXX gag me with a spoon */
3105 /* non-destructive file sources have a name of the form:
3107 /path/to/NAME-nnnnn(%[LR])?.ext
3109 the task here is to replace NAME with the new name.
3114 string::size_type slash;
3115 string::size_type dash;
3116 string::size_type postfix;
3118 /* find last slash */
3120 if ((slash = path.find_last_of ('/')) == string::npos) {
3124 dir = path.substr (0, slash+1);
3126 /* '-' is not a legal character for the NAME part of the path */
3128 if ((dash = path.find_last_of ('-')) == string::npos) {
3132 suffix = path.substr (dash+1);
3134 // Suffix is now everything after the dash. Now we need to eliminate
3135 // the nnnnn part, which is done by either finding a '%' or a '.'
3137 postfix = suffix.find_last_of ("%");
3138 if (postfix == string::npos) {
3139 postfix = suffix.find_last_of ('.');
3142 if (postfix != string::npos) {
3143 suffix = suffix.substr (postfix);
3145 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3149 const uint32_t limit = 10000;
3150 char buf[PATH_MAX+1];
3152 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3154 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3156 if (access (buf, F_OK) != 0) {
3164 error << "FATAL ERROR! Could not find a " << endl;
3172 /** Return the full path (in some session directory) for a new embedded source.
3173 * \a name must be a session-unique name that does not contain slashes
3174 * (e.g. as returned by new_*_source_name)
3177 Session::new_source_path_from_name (DataType type, const string& name)
3179 assert(name.find("/") == string::npos);
3181 SessionDirectory sdir(get_best_session_directory_for_new_source());
3184 if (type == DataType::AUDIO) {
3185 p = sdir.sound_path();
3186 } else if (type == DataType::MIDI) {
3187 p = sdir.midi_path();
3189 error << "Unknown source type, unable to create file path" << endmsg;
3194 return p.to_string();
3198 Session::peak_path (Glib::ustring base) const
3200 sys::path peakfile_path(_session_dir->peak_path());
3201 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3202 return peakfile_path.to_string();
3205 /** Return a unique name based on \a base for a new internal audio source */
3207 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3211 char buf[PATH_MAX+1];
3212 const uint32_t limit = 10000;
3216 legalized = legalize_for_path (base);
3218 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3219 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3221 vector<space_and_path>::iterator i;
3222 uint32_t existing = 0;
3224 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3226 SessionDirectory sdir((*i).path);
3228 spath = sdir.sound_path().to_string();
3233 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3234 spath.c_str(), cnt, legalized.c_str());
3235 } else if (nchan == 2) {
3237 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3238 spath.c_str(), cnt, legalized.c_str());
3240 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3241 spath.c_str(), cnt, legalized.c_str());
3243 } else if (nchan < 26) {
3244 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3245 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3247 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3248 spath.c_str(), cnt, legalized.c_str());
3257 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3258 } else if (nchan == 2) {
3260 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3262 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3264 } else if (nchan < 26) {
3265 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3267 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3271 if (sys::exists(buf)) {
3277 if (existing == 0) {
3282 error << string_compose(
3283 _("There are already %1 recordings for %2, which I consider too many."),
3284 limit, base) << endmsg;
3286 throw failed_constructor();
3290 return Glib::path_get_basename(buf);
3293 /** Create a new embedded audio source */
3294 boost::shared_ptr<AudioFileSource>
3295 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3297 const size_t n_chans = ds.n_channels().n_audio();
3298 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3299 const string path = new_source_path_from_name(DataType::AUDIO, name);
3300 return boost::dynamic_pointer_cast<AudioFileSource> (
3301 SourceFactory::createWritable (
3302 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3305 /** Return a unique name based on \a base for a new internal MIDI source */
3307 Session::new_midi_source_name (const string& base)
3310 char buf[PATH_MAX+1];
3311 const uint32_t limit = 10000;
3315 legalized = legalize_for_path (base);
3317 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3318 for (cnt = 1; cnt <= limit; ++cnt) {
3320 vector<space_and_path>::iterator i;
3321 uint32_t existing = 0;
3323 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3325 SessionDirectory sdir((*i).path);
3327 sys::path p = sdir.midi_path();
3330 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3332 if (sys::exists (buf)) {
3337 if (existing == 0) {
3342 error << string_compose(
3343 _("There are already %1 recordings for %2, which I consider too many."),
3344 limit, base) << endmsg;
3346 throw failed_constructor();
3350 return Glib::path_get_basename(buf);
3354 /** Create a new embedded MIDI source */
3355 boost::shared_ptr<MidiSource>
3356 Session::create_midi_source_for_session (MidiDiskstream& ds)
3358 const string name = new_midi_source_name (ds.name());
3359 const string path = new_source_path_from_name (DataType::MIDI, name);
3361 return boost::dynamic_pointer_cast<SMFSource> (
3362 SourceFactory::createWritable (
3363 DataType::MIDI, *this, path, true, false, frame_rate()));
3367 /* Playlist management */
3369 boost::shared_ptr<Playlist>
3370 Session::playlist_by_name (string name)
3372 Glib::Mutex::Lock lm (playlist_lock);
3373 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3374 if ((*i)->name() == name) {
3378 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3379 if ((*i)->name() == name) {
3384 return boost::shared_ptr<Playlist>();
3388 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3390 Glib::Mutex::Lock lm (playlist_lock);
3391 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3392 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3393 list.push_back (*i);
3396 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3397 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3398 list.push_back (*i);
3404 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3406 if (playlist->hidden()) {
3411 Glib::Mutex::Lock lm (playlist_lock);
3412 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3413 playlists.insert (playlists.begin(), playlist);
3414 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3415 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3420 playlist->release();
3425 PlaylistAdded (playlist); /* EMIT SIGNAL */
3429 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3432 Glib::Mutex::Lock lm (playlist_lock);
3433 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3436 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3443 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3445 boost::shared_ptr<Playlist> pl(wpl.lock());
3451 PlaylistList::iterator x;
3454 /* its not supposed to be visible */
3459 Glib::Mutex::Lock lm (playlist_lock);
3463 unused_playlists.insert (pl);
3465 if ((x = playlists.find (pl)) != playlists.end()) {
3466 playlists.erase (x);
3472 playlists.insert (pl);
3474 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3475 unused_playlists.erase (x);
3482 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3484 if (_state_of_the_state & Deletion) {
3488 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3495 Glib::Mutex::Lock lm (playlist_lock);
3497 PlaylistList::iterator i;
3499 i = find (playlists.begin(), playlists.end(), playlist);
3500 if (i != playlists.end()) {
3501 playlists.erase (i);
3504 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3505 if (i != unused_playlists.end()) {
3506 unused_playlists.erase (i);
3513 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3517 Session::set_audition (boost::shared_ptr<Region> r)
3519 pending_audition_region = r;
3520 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3521 _butler->schedule_transport_work ();
3525 Session::audition_playlist ()
3527 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3528 ev->region.reset ();
3533 Session::non_realtime_set_audition ()
3535 if (!pending_audition_region) {
3536 auditioner->audition_current_playlist ();
3538 auditioner->audition_region (pending_audition_region);
3539 pending_audition_region.reset ();
3541 AuditionActive (true); /* EMIT SIGNAL */
3545 Session::audition_region (boost::shared_ptr<Region> r)
3547 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3553 Session::cancel_audition ()
3555 if (auditioner->active()) {
3556 auditioner->cancel_audition ();
3557 AuditionActive (false); /* EMIT SIGNAL */
3562 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3564 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3568 Session::remove_empty_sounds ()
3570 vector<string> audio_filenames;
3572 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3574 Glib::Mutex::Lock lm (source_lock);
3576 TapeFileMatcher tape_file_matcher;
3578 remove_if (audio_filenames.begin(), audio_filenames.end(),
3579 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3581 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3583 sys::path audio_file_path (_session_dir->sound_path());
3585 audio_file_path /= *i;
3587 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3591 sys::remove (audio_file_path);
3592 const string peakfile = peak_path (audio_file_path.to_string());
3593 sys::remove (peakfile);
3595 catch (const sys::filesystem_error& err)
3597 error << err.what() << endmsg;
3604 Session::is_auditioning () const
3606 /* can be called before we have an auditioner object */
3608 return auditioner->active();
3615 Session::set_all_solo (bool yn)
3617 shared_ptr<RouteList> r = routes.reader ();
3619 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3620 if (!(*i)->is_hidden()) {
3621 (*i)->set_solo (yn, this);
3629 Session::set_all_listen (bool yn)
3631 shared_ptr<RouteList> r = routes.reader ();
3633 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3634 if (!(*i)->is_hidden()) {
3635 (*i)->set_listen (yn, this);
3643 Session::set_all_mute (bool yn)
3645 shared_ptr<RouteList> r = routes.reader ();
3647 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3648 if (!(*i)->is_hidden()) {
3649 (*i)->set_mute (yn, this);
3657 Session::n_diskstreams () const
3661 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3663 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3664 if (!(*i)->hidden()) {
3672 Session::graph_reordered ()
3674 /* don't do this stuff if we are setting up connections
3675 from a set_state() call or creating new tracks.
3678 if (_state_of_the_state & InitialConnecting) {
3682 /* every track/bus asked for this to be handled but it was deferred because
3683 we were connecting. do it now.
3686 request_input_change_handling ();
3690 /* force all diskstreams to update their capture offset values to
3691 reflect any changes in latencies within the graph.
3694 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3696 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3697 (*i)->set_capture_offset ();
3702 Session::record_disenable_all ()
3704 record_enable_change_all (false);
3708 Session::record_enable_all ()
3710 record_enable_change_all (true);
3714 Session::record_enable_change_all (bool yn)
3716 shared_ptr<RouteList> r = routes.reader ();
3718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3719 boost::shared_ptr<Track> t;
3721 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3722 t->set_record_enable (yn, this);
3726 /* since we don't keep rec-enable state, don't mark session dirty */
3730 Session::add_processor (Processor* processor)
3732 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3737 Session::remove_processor (Processor* processor)
3741 PortInsert* port_insert;
3743 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3744 insert_bitset[port_insert->bit_slot()] = false;
3745 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3746 send_bitset[send->bit_slot()] = false;
3747 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3748 return_bitset[send->bit_slot()] = false;
3755 Session::available_capture_duration ()
3757 float sample_bytes_on_disk = 4.0; // keep gcc happy
3759 switch (config.get_native_file_data_format()) {
3761 sample_bytes_on_disk = 4.0;
3765 sample_bytes_on_disk = 3.0;
3769 sample_bytes_on_disk = 2.0;
3773 /* impossible, but keep some gcc versions happy */
3774 fatal << string_compose (_("programming error: %1"),
3775 X_("illegal native file data format"))
3780 double scale = 4096.0 / sample_bytes_on_disk;
3782 if (_total_free_4k_blocks * scale > (double) max_frames) {
3786 return (nframes_t) floor (_total_free_4k_blocks * scale);
3790 Session::add_bundle (shared_ptr<Bundle> bundle)
3793 RCUWriter<BundleList> writer (_bundles);
3794 boost::shared_ptr<BundleList> b = writer.get_copy ();
3795 b->push_back (bundle);
3798 BundleAdded (bundle); /* EMIT SIGNAL */
3804 Session::remove_bundle (shared_ptr<Bundle> bundle)
3806 bool removed = false;
3809 RCUWriter<BundleList> writer (_bundles);
3810 boost::shared_ptr<BundleList> b = writer.get_copy ();
3811 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3813 if (i != b->end()) {
3820 BundleRemoved (bundle); /* EMIT SIGNAL */
3827 Session::bundle_by_name (string name) const
3829 boost::shared_ptr<BundleList> b = _bundles.reader ();
3831 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3832 if ((*i)->name() == name) {
3837 return boost::shared_ptr<Bundle> ();
3841 Session::tempo_map_changed (Change)
3845 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3846 (*i)->update_after_tempo_map_change ();
3849 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3850 (*i)->update_after_tempo_map_change ();
3856 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3857 * the given count with the current block size.
3860 Session::ensure_buffers (ChanCount howmany)
3862 if (current_block_size == 0) {
3863 return; // too early? (is this ok?)
3866 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3867 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3868 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3869 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3870 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3873 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3877 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3879 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3880 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3885 Session::next_insert_id ()
3887 /* this doesn't really loop forever. just think about it */
3890 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3891 if (!insert_bitset[n]) {
3892 insert_bitset[n] = true;
3898 /* none available, so resize and try again */
3900 insert_bitset.resize (insert_bitset.size() + 16, false);
3905 Session::next_send_id ()
3907 /* this doesn't really loop forever. just think about it */
3910 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3911 if (!send_bitset[n]) {
3912 send_bitset[n] = true;
3918 /* none available, so resize and try again */
3920 send_bitset.resize (send_bitset.size() + 16, false);
3925 Session::next_return_id ()
3927 /* this doesn't really loop forever. just think about it */
3930 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3931 if (!return_bitset[n]) {
3932 return_bitset[n] = true;
3938 /* none available, so resize and try again */
3940 return_bitset.resize (return_bitset.size() + 16, false);
3945 Session::mark_send_id (uint32_t id)
3947 if (id >= send_bitset.size()) {
3948 send_bitset.resize (id+16, false);
3950 if (send_bitset[id]) {
3951 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3953 send_bitset[id] = true;
3957 Session::mark_return_id (uint32_t id)
3959 if (id >= return_bitset.size()) {
3960 return_bitset.resize (id+16, false);
3962 if (return_bitset[id]) {
3963 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3965 return_bitset[id] = true;
3969 Session::mark_insert_id (uint32_t id)
3971 if (id >= insert_bitset.size()) {
3972 insert_bitset.resize (id+16, false);
3974 if (insert_bitset[id]) {
3975 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3977 insert_bitset[id] = true;
3980 /* Named Selection management */
3983 Session::named_selection_by_name (string name)
3985 Glib::Mutex::Lock lm (named_selection_lock);
3986 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3987 if ((*i)->name == name) {
3995 Session::add_named_selection (NamedSelection* named_selection)
3998 Glib::Mutex::Lock lm (named_selection_lock);
3999 named_selections.insert (named_selections.begin(), named_selection);
4002 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4008 NamedSelectionAdded (); /* EMIT SIGNAL */
4012 Session::remove_named_selection (NamedSelection* named_selection)
4014 bool removed = false;
4017 Glib::Mutex::Lock lm (named_selection_lock);
4019 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4021 if (i != named_selections.end()) {
4023 named_selections.erase (i);
4030 NamedSelectionRemoved (); /* EMIT SIGNAL */
4035 Session::reset_native_file_format ()
4037 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4039 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4040 (*i)->reset_write_sources (false);
4045 Session::route_name_unique (string n) const
4047 shared_ptr<RouteList> r = routes.reader ();
4049 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4050 if ((*i)->name() == n) {
4059 Session::route_name_internal (string n) const
4061 if (auditioner && auditioner->name() == n) {
4065 if (_click_io && _click_io->name() == n) {
4073 Session::n_playlists () const
4075 Glib::Mutex::Lock lm (playlist_lock);
4076 return playlists.size();
4080 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4082 if (!force && howmany <= _npan_buffers) {
4086 if (_pan_automation_buffer) {
4088 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4089 delete [] _pan_automation_buffer[i];
4092 delete [] _pan_automation_buffer;
4095 _pan_automation_buffer = new pan_t*[howmany];
4097 for (uint32_t i = 0; i < howmany; ++i) {
4098 _pan_automation_buffer[i] = new pan_t[nframes];
4101 _npan_buffers = howmany;
4105 Session::freeze (InterThreadInfo& itt)
4107 shared_ptr<RouteList> r = routes.reader ();
4109 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4111 boost::shared_ptr<Track> t;
4113 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4114 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4124 boost::shared_ptr<Region>
4125 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4126 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4127 InterThreadInfo& itt, bool enable_processing)
4129 boost::shared_ptr<Region> result;
4130 boost::shared_ptr<Playlist> playlist;
4131 boost::shared_ptr<AudioFileSource> fsource;
4133 char buf[PATH_MAX+1];
4134 ChanCount nchans(track.audio_diskstream()->n_channels());
4136 nframes_t this_chunk;
4139 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4140 const string sound_dir = sdir.sound_path().to_string();
4141 nframes_t len = end - start;
4144 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4145 end, start) << endmsg;
4149 // any bigger than this seems to cause stack overflows in called functions
4150 const nframes_t chunk_size = (128 * 1024)/4;
4152 // block all process callback handling
4154 block_processing ();
4156 /* call tree *MUST* hold route_lock */
4158 if ((playlist = track.diskstream()->playlist()) == 0) {
4162 /* external redirects will be a problem */
4164 if (track.has_external_redirects()) {
4168 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4170 for (x = 0; x < 99999; ++x) {
4171 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4172 if (access (buf, F_OK) != 0) {
4178 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4183 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4184 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4187 catch (failed_constructor& err) {
4188 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4192 srcs.push_back (fsource);
4195 /* XXX need to flush all redirects */
4200 /* create a set of reasonably-sized buffers */
4201 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4202 buffers.set_count(nchans);
4204 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4205 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4207 afs->prepare_for_peakfile_writes ();
4210 while (to_do && !itt.cancel) {
4212 this_chunk = min (to_do, chunk_size);
4214 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4219 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4220 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4223 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4229 start += this_chunk;
4230 to_do -= this_chunk;
4232 itt.progress = (float) (1.0 - ((double) to_do / len));
4241 xnow = localtime (&now);
4243 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4244 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4247 afs->update_header (position, *xnow, now);
4248 afs->flush_header ();
4252 /* construct a region to represent the bounced material */
4254 result = RegionFactory::create (srcs, 0,
4255 srcs.front()->length(srcs.front()->timeline_position()),
4256 region_name_from_path (srcs.front()->name(), true));
4261 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4262 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4265 afs->mark_for_remove ();
4268 (*src)->drop_references ();
4272 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4273 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4276 afs->done_with_peakfile_writes ();
4280 unblock_processing ();
4286 Session::get_silent_buffers (ChanCount count)
4288 assert(_silent_buffers->available() >= count);
4289 _silent_buffers->set_count(count);
4291 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4292 for (size_t i= 0; i < count.get(*t); ++i) {
4293 _silent_buffers->get(*t, i).clear();
4297 return *_silent_buffers;
4301 Session::get_scratch_buffers (ChanCount count)
4303 if (count != ChanCount::ZERO) {
4304 assert(_scratch_buffers->available() >= count);
4305 _scratch_buffers->set_count(count);
4307 _scratch_buffers->set_count (_scratch_buffers->available());
4310 return *_scratch_buffers;
4314 Session::get_mix_buffers (ChanCount count)
4316 assert(_mix_buffers->available() >= count);
4317 _mix_buffers->set_count(count);
4318 return *_mix_buffers;
4322 Session::ntracks () const
4325 shared_ptr<RouteList> r = routes.reader ();
4327 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4328 if (boost::dynamic_pointer_cast<Track> (*i)) {
4337 Session::nbusses () const
4340 shared_ptr<RouteList> r = routes.reader ();
4342 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4343 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4352 Session::add_automation_list(AutomationList *al)
4354 automation_lists[al->id()] = al;
4358 Session::compute_initial_length ()
4360 return _engine.frame_rate() * 60 * 5;
4364 Session::sync_order_keys (std::string const & base)
4366 if (!Config->get_sync_all_route_ordering()) {
4367 /* leave order keys as they are */
4371 boost::shared_ptr<RouteList> r = routes.reader ();
4373 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4374 (*i)->sync_order_keys (base);
4377 Route::SyncOrderKeys (base); // EMIT SIGNAL
4381 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4383 Session::have_rec_enabled_diskstream () const
4385 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4388 /** Update the state of our rec-enabled diskstreams flag */
4390 Session::update_have_rec_enabled_diskstream ()
4392 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4393 DiskstreamList::iterator i = dsl->begin ();
4394 while (i != dsl->end () && (*i)->record_enabled () == false) {
4398 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4400 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4402 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4403 RecordStateChanged (); /* EMIT SIGNAL */
4408 Session::listen_position_changed ()
4412 switch (Config->get_listen_position()) {
4413 case AfterFaderListen:
4417 case PreFaderListen:
4422 boost::shared_ptr<RouteList> r = routes.reader ();
4424 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4425 (*i)->put_control_outs_at (p);
4430 Session::solo_control_mode_changed ()
4432 /* cancel all solo or all listen when solo control mode changes */
4434 if (Config->get_solo_control_is_listen_control()) {
4435 set_all_solo (false);
4437 set_all_listen (false);
4442 Session::route_group_changed ()
4444 RouteGroupChanged (); /* EMIT SIGNAL */