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 (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);
2010 ret.push_back (bus);
2014 catch (failed_constructor &err) {
2015 error << _("Session: could not create new audio route.") << endmsg;
2019 catch (AudioEngine::PortRegistrationFailure& pfe) {
2020 error << pfe.what() << endmsg;
2030 add_routes (ret, true);
2038 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2042 uint32_t control_id;
2044 uint32_t number = 1;
2046 if (!tree.read (template_path.c_str())) {
2050 XMLNode* node = tree.root();
2052 control_id = ntracks() + nbusses() + 1;
2056 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2058 std::string node_name = IO::name_from_state (*node_copy.children().front());
2060 /* generate a new name by adding a number to the end of the template name */
2063 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2067 if (route_by_name (name) == 0) {
2071 } while (number < UINT_MAX);
2073 if (number == UINT_MAX) {
2074 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2078 IO::set_name_in_state (*node_copy.children().front(), name);
2080 Track::zero_diskstream_id_in_xml (node_copy);
2083 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2086 error << _("Session: cannot create track/bus from template description") << endmsg;
2090 if (boost::dynamic_pointer_cast<Track>(route)) {
2091 /* force input/output change signals so that the new diskstream
2092 picks up the configuration of the route. During session
2093 loading this normally happens in a different way.
2095 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2096 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2099 route->set_remote_control_id (control_id);
2102 ret.push_back (route);
2105 catch (failed_constructor &err) {
2106 error << _("Session: could not create new route from template") << endmsg;
2110 catch (AudioEngine::PortRegistrationFailure& pfe) {
2111 error << pfe.what() << endmsg;
2120 add_routes (ret, true);
2127 Session::add_routes (RouteList& new_routes, bool save)
2130 RCUWriter<RouteList> writer (routes);
2131 shared_ptr<RouteList> r = writer.get_copy ();
2132 r->insert (r->end(), new_routes.begin(), new_routes.end());
2135 /* if there is no control out and we're not in the middle of loading,
2136 resort the graph here. if there is a control out, we will resort
2137 toward the end of this method. if we are in the middle of loading,
2138 we will resort when done.
2141 if (!_control_out && IO::connecting_legal) {
2142 resort_routes_using (r);
2146 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2148 boost::weak_ptr<Route> wpr (*x);
2150 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2151 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2152 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2153 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2154 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2155 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2157 if ((*x)->is_master()) {
2161 if ((*x)->is_control()) {
2162 _control_out = (*x);
2166 if (_control_out && IO::connecting_legal) {
2168 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2169 if ((*x)->is_control() || (*x)->is_master()) {
2172 (*x)->listen_via (_control_out,
2173 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2183 save_state (_current_snapshot_name);
2186 RouteAdded (new_routes); /* EMIT SIGNAL */
2190 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2192 boost::shared_ptr<RouteList> r = routes.reader ();
2193 boost::shared_ptr<Send> s;
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if (boost::dynamic_pointer_cast<Track>(*i)) {
2199 if ((s = (*i)->internal_send_for (dest)) != 0) {
2200 s->amp()->gain_control()->set_value (0.0);
2207 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2209 boost::shared_ptr<RouteList> r = routes.reader ();
2210 boost::shared_ptr<Send> s;
2214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2215 if (boost::dynamic_pointer_cast<Track>(*i)) {
2216 if ((s = (*i)->internal_send_for (dest)) != 0) {
2217 s->amp()->gain_control()->set_value (1.0);
2224 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2226 boost::shared_ptr<RouteList> r = routes.reader ();
2227 boost::shared_ptr<Send> s;
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if (boost::dynamic_pointer_cast<Track>(*i)) {
2233 if ((s = (*i)->internal_send_for (dest)) != 0) {
2234 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2241 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2243 boost::shared_ptr<RouteList> r = routes.reader ();
2244 boost::shared_ptr<RouteList> t (new RouteList);
2246 /* only send tracks */
2248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2249 if (boost::dynamic_pointer_cast<Track>(*i)) {
2254 add_internal_sends (dest, p, t);
2259 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2261 if (dest->is_control() || dest->is_master()) {
2265 if (!dest->internal_return()) {
2266 dest->add_internal_return();
2269 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2271 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2275 (*i)->listen_via (dest, p, true, true);
2280 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2282 /* need to do this in case we're rolling at the time, to prevent false underruns */
2283 dstream->do_refill_with_alloc ();
2285 dstream->set_block_size (current_block_size);
2288 RCUWriter<DiskstreamList> writer (diskstreams);
2289 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2290 ds->push_back (dstream);
2291 /* writer goes out of scope, copies ds back to main */
2294 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2295 /* this will connect to future changes, and check the current length */
2296 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2298 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2300 dstream->prepare ();
2305 Session::remove_route (shared_ptr<Route> route)
2308 RCUWriter<RouteList> writer (routes);
2309 shared_ptr<RouteList> rs = writer.get_copy ();
2313 /* deleting the master out seems like a dumb
2314 idea, but its more of a UI policy issue
2318 if (route == _master_out) {
2319 _master_out = shared_ptr<Route> ();
2322 if (route == _control_out) {
2324 /* cancel control outs for all routes */
2326 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2327 (*r)->drop_listen (_control_out);
2330 _control_out.reset ();
2333 update_route_solo_state ();
2335 /* writer goes out of scope, forces route list update */
2338 boost::shared_ptr<Track> t;
2339 boost::shared_ptr<Diskstream> ds;
2341 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2342 ds = t->diskstream();
2348 RCUWriter<DiskstreamList> dsl (diskstreams);
2349 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2354 find_current_end ();
2356 // We need to disconnect the routes inputs and outputs
2358 route->input()->disconnect (0);
2359 route->output()->disconnect (0);
2361 update_latency_compensation (false, false);
2364 /* get rid of it from the dead wood collection in the route list manager */
2366 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2370 /* try to cause everyone to drop their references */
2372 route->drop_references ();
2374 sync_order_keys (N_("session"));
2376 /* save the new state of the world */
2378 if (save_state (_current_snapshot_name)) {
2379 save_history (_current_snapshot_name);
2384 Session::route_mute_changed (void* /*src*/)
2390 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2392 boost::shared_ptr<Route> route = wpr.lock();
2394 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2398 if (route->listening()) {
2400 } else if (_listen_cnt > 0) {
2406 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2408 if (solo_update_disabled) {
2413 boost::shared_ptr<Route> route = wpr.lock ();
2416 /* should not happen */
2417 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2421 shared_ptr<RouteList> r = routes.reader ();
2424 if (route->soloed()) {
2430 /* now mod the solo level of all other routes except master & control outs
2431 so that they will be silent if appropriate.
2434 solo_update_disabled = true;
2435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2437 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2439 (*i)->mod_solo_level (delta);
2443 /* make sure master is never muted by solo */
2445 if (_master_out && route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2446 _master_out->mod_solo_level (1);
2449 /* ditto for control outs make sure master is never muted by solo */
2451 if (_control_out && route != _control_out && _control_out && _control_out->solo_level() == 0) {
2452 _control_out->mod_solo_level (1);
2455 solo_update_disabled = false;
2456 update_route_solo_state (r);
2457 SoloChanged (); /* EMIT SIGNAL */
2462 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2464 /* now figure out if anything that matters is soloed */
2466 bool something_soloed = false;
2469 r = routes.reader();
2472 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2473 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2474 something_soloed = true;
2479 if (something_soloed != _non_soloed_outs_muted) {
2480 _non_soloed_outs_muted = something_soloed;
2481 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2486 Session::route_by_name (string name)
2488 shared_ptr<RouteList> r = routes.reader ();
2490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2491 if ((*i)->name() == name) {
2496 return shared_ptr<Route> ((Route*) 0);
2500 Session::route_by_id (PBD::ID id)
2502 shared_ptr<RouteList> r = routes.reader ();
2504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2505 if ((*i)->id() == id) {
2510 return shared_ptr<Route> ((Route*) 0);
2514 Session::route_by_remote_id (uint32_t id)
2516 shared_ptr<RouteList> r = routes.reader ();
2518 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2519 if ((*i)->remote_control_id() == id) {
2524 return shared_ptr<Route> ((Route*) 0);
2528 Session::find_current_end ()
2530 if (_state_of_the_state & Loading) {
2534 nframes_t max = get_maximum_extent ();
2536 if (max > end_location->end()) {
2537 end_location->set_end (max);
2539 DurationChanged(); /* EMIT SIGNAL */
2544 Session::get_maximum_extent () const
2549 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2551 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2552 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2554 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2555 if ((me = pl->get_maximum_extent()) > max) {
2563 boost::shared_ptr<Diskstream>
2564 Session::diskstream_by_name (string name)
2566 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2568 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2569 if ((*i)->name() == name) {
2574 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2577 boost::shared_ptr<Diskstream>
2578 Session::diskstream_by_id (const PBD::ID& id)
2580 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2582 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2583 if ((*i)->id() == id) {
2588 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2591 /* Region management */
2594 Session::new_region_name (string old)
2596 string::size_type last_period;
2598 string::size_type len = old.length() + 64;
2601 if ((last_period = old.find_last_of ('.')) == string::npos) {
2603 /* no period present - add one explicitly */
2606 last_period = old.length() - 1;
2611 number = atoi (old.substr (last_period+1).c_str());
2615 while (number < (UINT_MAX-1)) {
2617 RegionList::const_iterator i;
2622 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2625 for (i = regions.begin(); i != regions.end(); ++i) {
2626 if (i->second->name() == sbuf) {
2631 if (i == regions.end()) {
2636 if (number != (UINT_MAX-1)) {
2640 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2645 Session::region_name (string& result, string base, bool newlevel)
2650 if (base.find("/") != string::npos) {
2651 base = base.substr(base.find_last_of("/") + 1);
2656 Glib::Mutex::Lock lm (region_lock);
2658 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2667 string::size_type pos;
2669 pos = base.find_last_of ('.');
2671 /* pos may be npos, but then we just use entire base */
2673 subbase = base.substr (0, pos);
2678 Glib::Mutex::Lock lm (region_lock);
2680 map<string,uint32_t>::iterator x;
2684 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2686 region_name_map[subbase] = 1;
2689 snprintf (buf, sizeof (buf), ".%d", x->second);
2700 Session::add_region (boost::shared_ptr<Region> region)
2702 vector<boost::shared_ptr<Region> > v;
2703 v.push_back (region);
2708 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2713 Glib::Mutex::Lock lm (region_lock);
2715 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2717 boost::shared_ptr<Region> region = *ii;
2721 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2725 RegionList::iterator x;
2727 for (x = regions.begin(); x != regions.end(); ++x) {
2729 if (region->region_list_equivalent (x->second)) {
2734 if (x == regions.end()) {
2736 pair<RegionList::key_type,RegionList::mapped_type> entry;
2738 entry.first = region->id();
2739 entry.second = region;
2741 pair<RegionList::iterator,bool> x = regions.insert (entry);
2753 /* mark dirty because something has changed even if we didn't
2754 add the region to the region list.
2761 vector<boost::weak_ptr<Region> > v;
2762 boost::shared_ptr<Region> first_r;
2764 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2766 boost::shared_ptr<Region> region = *ii;
2770 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2773 v.push_back (region);
2780 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2781 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2783 update_region_name_map (region);
2787 RegionsAdded (v); /* EMIT SIGNAL */
2793 Session::update_region_name_map (boost::shared_ptr<Region> region)
2795 string::size_type last_period = region->name().find_last_of ('.');
2797 if (last_period != string::npos && last_period < region->name().length() - 1) {
2799 string base = region->name().substr (0, last_period);
2800 string number = region->name().substr (last_period+1);
2801 map<string,uint32_t>::iterator x;
2803 /* note that if there is no number, we get zero from atoi,
2807 region_name_map[base] = atoi (number);
2812 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2814 boost::shared_ptr<Region> region (weak_region.lock ());
2820 if (what_changed & Region::HiddenChanged) {
2821 /* relay hidden changes */
2822 RegionHiddenChange (region);
2825 if (what_changed & NameChanged) {
2826 update_region_name_map (region);
2831 Session::remove_region (boost::weak_ptr<Region> weak_region)
2833 RegionList::iterator i;
2834 boost::shared_ptr<Region> region (weak_region.lock ());
2840 bool removed = false;
2843 Glib::Mutex::Lock lm (region_lock);
2845 if ((i = regions.find (region->id())) != regions.end()) {
2851 /* mark dirty because something has changed even if we didn't
2852 remove the region from the region list.
2858 RegionRemoved(region); /* EMIT SIGNAL */
2862 boost::shared_ptr<Region>
2863 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2865 RegionList::iterator i;
2866 boost::shared_ptr<Region> region;
2868 Glib::Mutex::Lock lm (region_lock);
2870 for (i = regions.begin(); i != regions.end(); ++i) {
2874 if (region->whole_file()) {
2876 if (child->source_equivalent (region)) {
2882 return boost::shared_ptr<Region> ();
2886 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2888 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2889 (*i)->get_region_list_equivalent_regions (region, result);
2893 Session::destroy_region (boost::shared_ptr<Region> region)
2895 vector<boost::shared_ptr<Source> > srcs;
2898 if (region->playlist()) {
2899 region->playlist()->destroy_region (region);
2902 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2903 srcs.push_back (region->source (n));
2907 region->drop_references ();
2909 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2911 (*i)->mark_for_remove ();
2912 (*i)->drop_references ();
2914 cerr << "source was not used by any playlist\n";
2921 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2923 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2924 destroy_region (*i);
2930 Session::remove_last_capture ()
2932 list<boost::shared_ptr<Region> > r;
2934 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2936 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2937 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2940 r.insert (r.end(), l.begin(), l.end());
2945 destroy_regions (r);
2947 save_state (_current_snapshot_name);
2953 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2959 /* Source Management */
2962 Session::add_source (boost::shared_ptr<Source> source)
2964 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2965 pair<SourceMap::iterator,bool> result;
2967 entry.first = source->id();
2968 entry.second = source;
2971 Glib::Mutex::Lock lm (source_lock);
2972 result = sources.insert (entry);
2975 if (result.second) {
2976 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2980 boost::shared_ptr<AudioFileSource> afs;
2982 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2983 if (Config->get_auto_analyse_audio()) {
2984 Analyser::queue_source_for_analysis (source, false);
2990 Session::remove_source (boost::weak_ptr<Source> src)
2992 SourceMap::iterator i;
2993 boost::shared_ptr<Source> source = src.lock();
3000 Glib::Mutex::Lock lm (source_lock);
3002 if ((i = sources.find (source->id())) != sources.end()) {
3007 if (!_state_of_the_state & InCleanup) {
3009 /* save state so we don't end up with a session file
3010 referring to non-existent sources.
3013 save_state (_current_snapshot_name);
3017 /** Return the number of playlists (not regions) that contain @a src */
3019 Session::source_use_count (boost::shared_ptr<const Source> src) const
3022 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3023 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3024 r != (*p)->region_list().end(); ++r) {
3025 if ((*r)->uses_source(src)) {
3034 boost::shared_ptr<Source>
3035 Session::source_by_id (const PBD::ID& id)
3037 Glib::Mutex::Lock lm (source_lock);
3038 SourceMap::iterator i;
3039 boost::shared_ptr<Source> source;
3041 if ((i = sources.find (id)) != sources.end()) {
3048 boost::shared_ptr<Source>
3049 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3051 Glib::Mutex::Lock lm (source_lock);
3053 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3054 cerr << "comparing " << path << " with " << i->second->name() << endl;
3055 boost::shared_ptr<AudioFileSource> afs
3056 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3058 if (afs && afs->path() == path && chn == afs->channel()) {
3062 return boost::shared_ptr<Source>();
3067 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3070 string old_basename = PBD::basename_nosuffix (oldname);
3071 string new_legalized = legalize_for_path (newname);
3073 /* note: we know (or assume) the old path is already valid */
3077 /* destructive file sources have a name of the form:
3079 /path/to/Tnnnn-NAME(%[LR])?.wav
3081 the task here is to replace NAME with the new name.
3084 /* find last slash */
3088 string::size_type slash;
3089 string::size_type dash;
3091 if ((slash = path.find_last_of ('/')) == string::npos) {
3095 dir = path.substr (0, slash+1);
3097 /* '-' is not a legal character for the NAME part of the path */
3099 if ((dash = path.find_last_of ('-')) == string::npos) {
3103 prefix = path.substr (slash+1, dash-(slash+1));
3108 path += new_legalized;
3109 path += ".wav"; /* XXX gag me with a spoon */
3113 /* non-destructive file sources have a name of the form:
3115 /path/to/NAME-nnnnn(%[LR])?.ext
3117 the task here is to replace NAME with the new name.
3122 string::size_type slash;
3123 string::size_type dash;
3124 string::size_type postfix;
3126 /* find last slash */
3128 if ((slash = path.find_last_of ('/')) == string::npos) {
3132 dir = path.substr (0, slash+1);
3134 /* '-' is not a legal character for the NAME part of the path */
3136 if ((dash = path.find_last_of ('-')) == string::npos) {
3140 suffix = path.substr (dash+1);
3142 // Suffix is now everything after the dash. Now we need to eliminate
3143 // the nnnnn part, which is done by either finding a '%' or a '.'
3145 postfix = suffix.find_last_of ("%");
3146 if (postfix == string::npos) {
3147 postfix = suffix.find_last_of ('.');
3150 if (postfix != string::npos) {
3151 suffix = suffix.substr (postfix);
3153 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3157 const uint32_t limit = 10000;
3158 char buf[PATH_MAX+1];
3160 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3162 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3164 if (access (buf, F_OK) != 0) {
3172 error << "FATAL ERROR! Could not find a " << endl;
3180 /** Return the full path (in some session directory) for a new embedded source.
3181 * \a name must be a session-unique name that does not contain slashes
3182 * (e.g. as returned by new_*_source_name)
3185 Session::new_source_path_from_name (DataType type, const string& name)
3187 assert(name.find("/") == string::npos);
3189 SessionDirectory sdir(get_best_session_directory_for_new_source());
3192 if (type == DataType::AUDIO) {
3193 p = sdir.sound_path();
3194 } else if (type == DataType::MIDI) {
3195 p = sdir.midi_path();
3197 error << "Unknown source type, unable to create file path" << endmsg;
3202 return p.to_string();
3206 Session::peak_path (Glib::ustring base) const
3208 sys::path peakfile_path(_session_dir->peak_path());
3209 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3210 return peakfile_path.to_string();
3213 /** Return a unique name based on \a base for a new internal audio source */
3215 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3219 char buf[PATH_MAX+1];
3220 const uint32_t limit = 10000;
3224 legalized = legalize_for_path (base);
3226 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3227 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3229 vector<space_and_path>::iterator i;
3230 uint32_t existing = 0;
3232 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3234 SessionDirectory sdir((*i).path);
3236 spath = sdir.sound_path().to_string();
3241 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3242 spath.c_str(), cnt, legalized.c_str());
3243 } else if (nchan == 2) {
3245 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3246 spath.c_str(), cnt, legalized.c_str());
3248 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3249 spath.c_str(), cnt, legalized.c_str());
3251 } else if (nchan < 26) {
3252 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3253 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3255 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3256 spath.c_str(), cnt, legalized.c_str());
3265 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3266 } else if (nchan == 2) {
3268 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3270 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3272 } else if (nchan < 26) {
3273 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3275 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3279 if (sys::exists(buf)) {
3285 if (existing == 0) {
3290 error << string_compose(
3291 _("There are already %1 recordings for %2, which I consider too many."),
3292 limit, base) << endmsg;
3294 throw failed_constructor();
3298 return Glib::path_get_basename(buf);
3301 /** Create a new embedded audio source */
3302 boost::shared_ptr<AudioFileSource>
3303 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3305 const size_t n_chans = ds.n_channels().n_audio();
3306 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3307 const string path = new_source_path_from_name(DataType::AUDIO, name);
3308 return boost::dynamic_pointer_cast<AudioFileSource> (
3309 SourceFactory::createWritable (
3310 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3313 /** Return a unique name based on \a base for a new internal MIDI source */
3315 Session::new_midi_source_name (const string& base)
3318 char buf[PATH_MAX+1];
3319 const uint32_t limit = 10000;
3323 legalized = legalize_for_path (base);
3325 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3326 for (cnt = 1; cnt <= limit; ++cnt) {
3328 vector<space_and_path>::iterator i;
3329 uint32_t existing = 0;
3331 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3333 SessionDirectory sdir((*i).path);
3335 sys::path p = sdir.midi_path();
3338 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3340 if (sys::exists (buf)) {
3345 if (existing == 0) {
3350 error << string_compose(
3351 _("There are already %1 recordings for %2, which I consider too many."),
3352 limit, base) << endmsg;
3354 throw failed_constructor();
3358 return Glib::path_get_basename(buf);
3362 /** Create a new embedded MIDI source */
3363 boost::shared_ptr<MidiSource>
3364 Session::create_midi_source_for_session (MidiDiskstream& ds)
3366 const string name = new_midi_source_name (ds.name());
3367 const string path = new_source_path_from_name (DataType::MIDI, name);
3369 return boost::dynamic_pointer_cast<SMFSource> (
3370 SourceFactory::createWritable (
3371 DataType::MIDI, *this, path, true, false, frame_rate()));
3375 /* Playlist management */
3377 boost::shared_ptr<Playlist>
3378 Session::playlist_by_name (string name)
3380 Glib::Mutex::Lock lm (playlist_lock);
3381 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3382 if ((*i)->name() == name) {
3386 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3387 if ((*i)->name() == name) {
3392 return boost::shared_ptr<Playlist>();
3396 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3398 Glib::Mutex::Lock lm (playlist_lock);
3399 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3400 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3401 list.push_back (*i);
3404 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3405 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3406 list.push_back (*i);
3412 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3414 if (playlist->hidden()) {
3419 Glib::Mutex::Lock lm (playlist_lock);
3420 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3421 playlists.insert (playlists.begin(), playlist);
3422 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3423 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3428 playlist->release();
3433 PlaylistAdded (playlist); /* EMIT SIGNAL */
3437 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3440 Glib::Mutex::Lock lm (playlist_lock);
3441 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3444 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3451 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3453 boost::shared_ptr<Playlist> pl(wpl.lock());
3459 PlaylistList::iterator x;
3462 /* its not supposed to be visible */
3467 Glib::Mutex::Lock lm (playlist_lock);
3471 unused_playlists.insert (pl);
3473 if ((x = playlists.find (pl)) != playlists.end()) {
3474 playlists.erase (x);
3480 playlists.insert (pl);
3482 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3483 unused_playlists.erase (x);
3490 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3492 if (_state_of_the_state & Deletion) {
3496 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3503 Glib::Mutex::Lock lm (playlist_lock);
3505 PlaylistList::iterator i;
3507 i = find (playlists.begin(), playlists.end(), playlist);
3508 if (i != playlists.end()) {
3509 playlists.erase (i);
3512 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3513 if (i != unused_playlists.end()) {
3514 unused_playlists.erase (i);
3521 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3525 Session::set_audition (boost::shared_ptr<Region> r)
3527 pending_audition_region = r;
3528 add_post_transport_work (PostTransportAudition);
3529 _butler->schedule_transport_work ();
3533 Session::audition_playlist ()
3535 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3536 ev->region.reset ();
3541 Session::non_realtime_set_audition ()
3543 if (!pending_audition_region) {
3544 auditioner->audition_current_playlist ();
3546 auditioner->audition_region (pending_audition_region);
3547 pending_audition_region.reset ();
3549 AuditionActive (true); /* EMIT SIGNAL */
3553 Session::audition_region (boost::shared_ptr<Region> r)
3555 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3561 Session::cancel_audition ()
3563 if (auditioner->active()) {
3564 auditioner->cancel_audition ();
3565 AuditionActive (false); /* EMIT SIGNAL */
3570 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3572 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3576 Session::remove_empty_sounds ()
3578 vector<string> audio_filenames;
3580 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3582 Glib::Mutex::Lock lm (source_lock);
3584 TapeFileMatcher tape_file_matcher;
3586 remove_if (audio_filenames.begin(), audio_filenames.end(),
3587 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3589 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3591 sys::path audio_file_path (_session_dir->sound_path());
3593 audio_file_path /= *i;
3595 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3599 sys::remove (audio_file_path);
3600 const string peakfile = peak_path (audio_file_path.to_string());
3601 sys::remove (peakfile);
3603 catch (const sys::filesystem_error& err)
3605 error << err.what() << endmsg;
3612 Session::is_auditioning () const
3614 /* can be called before we have an auditioner object */
3616 return auditioner->active();
3623 Session::set_all_solo (bool yn)
3625 shared_ptr<RouteList> r = routes.reader ();
3627 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3628 if (!(*i)->is_hidden()) {
3629 (*i)->set_solo (yn, this);
3637 Session::set_all_listen (bool yn)
3639 shared_ptr<RouteList> r = routes.reader ();
3641 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3642 if (!(*i)->is_hidden()) {
3643 (*i)->set_listen (yn, this);
3651 Session::set_all_mute (bool yn)
3653 shared_ptr<RouteList> r = routes.reader ();
3655 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3656 if (!(*i)->is_hidden()) {
3657 (*i)->set_mute (yn, this);
3665 Session::n_diskstreams () const
3669 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3671 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3672 if (!(*i)->hidden()) {
3680 Session::graph_reordered ()
3682 /* don't do this stuff if we are setting up connections
3683 from a set_state() call or creating new tracks.
3686 if (_state_of_the_state & InitialConnecting) {
3690 /* every track/bus asked for this to be handled but it was deferred because
3691 we were connecting. do it now.
3694 request_input_change_handling ();
3698 /* force all diskstreams to update their capture offset values to
3699 reflect any changes in latencies within the graph.
3702 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3704 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3705 (*i)->set_capture_offset ();
3710 Session::record_disenable_all ()
3712 record_enable_change_all (false);
3716 Session::record_enable_all ()
3718 record_enable_change_all (true);
3722 Session::record_enable_change_all (bool yn)
3724 shared_ptr<RouteList> r = routes.reader ();
3726 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3727 boost::shared_ptr<Track> t;
3729 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3730 t->set_record_enable (yn, this);
3734 /* since we don't keep rec-enable state, don't mark session dirty */
3738 Session::add_processor (Processor* processor)
3740 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3745 Session::remove_processor (Processor* processor)
3749 PortInsert* port_insert;
3751 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3752 insert_bitset[port_insert->bit_slot()] = false;
3753 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3754 send_bitset[send->bit_slot()] = false;
3755 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3756 return_bitset[send->bit_slot()] = false;
3763 Session::available_capture_duration ()
3765 float sample_bytes_on_disk = 4.0; // keep gcc happy
3767 switch (config.get_native_file_data_format()) {
3769 sample_bytes_on_disk = 4.0;
3773 sample_bytes_on_disk = 3.0;
3777 sample_bytes_on_disk = 2.0;
3781 /* impossible, but keep some gcc versions happy */
3782 fatal << string_compose (_("programming error: %1"),
3783 X_("illegal native file data format"))
3788 double scale = 4096.0 / sample_bytes_on_disk;
3790 if (_total_free_4k_blocks * scale > (double) max_frames) {
3794 return (nframes_t) floor (_total_free_4k_blocks * scale);
3798 Session::add_bundle (shared_ptr<Bundle> bundle)
3801 RCUWriter<BundleList> writer (_bundles);
3802 boost::shared_ptr<BundleList> b = writer.get_copy ();
3803 b->push_back (bundle);
3806 BundleAdded (bundle); /* EMIT SIGNAL */
3812 Session::remove_bundle (shared_ptr<Bundle> bundle)
3814 bool removed = false;
3817 RCUWriter<BundleList> writer (_bundles);
3818 boost::shared_ptr<BundleList> b = writer.get_copy ();
3819 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3821 if (i != b->end()) {
3828 BundleRemoved (bundle); /* EMIT SIGNAL */
3835 Session::bundle_by_name (string name) const
3837 boost::shared_ptr<BundleList> b = _bundles.reader ();
3839 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3840 if ((*i)->name() == name) {
3845 return boost::shared_ptr<Bundle> ();
3849 Session::tempo_map_changed (Change)
3853 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3854 (*i)->update_after_tempo_map_change ();
3857 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3858 (*i)->update_after_tempo_map_change ();
3864 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3865 * the given count with the current block size.
3868 Session::ensure_buffers (ChanCount howmany)
3870 if (current_block_size == 0) {
3871 return; // too early? (is this ok?)
3874 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3875 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3876 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3877 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3878 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3881 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3885 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3887 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3888 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3893 Session::next_insert_id ()
3895 /* this doesn't really loop forever. just think about it */
3898 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3899 if (!insert_bitset[n]) {
3900 insert_bitset[n] = true;
3906 /* none available, so resize and try again */
3908 insert_bitset.resize (insert_bitset.size() + 16, false);
3913 Session::next_send_id ()
3915 /* this doesn't really loop forever. just think about it */
3918 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3919 if (!send_bitset[n]) {
3920 send_bitset[n] = true;
3926 /* none available, so resize and try again */
3928 send_bitset.resize (send_bitset.size() + 16, false);
3933 Session::next_return_id ()
3935 /* this doesn't really loop forever. just think about it */
3938 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3939 if (!return_bitset[n]) {
3940 return_bitset[n] = true;
3946 /* none available, so resize and try again */
3948 return_bitset.resize (return_bitset.size() + 16, false);
3953 Session::mark_send_id (uint32_t id)
3955 if (id >= send_bitset.size()) {
3956 send_bitset.resize (id+16, false);
3958 if (send_bitset[id]) {
3959 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3961 send_bitset[id] = true;
3965 Session::mark_return_id (uint32_t id)
3967 if (id >= return_bitset.size()) {
3968 return_bitset.resize (id+16, false);
3970 if (return_bitset[id]) {
3971 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3973 return_bitset[id] = true;
3977 Session::mark_insert_id (uint32_t id)
3979 if (id >= insert_bitset.size()) {
3980 insert_bitset.resize (id+16, false);
3982 if (insert_bitset[id]) {
3983 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3985 insert_bitset[id] = true;
3988 /* Named Selection management */
3991 Session::named_selection_by_name (string name)
3993 Glib::Mutex::Lock lm (named_selection_lock);
3994 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3995 if ((*i)->name == name) {
4003 Session::add_named_selection (NamedSelection* named_selection)
4006 Glib::Mutex::Lock lm (named_selection_lock);
4007 named_selections.insert (named_selections.begin(), named_selection);
4010 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4016 NamedSelectionAdded (); /* EMIT SIGNAL */
4020 Session::remove_named_selection (NamedSelection* named_selection)
4022 bool removed = false;
4025 Glib::Mutex::Lock lm (named_selection_lock);
4027 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4029 if (i != named_selections.end()) {
4031 named_selections.erase (i);
4038 NamedSelectionRemoved (); /* EMIT SIGNAL */
4043 Session::reset_native_file_format ()
4045 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4047 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4048 (*i)->reset_write_sources (false);
4053 Session::route_name_unique (string n) const
4055 shared_ptr<RouteList> r = routes.reader ();
4057 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4058 if ((*i)->name() == n) {
4067 Session::route_name_internal (string n) const
4069 if (auditioner && auditioner->name() == n) {
4073 if (_click_io && _click_io->name() == n) {
4081 Session::n_playlists () const
4083 Glib::Mutex::Lock lm (playlist_lock);
4084 return playlists.size();
4088 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4090 if (!force && howmany <= _npan_buffers) {
4094 if (_pan_automation_buffer) {
4096 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4097 delete [] _pan_automation_buffer[i];
4100 delete [] _pan_automation_buffer;
4103 _pan_automation_buffer = new pan_t*[howmany];
4105 for (uint32_t i = 0; i < howmany; ++i) {
4106 _pan_automation_buffer[i] = new pan_t[nframes];
4109 _npan_buffers = howmany;
4113 Session::freeze (InterThreadInfo& itt)
4115 shared_ptr<RouteList> r = routes.reader ();
4117 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4119 boost::shared_ptr<Track> t;
4121 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4122 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4132 boost::shared_ptr<Region>
4133 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4134 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4135 InterThreadInfo& itt, bool enable_processing)
4137 boost::shared_ptr<Region> result;
4138 boost::shared_ptr<Playlist> playlist;
4139 boost::shared_ptr<AudioFileSource> fsource;
4141 char buf[PATH_MAX+1];
4142 ChanCount nchans(track.audio_diskstream()->n_channels());
4144 nframes_t this_chunk;
4147 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4148 const string sound_dir = sdir.sound_path().to_string();
4149 nframes_t len = end - start;
4152 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4153 end, start) << endmsg;
4157 // any bigger than this seems to cause stack overflows in called functions
4158 const nframes_t chunk_size = (128 * 1024)/4;
4160 // block all process callback handling
4162 block_processing ();
4164 /* call tree *MUST* hold route_lock */
4166 if ((playlist = track.diskstream()->playlist()) == 0) {
4170 /* external redirects will be a problem */
4172 if (track.has_external_redirects()) {
4176 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4178 for (x = 0; x < 99999; ++x) {
4179 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4180 if (access (buf, F_OK) != 0) {
4186 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4191 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4192 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4195 catch (failed_constructor& err) {
4196 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4200 srcs.push_back (fsource);
4203 /* XXX need to flush all redirects */
4208 /* create a set of reasonably-sized buffers */
4209 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4210 buffers.set_count(nchans);
4212 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4213 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4215 afs->prepare_for_peakfile_writes ();
4218 while (to_do && !itt.cancel) {
4220 this_chunk = min (to_do, chunk_size);
4222 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4227 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4228 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4231 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4237 start += this_chunk;
4238 to_do -= this_chunk;
4240 itt.progress = (float) (1.0 - ((double) to_do / len));
4249 xnow = localtime (&now);
4251 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4252 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4255 afs->update_header (position, *xnow, now);
4256 afs->flush_header ();
4260 /* construct a region to represent the bounced material */
4262 result = RegionFactory::create (srcs, 0,
4263 srcs.front()->length(srcs.front()->timeline_position()),
4264 region_name_from_path (srcs.front()->name(), true));
4269 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4270 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4273 afs->mark_for_remove ();
4276 (*src)->drop_references ();
4280 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4281 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4284 afs->done_with_peakfile_writes ();
4288 unblock_processing ();
4294 Session::get_silent_buffers (ChanCount count)
4296 assert(_silent_buffers->available() >= count);
4297 _silent_buffers->set_count(count);
4299 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4300 for (size_t i= 0; i < count.get(*t); ++i) {
4301 _silent_buffers->get(*t, i).clear();
4305 return *_silent_buffers;
4309 Session::get_scratch_buffers (ChanCount count)
4311 if (count != ChanCount::ZERO) {
4312 assert(_scratch_buffers->available() >= count);
4313 _scratch_buffers->set_count(count);
4315 _scratch_buffers->set_count (_scratch_buffers->available());
4318 return *_scratch_buffers;
4322 Session::get_mix_buffers (ChanCount count)
4324 assert(_mix_buffers->available() >= count);
4325 _mix_buffers->set_count(count);
4326 return *_mix_buffers;
4330 Session::ntracks () const
4333 shared_ptr<RouteList> r = routes.reader ();
4335 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4336 if (boost::dynamic_pointer_cast<Track> (*i)) {
4345 Session::nbusses () const
4348 shared_ptr<RouteList> r = routes.reader ();
4350 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4351 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4360 Session::add_automation_list(AutomationList *al)
4362 automation_lists[al->id()] = al;
4366 Session::compute_initial_length ()
4368 return _engine.frame_rate() * 60 * 5;
4372 Session::sync_order_keys (std::string const & base)
4374 if (!Config->get_sync_all_route_ordering()) {
4375 /* leave order keys as they are */
4379 boost::shared_ptr<RouteList> r = routes.reader ();
4381 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4382 (*i)->sync_order_keys (base);
4385 Route::SyncOrderKeys (base); // EMIT SIGNAL
4389 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4391 Session::have_rec_enabled_diskstream () const
4393 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4396 /** Update the state of our rec-enabled diskstreams flag */
4398 Session::update_have_rec_enabled_diskstream ()
4400 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4401 DiskstreamList::iterator i = dsl->begin ();
4402 while (i != dsl->end () && (*i)->record_enabled () == false) {
4406 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4408 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4410 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4411 RecordStateChanged (); /* EMIT SIGNAL */
4416 Session::listen_position_changed ()
4420 switch (Config->get_listen_position()) {
4421 case AfterFaderListen:
4425 case PreFaderListen:
4430 boost::shared_ptr<RouteList> r = routes.reader ();
4432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4433 (*i)->put_control_outs_at (p);
4438 Session::solo_control_mode_changed ()
4440 /* cancel all solo or all listen when solo control mode changes */
4442 if (Config->get_solo_control_is_listen_control()) {
4443 set_all_solo (false);
4445 set_all_listen (false);
4450 Session::route_group_changed ()
4452 RouteGroupChanged (); /* EMIT SIGNAL */
4456 Session::get_available_sync_options () const
4458 vector<SyncSource> ret;
4460 ret.push_back (JACK);
4463 ret.push_back (MTC);
4466 if (midi_clock_port()) {
4467 ret.push_back (MIDIClock);