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 (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 (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::weak_ptr<Diskstream> wp)
876 boost::shared_ptr<Diskstream> dstream = wp.lock ();
881 boost::shared_ptr<Playlist> playlist;
883 if ((playlist = dstream->playlist()) != 0) {
884 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
887 /* see comment in playlist_length_changed () */
892 Session::record_enabling_legal () const
894 /* this used to be in here, but survey says.... we don't need to restrict it */
895 // if (record_status() == Recording) {
899 if (Config->get_all_safe()) {
906 Session::reset_input_monitor_state ()
908 if (transport_rolling()) {
910 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
912 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
913 if ((*i)->record_enabled ()) {
914 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
915 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
919 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
921 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
922 if ((*i)->record_enabled ()) {
923 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
924 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
931 Session::auto_punch_start_changed (Location* location)
933 replace_event (Event::PunchIn, location->start());
935 if (get_record_enabled() && config.get_punch_in()) {
936 /* capture start has been changed, so save new pending state */
937 save_state ("", true);
942 Session::auto_punch_end_changed (Location* location)
944 nframes_t when_to_stop = location->end();
945 // when_to_stop += _worst_output_latency + _worst_input_latency;
946 replace_event (Event::PunchOut, when_to_stop);
950 Session::auto_punch_changed (Location* location)
952 nframes_t when_to_stop = location->end();
954 replace_event (Event::PunchIn, location->start());
955 //when_to_stop += _worst_output_latency + _worst_input_latency;
956 replace_event (Event::PunchOut, when_to_stop);
960 Session::auto_loop_changed (Location* location)
962 replace_event (Event::AutoLoop, location->end(), location->start());
964 if (transport_rolling() && play_loop) {
967 // if (_transport_frame > location->end()) {
969 if (_transport_frame < location->start() || _transport_frame > location->end()) {
970 // relocate to beginning of loop
971 clear_events (Event::LocateRoll);
973 request_locate (location->start(), true);
976 else if (Config->get_seamless_loop() && !loop_changing) {
978 // schedule a locate-roll to refill the diskstreams at the
980 loop_changing = true;
982 if (location->end() > last_loopend) {
983 clear_events (Event::LocateRoll);
984 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
991 last_loopend = location->end();
995 Session::set_auto_punch_location (Location* location)
999 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1000 auto_punch_start_changed_connection.disconnect();
1001 auto_punch_end_changed_connection.disconnect();
1002 auto_punch_changed_connection.disconnect();
1003 existing->set_auto_punch (false, this);
1004 remove_event (existing->start(), Event::PunchIn);
1005 clear_events (Event::PunchOut);
1006 auto_punch_location_changed (0);
1011 if (location == 0) {
1015 if (location->end() <= location->start()) {
1016 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1020 auto_punch_start_changed_connection.disconnect();
1021 auto_punch_end_changed_connection.disconnect();
1022 auto_punch_changed_connection.disconnect();
1024 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1025 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1026 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1028 location->set_auto_punch (true, this);
1031 auto_punch_changed (location);
1033 auto_punch_location_changed (location);
1037 Session::set_auto_loop_location (Location* location)
1041 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1042 auto_loop_start_changed_connection.disconnect();
1043 auto_loop_end_changed_connection.disconnect();
1044 auto_loop_changed_connection.disconnect();
1045 existing->set_auto_loop (false, this);
1046 remove_event (existing->end(), Event::AutoLoop);
1047 auto_loop_location_changed (0);
1052 if (location == 0) {
1056 if (location->end() <= location->start()) {
1057 error << _("Session: you can't use a mark for auto loop") << endmsg;
1061 last_loopend = location->end();
1063 auto_loop_start_changed_connection.disconnect();
1064 auto_loop_end_changed_connection.disconnect();
1065 auto_loop_changed_connection.disconnect();
1067 auto_loop_start_changed_connection = location->start_changed.connect (
1068 mem_fun (this, &Session::auto_loop_changed));
1069 auto_loop_end_changed_connection = location->end_changed.connect (
1070 mem_fun (this, &Session::auto_loop_changed));
1071 auto_loop_changed_connection = location->changed.connect (
1072 mem_fun (this, &Session::auto_loop_changed));
1074 location->set_auto_loop (true, this);
1076 /* take care of our stuff first */
1078 auto_loop_changed (location);
1080 /* now tell everyone else */
1082 auto_loop_location_changed (location);
1086 Session::locations_added (Location *)
1092 Session::locations_changed ()
1094 _locations.apply (*this, &Session::handle_locations_changed);
1098 Session::handle_locations_changed (Locations::LocationList& locations)
1100 Locations::LocationList::iterator i;
1102 bool set_loop = false;
1103 bool set_punch = false;
1105 for (i = locations.begin(); i != locations.end(); ++i) {
1109 if (location->is_auto_punch()) {
1110 set_auto_punch_location (location);
1113 if (location->is_auto_loop()) {
1114 set_auto_loop_location (location);
1118 if (location->is_start()) {
1119 start_location = location;
1121 if (location->is_end()) {
1122 end_location = location;
1127 set_auto_loop_location (0);
1130 set_auto_punch_location (0);
1137 Session::enable_record ()
1139 /* XXX really atomic compare+swap here */
1140 if (g_atomic_int_get (&_record_status) != Recording) {
1141 g_atomic_int_set (&_record_status, Recording);
1142 _last_record_location = _transport_frame;
1143 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1145 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1146 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1147 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1148 if ((*i)->record_enabled ()) {
1149 (*i)->monitor_input (true);
1154 RecordStateChanged ();
1159 Session::disable_record (bool rt_context, bool force)
1163 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1165 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1166 g_atomic_int_set (&_record_status, Disabled);
1168 if (rs == Recording) {
1169 g_atomic_int_set (&_record_status, Enabled);
1173 // FIXME: timestamp correct? [DR]
1174 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1175 // does this /need/ to be sent in all cases?
1177 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1179 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1180 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1182 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1183 if ((*i)->record_enabled ()) {
1184 (*i)->monitor_input (false);
1189 RecordStateChanged (); /* emit signal */
1192 remove_pending_capture_state ();
1198 Session::step_back_from_record ()
1200 /* XXX really atomic compare+swap here */
1201 if (g_atomic_int_get (&_record_status) == Recording) {
1202 g_atomic_int_set (&_record_status, Enabled);
1204 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1205 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1207 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1208 if ((*i)->record_enabled ()) {
1209 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1210 (*i)->monitor_input (false);
1218 Session::maybe_enable_record ()
1220 g_atomic_int_set (&_record_status, Enabled);
1222 /* this function is currently called from somewhere other than an RT thread.
1223 this save_state() call therefore doesn't impact anything.
1226 save_state ("", true);
1228 if (_transport_speed) {
1229 if (!config.get_punch_in()) {
1233 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1234 RecordStateChanged (); /* EMIT SIGNAL */
1241 Session::audible_frame () const
1247 /* the first of these two possible settings for "offset"
1248 mean that the audible frame is stationary until
1249 audio emerges from the latency compensation
1252 the second means that the audible frame is stationary
1253 until audio would emerge from a physical port
1254 in the absence of any plugin latency compensation
1257 offset = _worst_output_latency;
1259 if (offset > current_block_size) {
1260 offset -= current_block_size;
1262 /* XXX is this correct? if we have no external
1263 physical connections and everything is internal
1264 then surely this is zero? still, how
1265 likely is that anyway?
1267 offset = current_block_size;
1270 if (synced_to_jack()) {
1271 tf = _engine.transport_frame();
1273 tf = _transport_frame;
1278 if (!non_realtime_work_pending()) {
1282 /* check to see if we have passed the first guaranteed
1283 audible frame past our last start position. if not,
1284 return that last start point because in terms
1285 of audible frames, we have not moved yet.
1288 if (_transport_speed > 0.0f) {
1290 if (!play_loop || !have_looped) {
1291 if (tf < _last_roll_location + offset) {
1292 return _last_roll_location;
1300 } else if (_transport_speed < 0.0f) {
1302 /* XXX wot? no backward looping? */
1304 if (tf > _last_roll_location - offset) {
1305 return _last_roll_location;
1317 Session::set_frame_rate (nframes_t frames_per_second)
1319 /** \fn void Session::set_frame_size(nframes_t)
1320 the AudioEngine object that calls this guarantees
1321 that it will not be called while we are also in
1322 ::process(). Its fine to do things that block
1326 _base_frame_rate = frames_per_second;
1330 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1334 // XXX we need some equivalent to this, somehow
1335 // SndFileSource::setup_standard_crossfades (frames_per_second);
1339 /* XXX need to reset/reinstantiate all LADSPA plugins */
1343 Session::set_block_size (nframes_t nframes)
1345 /* the AudioEngine guarantees
1346 that it will not be called while we are also in
1347 ::process(). It is therefore fine to do things that block
1352 current_block_size = nframes;
1354 ensure_buffers(_scratch_buffers->available());
1356 delete [] _gain_automation_buffer;
1357 _gain_automation_buffer = new gain_t[nframes];
1359 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1361 boost::shared_ptr<RouteList> r = routes.reader ();
1363 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1364 (*i)->set_block_size (nframes);
1367 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1368 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1369 (*i)->set_block_size (nframes);
1372 set_worst_io_latencies ();
1377 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1380 nframes_t fade_frames;
1382 /* Don't allow fade of less 1 frame */
1384 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1391 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1395 default_fade_msecs = fade_msecs;
1396 default_fade_steepness = steepness;
1399 // jlc, WTF is this!
1400 Glib::RWLock::ReaderLock lm (route_lock);
1401 AudioRegion::set_default_fade (steepness, fade_frames);
1406 /* XXX have to do this at some point */
1407 /* foreach region using default fade, reset, then
1408 refill_all_diskstream_buffers ();
1413 struct RouteSorter {
1414 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1415 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1417 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1420 if (r1->fed_by.empty()) {
1421 if (r2->fed_by.empty()) {
1422 /* no ardour-based connections inbound to either route. just use signal order */
1423 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1425 /* r2 has connections, r1 does not; run r1 early */
1429 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1436 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1438 shared_ptr<Route> r2;
1440 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1441 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1445 /* make a copy of the existing list of routes that feed r1 */
1447 set<shared_ptr<Route> > existing = r1->fed_by;
1449 /* for each route that feeds r1, recurse, marking it as feeding
1453 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1456 /* r2 is a route that feeds r1 which somehow feeds base. mark
1457 base as being fed by r2
1460 rbase->fed_by.insert (r2);
1464 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1468 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1472 /* now recurse, so that we can mark base as being fed by
1473 all routes that feed r2
1476 trace_terminal (r2, rbase);
1483 Session::resort_routes ()
1485 /* don't do anything here with signals emitted
1486 by Routes while we are being destroyed.
1489 if (_state_of_the_state & Deletion) {
1496 RCUWriter<RouteList> writer (routes);
1497 shared_ptr<RouteList> r = writer.get_copy ();
1498 resort_routes_using (r);
1499 /* writer goes out of scope and forces update */
1504 Session::resort_routes_using (shared_ptr<RouteList> r)
1506 RouteList::iterator i, j;
1508 for (i = r->begin(); i != r->end(); ++i) {
1510 (*i)->fed_by.clear ();
1512 for (j = r->begin(); j != r->end(); ++j) {
1514 /* although routes can feed themselves, it will
1515 cause an endless recursive descent if we
1516 detect it. so don't bother checking for
1524 if ((*j)->feeds (*i)) {
1525 (*i)->fed_by.insert (*j);
1530 for (i = r->begin(); i != r->end(); ++i) {
1531 trace_terminal (*i, *i);
1538 cerr << "finished route resort\n";
1540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1541 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1548 list<boost::shared_ptr<MidiTrack> >
1549 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1551 char track_name[32];
1552 uint32_t track_id = 0;
1555 RouteList new_routes;
1556 list<boost::shared_ptr<MidiTrack> > ret;
1557 //uint32_t control_id;
1559 // FIXME: need physical I/O and autoconnect stuff for MIDI
1561 /* count existing midi tracks */
1564 shared_ptr<RouteList> r = routes.reader ();
1566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1567 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1568 if (!(*i)->is_hidden()) {
1570 //channels_used += (*i)->n_inputs().n_midi();
1576 vector<string> physinputs;
1577 vector<string> physoutputs;
1579 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1580 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1582 // control_id = ntracks() + nbusses();
1586 /* check for duplicate route names, since we might have pre-existing
1587 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1588 save, close,restart,add new route - first named route is now
1596 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1598 if (route_by_name (track_name) == 0) {
1602 } while (track_id < (UINT_MAX-1));
1604 shared_ptr<MidiTrack> track;
1607 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1609 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1610 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1615 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1616 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1622 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1626 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1627 port = physinputs[(channels_used+x)%nphysical_in];
1630 if (port.length() && track->connect_input (track->input (x), port, this)) {
1636 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1640 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1641 port = physoutputs[(channels_used+x)%nphysical_out];
1642 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1644 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1648 if (port.length() && track->connect_output (track->output (x), port, this)) {
1653 channels_used += track->n_inputs ().n_midi();
1657 track->midi_diskstream()->non_realtime_input_change();
1658 track->set_route_group (route_group, 0);
1660 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1661 //track->set_remote_control_id (control_id);
1663 new_routes.push_back (track);
1664 ret.push_back (track);
1667 catch (failed_constructor &err) {
1668 error << _("Session: could not create new midi track.") << endmsg;
1671 /* we need to get rid of this, since the track failed to be created */
1672 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1675 RCUWriter<DiskstreamList> writer (diskstreams);
1676 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1677 ds->remove (track->midi_diskstream());
1684 catch (AudioEngine::PortRegistrationFailure& pfe) {
1686 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;
1689 /* we need to get rid of this, since the track failed to be created */
1690 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1693 RCUWriter<DiskstreamList> writer (diskstreams);
1694 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1695 ds->remove (track->midi_diskstream());
1706 if (!new_routes.empty()) {
1707 add_routes (new_routes, false);
1708 save_state (_current_snapshot_name);
1714 list<boost::shared_ptr<AudioTrack> >
1715 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1717 char track_name[32];
1718 uint32_t track_id = 0;
1720 uint32_t channels_used = 0;
1722 RouteList new_routes;
1723 list<boost::shared_ptr<AudioTrack> > ret;
1724 uint32_t control_id;
1726 /* count existing audio tracks */
1729 shared_ptr<RouteList> r = routes.reader ();
1731 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1732 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1733 if (!(*i)->is_hidden()) {
1735 channels_used += (*i)->n_inputs().n_audio();
1741 vector<string> physinputs;
1742 vector<string> physoutputs;
1744 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1745 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1747 control_id = ntracks() + nbusses() + 1;
1751 /* check for duplicate route names, since we might have pre-existing
1752 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1753 save, close,restart,add new route - first named route is now
1761 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1763 if (route_by_name (track_name) == 0) {
1767 } while (track_id < (UINT_MAX-1));
1769 shared_ptr<AudioTrack> track;
1772 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1774 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1775 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1776 input_channels, output_channels)
1781 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1782 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1788 if (!physinputs.empty()) {
1789 uint32_t nphysical_in = physinputs.size();
1791 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1795 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1796 port = physinputs[(channels_used+x)%nphysical_in];
1799 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1805 if (!physoutputs.empty()) {
1806 uint32_t nphysical_out = physoutputs.size();
1808 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1811 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1812 port = physoutputs[(channels_used+x)%nphysical_out];
1813 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1814 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1815 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1819 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1825 channels_used += track->n_inputs ().n_audio();
1827 track->set_route_group (route_group, 0);
1829 track->audio_diskstream()->non_realtime_input_change();
1831 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1832 track->set_remote_control_id (control_id);
1835 new_routes.push_back (track);
1836 ret.push_back (track);
1839 catch (failed_constructor &err) {
1840 error << _("Session: could not create new audio track.") << endmsg;
1843 /* we need to get rid of this, since the track failed to be created */
1844 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1847 RCUWriter<DiskstreamList> writer (diskstreams);
1848 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1849 ds->remove (track->audio_diskstream());
1856 catch (AudioEngine::PortRegistrationFailure& pfe) {
1858 error << pfe.what() << endmsg;
1861 /* we need to get rid of this, since the track failed to be created */
1862 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1865 RCUWriter<DiskstreamList> writer (diskstreams);
1866 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1867 ds->remove (track->audio_diskstream());
1878 if (!new_routes.empty()) {
1879 add_routes (new_routes, true);
1886 Session::set_remote_control_ids ()
1888 RemoteModel m = Config->get_remote_model();
1890 shared_ptr<RouteList> r = routes.reader ();
1892 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1893 if ( MixerOrdered == m) {
1894 long order = (*i)->order_key(N_("signal"));
1895 (*i)->set_remote_control_id( order+1 );
1896 } else if ( EditorOrdered == m) {
1897 long order = (*i)->order_key(N_("editor"));
1898 (*i)->set_remote_control_id( order+1 );
1899 } else if ( UserOrdered == m) {
1900 //do nothing ... only changes to remote id's are initiated by user
1907 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1910 uint32_t bus_id = 1;
1912 uint32_t channels_used = 0;
1915 uint32_t control_id;
1917 /* count existing audio busses */
1920 shared_ptr<RouteList> r = routes.reader ();
1922 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1923 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1925 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1928 channels_used += (*i)->n_inputs().n_audio();
1934 vector<string> physinputs;
1935 vector<string> physoutputs;
1937 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1938 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1940 n_physical_audio_outputs = physoutputs.size();
1941 n_physical_audio_inputs = physinputs.size();
1943 control_id = ntracks() + nbusses() + 1;
1948 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1952 if (route_by_name (bus_name) == 0) {
1956 } while (bus_id < (UINT_MAX-1));
1959 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1961 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1962 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1963 input_channels, output_channels)
1969 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1970 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1971 input_channels, output_channels)
1976 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1979 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1980 port = physinputs[((n+x)%n_physical_audio_inputs)];
1983 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1988 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1991 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1992 port = physoutputs[((n+x)%n_physical_outputs)];
1993 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1995 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1999 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
2004 channels_used += bus->n_inputs ().n_audio();
2006 bus->set_route_group (route_group, 0);
2007 bus->set_remote_control_id (control_id);
2011 bus->add_internal_return ();
2014 ret.push_back (bus);
2018 catch (failed_constructor &err) {
2019 error << _("Session: could not create new audio route.") << endmsg;
2023 catch (AudioEngine::PortRegistrationFailure& pfe) {
2024 error << pfe.what() << endmsg;
2034 add_routes (ret, true);
2042 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2046 uint32_t control_id;
2048 uint32_t number = 1;
2050 if (!tree.read (template_path.c_str())) {
2054 XMLNode* node = tree.root();
2056 control_id = ntracks() + nbusses() + 1;
2060 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2062 std::string node_name = IO::name_from_state (*node_copy.children().front());
2064 /* generate a new name by adding a number to the end of the template name */
2067 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2071 if (route_by_name (name) == 0) {
2075 } while (number < UINT_MAX);
2077 if (number == UINT_MAX) {
2078 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2082 IO::set_name_in_state (*node_copy.children().front(), name);
2084 Track::zero_diskstream_id_in_xml (node_copy);
2087 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2090 error << _("Session: cannot create track/bus from template description") << endmsg;
2094 if (boost::dynamic_pointer_cast<Track>(route)) {
2095 /* force input/output change signals so that the new diskstream
2096 picks up the configuration of the route. During session
2097 loading this normally happens in a different way.
2099 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2100 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2103 route->set_remote_control_id (control_id);
2106 ret.push_back (route);
2109 catch (failed_constructor &err) {
2110 error << _("Session: could not create new route from template") << endmsg;
2114 catch (AudioEngine::PortRegistrationFailure& pfe) {
2115 error << pfe.what() << endmsg;
2124 add_routes (ret, true);
2131 Session::add_routes (RouteList& new_routes, bool save)
2134 RCUWriter<RouteList> writer (routes);
2135 shared_ptr<RouteList> r = writer.get_copy ();
2136 r->insert (r->end(), new_routes.begin(), new_routes.end());
2139 /* if there is no control out and we're not in the middle of loading,
2140 resort the graph here. if there is a control out, we will resort
2141 toward the end of this method. if we are in the middle of loading,
2142 we will resort when done.
2145 if (!_control_out && IO::connecting_legal) {
2146 resort_routes_using (r);
2150 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2152 boost::weak_ptr<Route> wpr (*x);
2154 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2155 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2156 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2157 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2158 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2159 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2161 if ((*x)->is_master()) {
2165 if ((*x)->is_control()) {
2166 _control_out = (*x);
2170 if (_control_out && IO::connecting_legal) {
2172 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2173 if ((*x)->is_control() || (*x)->is_master()) {
2176 (*x)->listen_via (_control_out,
2177 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2187 save_state (_current_snapshot_name);
2190 RouteAdded (new_routes); /* EMIT SIGNAL */
2194 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2196 boost::shared_ptr<RouteList> r = routes.reader ();
2197 boost::shared_ptr<Send> s;
2201 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2202 if (boost::dynamic_pointer_cast<Track>(*i)) {
2203 if ((s = (*i)->internal_send_for (dest)) != 0) {
2204 s->amp()->gain_control()->set_value (0.0);
2211 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2213 boost::shared_ptr<RouteList> r = routes.reader ();
2214 boost::shared_ptr<Send> s;
2218 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2219 if (boost::dynamic_pointer_cast<Track>(*i)) {
2220 if ((s = (*i)->internal_send_for (dest)) != 0) {
2221 s->amp()->gain_control()->set_value (1.0);
2228 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2230 boost::shared_ptr<RouteList> r = routes.reader ();
2231 boost::shared_ptr<Send> s;
2235 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2236 if (boost::dynamic_pointer_cast<Track>(*i)) {
2237 if ((s = (*i)->internal_send_for (dest)) != 0) {
2238 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2245 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2247 boost::shared_ptr<RouteList> r = routes.reader ();
2248 boost::shared_ptr<RouteList> t (new RouteList);
2250 /* only send tracks */
2252 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2253 if (boost::dynamic_pointer_cast<Track>(*i)) {
2258 add_internal_sends (dest, p, t);
2263 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2265 if (dest->is_control() || dest->is_master()) {
2269 if (!dest->internal_return()) {
2270 dest->add_internal_return();
2273 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2275 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2279 (*i)->listen_via (dest, p, true, true);
2284 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2286 /* need to do this in case we're rolling at the time, to prevent false underruns */
2287 dstream->do_refill_with_alloc ();
2289 dstream->set_block_size (current_block_size);
2292 RCUWriter<DiskstreamList> writer (diskstreams);
2293 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2294 ds->push_back (dstream);
2295 /* writer goes out of scope, copies ds back to main */
2298 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2299 /* this will connect to future changes, and check the current length */
2300 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2302 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2304 dstream->prepare ();
2309 Session::remove_route (shared_ptr<Route> route)
2312 RCUWriter<RouteList> writer (routes);
2313 shared_ptr<RouteList> rs = writer.get_copy ();
2317 /* deleting the master out seems like a dumb
2318 idea, but its more of a UI policy issue
2322 if (route == _master_out) {
2323 _master_out = shared_ptr<Route> ();
2326 if (route == _control_out) {
2328 /* cancel control outs for all routes */
2330 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2331 (*r)->drop_listen (_control_out);
2334 _control_out.reset ();
2337 update_route_solo_state ();
2339 /* writer goes out of scope, forces route list update */
2342 boost::shared_ptr<Track> t;
2343 boost::shared_ptr<Diskstream> ds;
2345 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2346 ds = t->diskstream();
2352 RCUWriter<DiskstreamList> dsl (diskstreams);
2353 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2358 find_current_end ();
2360 // We need to disconnect the routes inputs and outputs
2362 route->input()->disconnect (0);
2363 route->output()->disconnect (0);
2365 update_latency_compensation (false, false);
2368 /* get rid of it from the dead wood collection in the route list manager */
2370 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2374 /* try to cause everyone to drop their references */
2376 route->drop_references ();
2378 sync_order_keys (N_("session"));
2380 /* save the new state of the world */
2382 if (save_state (_current_snapshot_name)) {
2383 save_history (_current_snapshot_name);
2388 Session::route_mute_changed (void* /*src*/)
2394 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2396 boost::shared_ptr<Route> route = wpr.lock();
2398 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2402 if (route->listening()) {
2404 } else if (_listen_cnt > 0) {
2410 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2412 if (solo_update_disabled) {
2417 boost::shared_ptr<Route> route = wpr.lock ();
2420 /* should not happen */
2421 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2425 shared_ptr<RouteList> r = routes.reader ();
2428 if (route->soloed()) {
2434 /* now mod the solo level of all other routes except master & control outs
2435 so that they will be silent if appropriate.
2438 solo_update_disabled = true;
2439 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2440 bool via_sends_only;
2442 if ((*i)->feeds (route, &via_sends_only) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2443 if (!via_sends_only) {
2445 (*i)->mod_solo_level (delta);
2450 /* make sure master is never muted by solo */
2452 if (_master_out && route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2453 _master_out->mod_solo_level (1);
2456 /* ditto for control outs make sure master is never muted by solo */
2458 if (_control_out && route != _control_out && _control_out && _control_out->solo_level() == 0) {
2459 _control_out->mod_solo_level (1);
2462 solo_update_disabled = false;
2463 update_route_solo_state (r);
2464 SoloChanged (); /* EMIT SIGNAL */
2469 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2471 /* now figure out if anything that matters is soloed */
2473 bool something_soloed = false;
2476 r = routes.reader();
2479 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2480 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2481 something_soloed = true;
2486 if (something_soloed != _non_soloed_outs_muted) {
2487 _non_soloed_outs_muted = something_soloed;
2488 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2492 boost::shared_ptr<RouteList>
2493 Session::get_routes_with_internal_returns() const
2495 shared_ptr<RouteList> r = routes.reader ();
2496 boost::shared_ptr<RouteList> rl (new RouteList);
2498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2499 if ((*i)->internal_return ()) {
2507 Session::route_by_name (string name)
2509 shared_ptr<RouteList> r = routes.reader ();
2511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2512 if ((*i)->name() == name) {
2517 return shared_ptr<Route> ((Route*) 0);
2521 Session::route_by_id (PBD::ID id)
2523 shared_ptr<RouteList> r = routes.reader ();
2525 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2526 if ((*i)->id() == id) {
2531 return shared_ptr<Route> ((Route*) 0);
2535 Session::route_by_remote_id (uint32_t id)
2537 shared_ptr<RouteList> r = routes.reader ();
2539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2540 if ((*i)->remote_control_id() == id) {
2545 return shared_ptr<Route> ((Route*) 0);
2549 Session::find_current_end ()
2551 if (_state_of_the_state & Loading) {
2555 nframes_t max = get_maximum_extent ();
2557 if (max > end_location->end()) {
2558 end_location->set_end (max);
2560 DurationChanged(); /* EMIT SIGNAL */
2565 Session::get_maximum_extent () const
2570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2572 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2573 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2575 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2576 if ((me = pl->get_maximum_extent()) > max) {
2584 boost::shared_ptr<Diskstream>
2585 Session::diskstream_by_name (string name)
2587 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2589 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2590 if ((*i)->name() == name) {
2595 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2598 boost::shared_ptr<Diskstream>
2599 Session::diskstream_by_id (const PBD::ID& id)
2601 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2603 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2604 if ((*i)->id() == id) {
2609 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2612 /* Region management */
2615 Session::new_region_name (string old)
2617 string::size_type last_period;
2619 string::size_type len = old.length() + 64;
2622 if ((last_period = old.find_last_of ('.')) == string::npos) {
2624 /* no period present - add one explicitly */
2627 last_period = old.length() - 1;
2632 number = atoi (old.substr (last_period+1).c_str());
2636 while (number < (UINT_MAX-1)) {
2638 RegionList::const_iterator i;
2643 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2646 for (i = regions.begin(); i != regions.end(); ++i) {
2647 if (i->second->name() == sbuf) {
2652 if (i == regions.end()) {
2657 if (number != (UINT_MAX-1)) {
2661 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2666 Session::region_name (string& result, string base, bool newlevel)
2671 if (base.find("/") != string::npos) {
2672 base = base.substr(base.find_last_of("/") + 1);
2677 Glib::Mutex::Lock lm (region_lock);
2679 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2688 string::size_type pos;
2690 pos = base.find_last_of ('.');
2692 /* pos may be npos, but then we just use entire base */
2694 subbase = base.substr (0, pos);
2699 Glib::Mutex::Lock lm (region_lock);
2701 map<string,uint32_t>::iterator x;
2705 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2707 region_name_map[subbase] = 1;
2710 snprintf (buf, sizeof (buf), ".%d", x->second);
2721 Session::add_region (boost::shared_ptr<Region> region)
2723 vector<boost::shared_ptr<Region> > v;
2724 v.push_back (region);
2729 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2734 Glib::Mutex::Lock lm (region_lock);
2736 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2738 boost::shared_ptr<Region> region = *ii;
2742 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2746 RegionList::iterator x;
2748 for (x = regions.begin(); x != regions.end(); ++x) {
2750 if (region->region_list_equivalent (x->second)) {
2755 if (x == regions.end()) {
2757 pair<RegionList::key_type,RegionList::mapped_type> entry;
2759 entry.first = region->id();
2760 entry.second = region;
2762 pair<RegionList::iterator,bool> x = regions.insert (entry);
2774 /* mark dirty because something has changed even if we didn't
2775 add the region to the region list.
2782 vector<boost::weak_ptr<Region> > v;
2783 boost::shared_ptr<Region> first_r;
2785 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2787 boost::shared_ptr<Region> region = *ii;
2791 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2794 v.push_back (region);
2801 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2802 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2804 update_region_name_map (region);
2808 RegionsAdded (v); /* EMIT SIGNAL */
2814 Session::update_region_name_map (boost::shared_ptr<Region> region)
2816 string::size_type last_period = region->name().find_last_of ('.');
2818 if (last_period != string::npos && last_period < region->name().length() - 1) {
2820 string base = region->name().substr (0, last_period);
2821 string number = region->name().substr (last_period+1);
2822 map<string,uint32_t>::iterator x;
2824 /* note that if there is no number, we get zero from atoi,
2828 region_name_map[base] = atoi (number);
2833 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2835 boost::shared_ptr<Region> region (weak_region.lock ());
2841 if (what_changed & Region::HiddenChanged) {
2842 /* relay hidden changes */
2843 RegionHiddenChange (region);
2846 if (what_changed & NameChanged) {
2847 update_region_name_map (region);
2852 Session::remove_region (boost::weak_ptr<Region> weak_region)
2854 RegionList::iterator i;
2855 boost::shared_ptr<Region> region (weak_region.lock ());
2861 bool removed = false;
2864 Glib::Mutex::Lock lm (region_lock);
2866 if ((i = regions.find (region->id())) != regions.end()) {
2872 /* mark dirty because something has changed even if we didn't
2873 remove the region from the region list.
2879 RegionRemoved(region); /* EMIT SIGNAL */
2883 boost::shared_ptr<Region>
2884 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2886 RegionList::iterator i;
2887 boost::shared_ptr<Region> region;
2889 Glib::Mutex::Lock lm (region_lock);
2891 for (i = regions.begin(); i != regions.end(); ++i) {
2895 if (region->whole_file()) {
2897 if (child->source_equivalent (region)) {
2903 return boost::shared_ptr<Region> ();
2907 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2909 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2910 (*i)->get_region_list_equivalent_regions (region, result);
2914 Session::destroy_region (boost::shared_ptr<Region> region)
2916 vector<boost::shared_ptr<Source> > srcs;
2919 if (region->playlist()) {
2920 region->playlist()->destroy_region (region);
2923 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2924 srcs.push_back (region->source (n));
2928 region->drop_references ();
2930 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2932 (*i)->mark_for_remove ();
2933 (*i)->drop_references ();
2935 cerr << "source was not used by any playlist\n";
2942 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2944 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2945 destroy_region (*i);
2951 Session::remove_last_capture ()
2953 list<boost::shared_ptr<Region> > r;
2955 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2957 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2958 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2961 r.insert (r.end(), l.begin(), l.end());
2966 destroy_regions (r);
2968 save_state (_current_snapshot_name);
2974 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2980 /* Source Management */
2983 Session::add_source (boost::shared_ptr<Source> source)
2985 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2986 pair<SourceMap::iterator,bool> result;
2988 entry.first = source->id();
2989 entry.second = source;
2992 Glib::Mutex::Lock lm (source_lock);
2993 result = sources.insert (entry);
2996 if (result.second) {
2997 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3001 boost::shared_ptr<AudioFileSource> afs;
3003 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3004 if (Config->get_auto_analyse_audio()) {
3005 Analyser::queue_source_for_analysis (source, false);
3011 Session::remove_source (boost::weak_ptr<Source> src)
3013 SourceMap::iterator i;
3014 boost::shared_ptr<Source> source = src.lock();
3021 Glib::Mutex::Lock lm (source_lock);
3023 if ((i = sources.find (source->id())) != sources.end()) {
3028 if (!_state_of_the_state & InCleanup) {
3030 /* save state so we don't end up with a session file
3031 referring to non-existent sources.
3034 save_state (_current_snapshot_name);
3038 /** Return the number of playlists (not regions) that contain @a src */
3040 Session::source_use_count (boost::shared_ptr<const Source> src) const
3043 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3044 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3045 r != (*p)->region_list().end(); ++r) {
3046 if ((*r)->uses_source(src)) {
3055 boost::shared_ptr<Source>
3056 Session::source_by_id (const PBD::ID& id)
3058 Glib::Mutex::Lock lm (source_lock);
3059 SourceMap::iterator i;
3060 boost::shared_ptr<Source> source;
3062 if ((i = sources.find (id)) != sources.end()) {
3069 boost::shared_ptr<Source>
3070 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3072 Glib::Mutex::Lock lm (source_lock);
3074 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3075 cerr << "comparing " << path << " with " << i->second->name() << endl;
3076 boost::shared_ptr<AudioFileSource> afs
3077 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3079 if (afs && afs->path() == path && chn == afs->channel()) {
3083 return boost::shared_ptr<Source>();
3088 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3091 string old_basename = PBD::basename_nosuffix (oldname);
3092 string new_legalized = legalize_for_path (newname);
3094 /* note: we know (or assume) the old path is already valid */
3098 /* destructive file sources have a name of the form:
3100 /path/to/Tnnnn-NAME(%[LR])?.wav
3102 the task here is to replace NAME with the new name.
3105 /* find last slash */
3109 string::size_type slash;
3110 string::size_type dash;
3112 if ((slash = path.find_last_of ('/')) == string::npos) {
3116 dir = path.substr (0, slash+1);
3118 /* '-' is not a legal character for the NAME part of the path */
3120 if ((dash = path.find_last_of ('-')) == string::npos) {
3124 prefix = path.substr (slash+1, dash-(slash+1));
3129 path += new_legalized;
3130 path += ".wav"; /* XXX gag me with a spoon */
3134 /* non-destructive file sources have a name of the form:
3136 /path/to/NAME-nnnnn(%[LR])?.ext
3138 the task here is to replace NAME with the new name.
3143 string::size_type slash;
3144 string::size_type dash;
3145 string::size_type postfix;
3147 /* find last slash */
3149 if ((slash = path.find_last_of ('/')) == string::npos) {
3153 dir = path.substr (0, slash+1);
3155 /* '-' is not a legal character for the NAME part of the path */
3157 if ((dash = path.find_last_of ('-')) == string::npos) {
3161 suffix = path.substr (dash+1);
3163 // Suffix is now everything after the dash. Now we need to eliminate
3164 // the nnnnn part, which is done by either finding a '%' or a '.'
3166 postfix = suffix.find_last_of ("%");
3167 if (postfix == string::npos) {
3168 postfix = suffix.find_last_of ('.');
3171 if (postfix != string::npos) {
3172 suffix = suffix.substr (postfix);
3174 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3178 const uint32_t limit = 10000;
3179 char buf[PATH_MAX+1];
3181 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3183 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3185 if (access (buf, F_OK) != 0) {
3193 error << "FATAL ERROR! Could not find a " << endl;
3201 /** Return the full path (in some session directory) for a new embedded source.
3202 * \a name must be a session-unique name that does not contain slashes
3203 * (e.g. as returned by new_*_source_name)
3206 Session::new_source_path_from_name (DataType type, const string& name)
3208 assert(name.find("/") == string::npos);
3210 SessionDirectory sdir(get_best_session_directory_for_new_source());
3213 if (type == DataType::AUDIO) {
3214 p = sdir.sound_path();
3215 } else if (type == DataType::MIDI) {
3216 p = sdir.midi_path();
3218 error << "Unknown source type, unable to create file path" << endmsg;
3223 return p.to_string();
3227 Session::peak_path (Glib::ustring base) const
3229 sys::path peakfile_path(_session_dir->peak_path());
3230 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3231 return peakfile_path.to_string();
3234 /** Return a unique name based on \a base for a new internal audio source */
3236 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3240 char buf[PATH_MAX+1];
3241 const uint32_t limit = 10000;
3245 legalized = legalize_for_path (base);
3247 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3248 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3250 vector<space_and_path>::iterator i;
3251 uint32_t existing = 0;
3253 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3255 SessionDirectory sdir((*i).path);
3257 spath = sdir.sound_path().to_string();
3262 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3263 spath.c_str(), cnt, legalized.c_str());
3264 } else if (nchan == 2) {
3266 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3267 spath.c_str(), cnt, legalized.c_str());
3269 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3270 spath.c_str(), cnt, legalized.c_str());
3272 } else if (nchan < 26) {
3273 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3274 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3276 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3277 spath.c_str(), cnt, legalized.c_str());
3286 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3287 } else if (nchan == 2) {
3289 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3291 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3293 } else if (nchan < 26) {
3294 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3296 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3300 if (sys::exists(buf)) {
3306 if (existing == 0) {
3311 error << string_compose(
3312 _("There are already %1 recordings for %2, which I consider too many."),
3313 limit, base) << endmsg;
3315 throw failed_constructor();
3319 return Glib::path_get_basename(buf);
3322 /** Create a new embedded audio source */
3323 boost::shared_ptr<AudioFileSource>
3324 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3326 const size_t n_chans = ds.n_channels().n_audio();
3327 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3328 const string path = new_source_path_from_name(DataType::AUDIO, name);
3329 return boost::dynamic_pointer_cast<AudioFileSource> (
3330 SourceFactory::createWritable (
3331 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3334 /** Return a unique name based on \a base for a new internal MIDI source */
3336 Session::new_midi_source_name (const string& base)
3339 char buf[PATH_MAX+1];
3340 const uint32_t limit = 10000;
3344 legalized = legalize_for_path (base);
3346 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3347 for (cnt = 1; cnt <= limit; ++cnt) {
3349 vector<space_and_path>::iterator i;
3350 uint32_t existing = 0;
3352 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3354 SessionDirectory sdir((*i).path);
3356 sys::path p = sdir.midi_path();
3359 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3361 if (sys::exists (buf)) {
3366 if (existing == 0) {
3371 error << string_compose(
3372 _("There are already %1 recordings for %2, which I consider too many."),
3373 limit, base) << endmsg;
3375 throw failed_constructor();
3379 return Glib::path_get_basename(buf);
3383 /** Create a new embedded MIDI source */
3384 boost::shared_ptr<MidiSource>
3385 Session::create_midi_source_for_session (MidiDiskstream& ds)
3387 const string name = new_midi_source_name (ds.name());
3388 const string path = new_source_path_from_name (DataType::MIDI, name);
3390 return boost::dynamic_pointer_cast<SMFSource> (
3391 SourceFactory::createWritable (
3392 DataType::MIDI, *this, path, true, false, frame_rate()));
3396 /* Playlist management */
3398 boost::shared_ptr<Playlist>
3399 Session::playlist_by_name (string name)
3401 Glib::Mutex::Lock lm (playlist_lock);
3402 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3403 if ((*i)->name() == name) {
3407 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3408 if ((*i)->name() == name) {
3413 return boost::shared_ptr<Playlist>();
3417 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3419 Glib::Mutex::Lock lm (playlist_lock);
3420 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3421 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3422 list.push_back (*i);
3425 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3426 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3427 list.push_back (*i);
3433 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3435 if (playlist->hidden()) {
3440 Glib::Mutex::Lock lm (playlist_lock);
3441 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3442 playlists.insert (playlists.begin(), playlist);
3443 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3444 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3449 playlist->release();
3454 PlaylistAdded (playlist); /* EMIT SIGNAL */
3458 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3461 Glib::Mutex::Lock lm (playlist_lock);
3462 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3465 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3472 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3474 boost::shared_ptr<Playlist> pl(wpl.lock());
3480 PlaylistList::iterator x;
3483 /* its not supposed to be visible */
3488 Glib::Mutex::Lock lm (playlist_lock);
3492 unused_playlists.insert (pl);
3494 if ((x = playlists.find (pl)) != playlists.end()) {
3495 playlists.erase (x);
3501 playlists.insert (pl);
3503 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3504 unused_playlists.erase (x);
3511 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3513 if (_state_of_the_state & Deletion) {
3517 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3524 Glib::Mutex::Lock lm (playlist_lock);
3526 PlaylistList::iterator i;
3528 i = find (playlists.begin(), playlists.end(), playlist);
3529 if (i != playlists.end()) {
3530 playlists.erase (i);
3533 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3534 if (i != unused_playlists.end()) {
3535 unused_playlists.erase (i);
3542 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3546 Session::set_audition (boost::shared_ptr<Region> r)
3548 pending_audition_region = r;
3549 add_post_transport_work (PostTransportAudition);
3550 _butler->schedule_transport_work ();
3554 Session::audition_playlist ()
3556 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3557 ev->region.reset ();
3562 Session::non_realtime_set_audition ()
3564 if (!pending_audition_region) {
3565 auditioner->audition_current_playlist ();
3567 auditioner->audition_region (pending_audition_region);
3568 pending_audition_region.reset ();
3570 AuditionActive (true); /* EMIT SIGNAL */
3574 Session::audition_region (boost::shared_ptr<Region> r)
3576 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3582 Session::cancel_audition ()
3584 if (auditioner->active()) {
3585 auditioner->cancel_audition ();
3586 AuditionActive (false); /* EMIT SIGNAL */
3591 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3593 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3597 Session::remove_empty_sounds ()
3599 vector<string> audio_filenames;
3601 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3603 Glib::Mutex::Lock lm (source_lock);
3605 TapeFileMatcher tape_file_matcher;
3607 remove_if (audio_filenames.begin(), audio_filenames.end(),
3608 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3610 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3612 sys::path audio_file_path (_session_dir->sound_path());
3614 audio_file_path /= *i;
3616 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3620 sys::remove (audio_file_path);
3621 const string peakfile = peak_path (audio_file_path.to_string());
3622 sys::remove (peakfile);
3624 catch (const sys::filesystem_error& err)
3626 error << err.what() << endmsg;
3633 Session::is_auditioning () const
3635 /* can be called before we have an auditioner object */
3637 return auditioner->active();
3644 Session::set_all_solo (bool yn)
3646 shared_ptr<RouteList> r = routes.reader ();
3648 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3649 if (!(*i)->is_hidden()) {
3650 (*i)->set_solo (yn, this);
3658 Session::set_all_listen (bool yn)
3660 shared_ptr<RouteList> r = routes.reader ();
3662 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3663 if (!(*i)->is_hidden()) {
3664 (*i)->set_listen (yn, this);
3672 Session::set_all_mute (bool yn)
3674 shared_ptr<RouteList> r = routes.reader ();
3676 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3677 if (!(*i)->is_hidden()) {
3678 (*i)->set_mute (yn, this);
3686 Session::n_diskstreams () const
3690 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3692 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3693 if (!(*i)->hidden()) {
3701 Session::graph_reordered ()
3703 /* don't do this stuff if we are setting up connections
3704 from a set_state() call or creating new tracks.
3707 if (_state_of_the_state & InitialConnecting) {
3711 /* every track/bus asked for this to be handled but it was deferred because
3712 we were connecting. do it now.
3715 request_input_change_handling ();
3719 /* force all diskstreams to update their capture offset values to
3720 reflect any changes in latencies within the graph.
3723 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3725 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3726 (*i)->set_capture_offset ();
3731 Session::record_disenable_all ()
3733 record_enable_change_all (false);
3737 Session::record_enable_all ()
3739 record_enable_change_all (true);
3743 Session::record_enable_change_all (bool yn)
3745 shared_ptr<RouteList> r = routes.reader ();
3747 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3748 boost::shared_ptr<Track> t;
3750 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3751 t->set_record_enable (yn, this);
3755 /* since we don't keep rec-enable state, don't mark session dirty */
3759 Session::add_processor (Processor* processor)
3761 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3766 Session::remove_processor (Processor* processor)
3770 PortInsert* port_insert;
3772 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3773 insert_bitset[port_insert->bit_slot()] = false;
3774 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3775 send_bitset[send->bit_slot()] = false;
3776 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3777 return_bitset[send->bit_slot()] = false;
3784 Session::available_capture_duration ()
3786 float sample_bytes_on_disk = 4.0; // keep gcc happy
3788 switch (config.get_native_file_data_format()) {
3790 sample_bytes_on_disk = 4.0;
3794 sample_bytes_on_disk = 3.0;
3798 sample_bytes_on_disk = 2.0;
3802 /* impossible, but keep some gcc versions happy */
3803 fatal << string_compose (_("programming error: %1"),
3804 X_("illegal native file data format"))
3809 double scale = 4096.0 / sample_bytes_on_disk;
3811 if (_total_free_4k_blocks * scale > (double) max_frames) {
3815 return (nframes_t) floor (_total_free_4k_blocks * scale);
3819 Session::add_bundle (shared_ptr<Bundle> bundle)
3822 RCUWriter<BundleList> writer (_bundles);
3823 boost::shared_ptr<BundleList> b = writer.get_copy ();
3824 b->push_back (bundle);
3827 BundleAdded (bundle); /* EMIT SIGNAL */
3833 Session::remove_bundle (shared_ptr<Bundle> bundle)
3835 bool removed = false;
3838 RCUWriter<BundleList> writer (_bundles);
3839 boost::shared_ptr<BundleList> b = writer.get_copy ();
3840 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3842 if (i != b->end()) {
3849 BundleRemoved (bundle); /* EMIT SIGNAL */
3856 Session::bundle_by_name (string name) const
3858 boost::shared_ptr<BundleList> b = _bundles.reader ();
3860 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3861 if ((*i)->name() == name) {
3866 return boost::shared_ptr<Bundle> ();
3870 Session::tempo_map_changed (Change)
3874 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3875 (*i)->update_after_tempo_map_change ();
3878 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3879 (*i)->update_after_tempo_map_change ();
3885 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3886 * the given count with the current block size.
3889 Session::ensure_buffers (ChanCount howmany)
3891 if (current_block_size == 0) {
3892 return; // too early? (is this ok?)
3895 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3896 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3897 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3898 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3899 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3902 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3906 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3908 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3909 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3914 Session::next_insert_id ()
3916 /* this doesn't really loop forever. just think about it */
3919 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3920 if (!insert_bitset[n]) {
3921 insert_bitset[n] = true;
3927 /* none available, so resize and try again */
3929 insert_bitset.resize (insert_bitset.size() + 16, false);
3934 Session::next_send_id ()
3936 /* this doesn't really loop forever. just think about it */
3939 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3940 if (!send_bitset[n]) {
3941 send_bitset[n] = true;
3947 /* none available, so resize and try again */
3949 send_bitset.resize (send_bitset.size() + 16, false);
3954 Session::next_return_id ()
3956 /* this doesn't really loop forever. just think about it */
3959 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3960 if (!return_bitset[n]) {
3961 return_bitset[n] = true;
3967 /* none available, so resize and try again */
3969 return_bitset.resize (return_bitset.size() + 16, false);
3974 Session::mark_send_id (uint32_t id)
3976 if (id >= send_bitset.size()) {
3977 send_bitset.resize (id+16, false);
3979 if (send_bitset[id]) {
3980 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3982 send_bitset[id] = true;
3986 Session::mark_return_id (uint32_t id)
3988 if (id >= return_bitset.size()) {
3989 return_bitset.resize (id+16, false);
3991 if (return_bitset[id]) {
3992 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3994 return_bitset[id] = true;
3998 Session::mark_insert_id (uint32_t id)
4000 if (id >= insert_bitset.size()) {
4001 insert_bitset.resize (id+16, false);
4003 if (insert_bitset[id]) {
4004 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4006 insert_bitset[id] = true;
4009 /* Named Selection management */
4012 Session::named_selection_by_name (string name)
4014 Glib::Mutex::Lock lm (named_selection_lock);
4015 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
4016 if ((*i)->name == name) {
4024 Session::add_named_selection (NamedSelection* named_selection)
4027 Glib::Mutex::Lock lm (named_selection_lock);
4028 named_selections.insert (named_selections.begin(), named_selection);
4031 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4037 NamedSelectionAdded (); /* EMIT SIGNAL */
4041 Session::remove_named_selection (NamedSelection* named_selection)
4043 bool removed = false;
4046 Glib::Mutex::Lock lm (named_selection_lock);
4048 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4050 if (i != named_selections.end()) {
4052 named_selections.erase (i);
4059 NamedSelectionRemoved (); /* EMIT SIGNAL */
4064 Session::reset_native_file_format ()
4066 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4068 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4069 (*i)->reset_write_sources (false);
4074 Session::route_name_unique (string n) const
4076 shared_ptr<RouteList> r = routes.reader ();
4078 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4079 if ((*i)->name() == n) {
4088 Session::route_name_internal (string n) const
4090 if (auditioner && auditioner->name() == n) {
4094 if (_click_io && _click_io->name() == n) {
4102 Session::n_playlists () const
4104 Glib::Mutex::Lock lm (playlist_lock);
4105 return playlists.size();
4109 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4111 if (!force && howmany <= _npan_buffers) {
4115 if (_pan_automation_buffer) {
4117 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4118 delete [] _pan_automation_buffer[i];
4121 delete [] _pan_automation_buffer;
4124 _pan_automation_buffer = new pan_t*[howmany];
4126 for (uint32_t i = 0; i < howmany; ++i) {
4127 _pan_automation_buffer[i] = new pan_t[nframes];
4130 _npan_buffers = howmany;
4134 Session::freeze (InterThreadInfo& itt)
4136 shared_ptr<RouteList> r = routes.reader ();
4138 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4140 boost::shared_ptr<Track> t;
4142 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4143 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4153 boost::shared_ptr<Region>
4154 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4155 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4156 InterThreadInfo& itt, bool enable_processing)
4158 boost::shared_ptr<Region> result;
4159 boost::shared_ptr<Playlist> playlist;
4160 boost::shared_ptr<AudioFileSource> fsource;
4162 char buf[PATH_MAX+1];
4163 ChanCount nchans(track.audio_diskstream()->n_channels());
4165 nframes_t this_chunk;
4168 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4169 const string sound_dir = sdir.sound_path().to_string();
4170 nframes_t len = end - start;
4173 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4174 end, start) << endmsg;
4178 // any bigger than this seems to cause stack overflows in called functions
4179 const nframes_t chunk_size = (128 * 1024)/4;
4181 // block all process callback handling
4183 block_processing ();
4185 /* call tree *MUST* hold route_lock */
4187 if ((playlist = track.diskstream()->playlist()) == 0) {
4191 /* external redirects will be a problem */
4193 if (track.has_external_redirects()) {
4197 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4199 for (x = 0; x < 99999; ++x) {
4200 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4201 if (access (buf, F_OK) != 0) {
4207 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4212 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4213 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4216 catch (failed_constructor& err) {
4217 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4221 srcs.push_back (fsource);
4224 /* XXX need to flush all redirects */
4229 /* create a set of reasonably-sized buffers */
4230 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4231 buffers.set_count(nchans);
4233 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4234 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4236 afs->prepare_for_peakfile_writes ();
4239 while (to_do && !itt.cancel) {
4241 this_chunk = min (to_do, chunk_size);
4243 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4248 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4249 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4252 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4258 start += this_chunk;
4259 to_do -= this_chunk;
4261 itt.progress = (float) (1.0 - ((double) to_do / len));
4270 xnow = localtime (&now);
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->update_header (position, *xnow, now);
4277 afs->flush_header ();
4281 /* construct a region to represent the bounced material */
4283 result = RegionFactory::create (srcs, 0,
4284 srcs.front()->length(srcs.front()->timeline_position()),
4285 region_name_from_path (srcs.front()->name(), true));
4290 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4291 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4294 afs->mark_for_remove ();
4297 (*src)->drop_references ();
4301 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4302 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4305 afs->done_with_peakfile_writes ();
4309 unblock_processing ();
4315 Session::get_silent_buffers (ChanCount count)
4317 assert(_silent_buffers->available() >= count);
4318 _silent_buffers->set_count(count);
4320 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4321 for (size_t i= 0; i < count.get(*t); ++i) {
4322 _silent_buffers->get(*t, i).clear();
4326 return *_silent_buffers;
4330 Session::get_scratch_buffers (ChanCount count)
4332 if (count != ChanCount::ZERO) {
4333 assert(_scratch_buffers->available() >= count);
4334 _scratch_buffers->set_count(count);
4336 _scratch_buffers->set_count (_scratch_buffers->available());
4339 return *_scratch_buffers;
4343 Session::get_mix_buffers (ChanCount count)
4345 assert(_mix_buffers->available() >= count);
4346 _mix_buffers->set_count(count);
4347 return *_mix_buffers;
4351 Session::ntracks () const
4354 shared_ptr<RouteList> r = routes.reader ();
4356 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4357 if (boost::dynamic_pointer_cast<Track> (*i)) {
4366 Session::nbusses () const
4369 shared_ptr<RouteList> r = routes.reader ();
4371 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4372 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4381 Session::add_automation_list(AutomationList *al)
4383 automation_lists[al->id()] = al;
4387 Session::compute_initial_length ()
4389 return _engine.frame_rate() * 60 * 5;
4393 Session::sync_order_keys (std::string const & base)
4395 if (!Config->get_sync_all_route_ordering()) {
4396 /* leave order keys as they are */
4400 boost::shared_ptr<RouteList> r = routes.reader ();
4402 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4403 (*i)->sync_order_keys (base);
4406 Route::SyncOrderKeys (base); // EMIT SIGNAL
4410 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4412 Session::have_rec_enabled_diskstream () const
4414 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4417 /** Update the state of our rec-enabled diskstreams flag */
4419 Session::update_have_rec_enabled_diskstream ()
4421 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4422 DiskstreamList::iterator i = dsl->begin ();
4423 while (i != dsl->end () && (*i)->record_enabled () == false) {
4427 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4429 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4431 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4432 RecordStateChanged (); /* EMIT SIGNAL */
4437 Session::listen_position_changed ()
4441 switch (Config->get_listen_position()) {
4442 case AfterFaderListen:
4446 case PreFaderListen:
4451 boost::shared_ptr<RouteList> r = routes.reader ();
4453 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4454 (*i)->put_control_outs_at (p);
4459 Session::solo_control_mode_changed ()
4461 /* cancel all solo or all listen when solo control mode changes */
4463 if (Config->get_solo_control_is_listen_control()) {
4464 set_all_solo (false);
4466 set_all_listen (false);
4471 Session::route_group_changed ()
4473 RouteGroupChanged (); /* EMIT SIGNAL */
4477 Session::get_available_sync_options () const
4479 vector<SyncSource> ret;
4481 ret.push_back (JACK);
4484 ret.push_back (MTC);
4487 if (midi_clock_port()) {
4488 ret.push_back (MIDIClock);