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/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/filename_extensions.h"
65 #include "ardour/internal_send.h"
66 #include "ardour/io_processor.h"
67 #include "ardour/midi_diskstream.h"
68 #include "ardour/midi_playlist.h"
69 #include "ardour/midi_region.h"
70 #include "ardour/midi_track.h"
71 #include "ardour/named_selection.h"
72 #include "ardour/playlist.h"
73 #include "ardour/plugin_insert.h"
74 #include "ardour/port_insert.h"
75 #include "ardour/processor.h"
76 #include "ardour/recent_sessions.h"
77 #include "ardour/region_factory.h"
78 #include "ardour/return.h"
79 #include "ardour/route_group.h"
80 #include "ardour/send.h"
81 #include "ardour/session.h"
82 #include "ardour/session_directory.h"
83 #include "ardour/session_directory.h"
84 #include "ardour/session_metadata.h"
85 #include "ardour/slave.h"
86 #include "ardour/smf_source.h"
87 #include "ardour/source_factory.h"
88 #include "ardour/tape_file_matcher.h"
89 #include "ardour/tempo.h"
90 #include "ardour/utils.h"
95 using namespace ARDOUR;
97 using boost::shared_ptr;
99 bool Session::_disable_all_loaded_plugins = false;
101 sigc::signal<void,std::string> Session::Dialog;
102 sigc::signal<int> Session::AskAboutPendingState;
103 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
109 sigc::signal<void> Session::AutoBindingOn;
110 sigc::signal<void> Session::AutoBindingOff;
111 sigc::signal<void, std::string, std::string> Session::Exported;
113 Session::Session (AudioEngine &eng,
114 const string& fullpath,
115 const string& snapshot_name,
119 _target_transport_speed (0.0),
120 _requested_return_frame (-1),
121 _scratch_buffers(new BufferSet()),
122 _silent_buffers(new BufferSet()),
123 _mix_buffers(new BufferSet()),
125 _mmc_port (default_mmc_port),
126 _mtc_port (default_mtc_port),
127 _midi_port (default_midi_port),
128 _midi_clock_port (default_midi_clock_port),
129 _session_dir (new SessionDirectory(fullpath)),
130 pending_events (2048),
132 butler_mixdown_buffer (0),
133 butler_gain_buffer (0),
134 post_transport_work((PostTransportWork)0),
135 _send_smpte_update (false),
136 midi_thread (pthread_t (0)),
137 midi_requests (128), // the size of this should match the midi request pool size
138 diskstreams (new DiskstreamList),
139 routes (new RouteList),
140 _total_free_4k_blocks (0),
141 _bundles (new BundleList),
142 _bundle_xml_node (0),
145 click_emphasis_data (0),
147 _metadata (new SessionMetadata()),
148 _have_rec_enabled_diskstream (false)
153 interpolation.add_channel_to (0, 0);
155 if (!eng.connected()) {
156 throw failed_constructor();
159 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
161 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
162 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
164 first_stage_init (fullpath, snapshot_name);
166 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
169 if (create (new_session, mix_template, compute_initial_length())) {
171 throw failed_constructor ();
175 if (second_stage_init (new_session)) {
177 throw failed_constructor ();
180 store_recent_sessions(_name, _path);
182 bool was_dirty = dirty();
184 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
186 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
187 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
190 DirtyChanged (); /* EMIT SIGNAL */
194 Session::Session (AudioEngine &eng,
196 string snapshot_name,
197 AutoConnectOption input_ac,
198 AutoConnectOption output_ac,
199 uint32_t control_out_channels,
200 uint32_t master_out_channels,
201 uint32_t requested_physical_in,
202 uint32_t requested_physical_out,
203 nframes_t initial_length)
206 _target_transport_speed (0.0),
207 _requested_return_frame (-1),
208 _scratch_buffers(new BufferSet()),
209 _silent_buffers(new BufferSet()),
210 _mix_buffers(new BufferSet()),
212 _mmc_port (default_mmc_port),
213 _mtc_port (default_mtc_port),
214 _midi_port (default_midi_port),
215 _midi_clock_port (default_midi_clock_port),
216 _session_dir ( new SessionDirectory(fullpath)),
217 pending_events (2048),
219 butler_mixdown_buffer (0),
220 butler_gain_buffer (0),
221 post_transport_work((PostTransportWork)0),
222 _send_smpte_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 terminate_butler_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 delete [] butler_mixdown_buffer;
492 delete [] butler_gain_buffer;
494 Crossfade::set_buffer_size (0);
500 Session::set_worst_io_latencies ()
502 _worst_output_latency = 0;
503 _worst_input_latency = 0;
505 if (!_engine.connected()) {
509 boost::shared_ptr<RouteList> r = routes.reader ();
511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
512 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
513 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
518 Session::when_engine_running ()
520 string first_physical_output;
522 BootMessage (_("Set block size and sample rate"));
524 set_block_size (_engine.frames_per_cycle());
525 set_frame_rate (_engine.frame_rate());
527 BootMessage (_("Using configuration"));
529 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
531 /* every time we reconnect, recompute worst case output latencies */
533 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
535 if (synced_to_jack()) {
536 _engine.transport_stop ();
539 if (config.get_jack_time_master()) {
540 _engine.transport_locate (_transport_frame);
548 _click_io.reset (new ClickIO (*this, "click"));
550 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
552 /* existing state for Click */
555 if (Stateful::loading_state_version < 3000) {
556 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
558 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
563 _clicking = Config->get_clicking ();
567 error << _("could not setup Click I/O") << endmsg;
574 /* default state for Click: dual-mono to first 2 physical outputs */
576 for (int physport = 0; physport < 2; ++physport) {
577 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
579 if (physical_output.length()) {
580 if (_click_io->add_port (physical_output, this)) {
581 // relax, even though its an error
586 if (_click_io->n_ports () > ChanCount::ZERO) {
587 _clicking = Config->get_clicking ();
592 catch (failed_constructor& err) {
593 error << _("cannot setup Click I/O") << endmsg;
596 BootMessage (_("Compute I/O Latencies"));
598 set_worst_io_latencies ();
601 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
604 BootMessage (_("Set up standard connections"));
606 /* Create a set of Bundle objects that map
607 to the physical I/O currently available. We create both
608 mono and stereo bundles, so that the common cases of mono
609 and stereo tracks get bundles to put in their mixer strip
610 in / out menus. There may be a nicer way of achieving that;
611 it doesn't really scale that well to higher channel counts
614 /* mono output bundles */
616 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
618 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
620 shared_ptr<Bundle> c (new Bundle (buf, true));
621 c->add_channel (_("mono"));
622 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
627 /* stereo output bundles */
629 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
630 if (np + 1 < n_physical_outputs) {
632 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
633 shared_ptr<Bundle> c (new Bundle (buf, true));
634 c->add_channel (_("L"));
635 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
636 c->add_channel (_("R"));
637 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
643 /* mono input bundles */
645 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
647 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
649 shared_ptr<Bundle> c (new Bundle (buf, false));
650 c->add_channel (_("mono"));
651 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
656 /* stereo input bundles */
658 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
659 if (np + 1 < n_physical_inputs) {
661 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
663 shared_ptr<Bundle> c (new Bundle (buf, false));
664 c->add_channel (_("L"));
665 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
666 c->add_channel (_("R"));
667 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
673 BootMessage (_("Setup signal flow and plugins"));
677 if (!no_auto_connect()) {
679 if (_master_out && Config->get_auto_connect_standard_busses()) {
681 /* if requested auto-connect the outputs to the first N physical ports.
684 uint32_t limit = _master_out->n_outputs().n_total();
686 for (uint32_t n = 0; n < limit; ++n) {
687 Port* p = _master_out->output()->nth (n);
688 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
690 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
691 if (_master_out->output()->connect (p, connect_to, this)) {
692 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
702 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
703 are undefined, at best.
706 /* control out listens to master bus (but ignores it
707 under some conditions)
710 uint32_t limit = _control_out->n_inputs().n_audio();
713 for (uint32_t n = 0; n < limit; ++n) {
714 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
715 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
718 string connect_to = o->name();
719 if (_control_out->input()->connect (p, connect_to, this)) {
720 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
728 /* if control out is not connected,
729 connect control out to physical outs, but use ones after the master if possible
732 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
734 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
736 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
739 _control_out->output()->connect_ports_to_bundle (b, this);
741 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
742 Config->get_monitor_bus_preferred_bundle())
748 /* XXX this logic is wrong for mixed port types */
750 uint32_t shift = _master_out->n_outputs().n_audio();
751 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
752 limit = _control_out->n_outputs().n_audio();
754 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
756 for (uint32_t n = 0; n < limit; ++n) {
758 Port* p = _control_out->output()->nth (n);
759 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
761 if (!connect_to.empty()) {
762 if (_control_out->output()->connect (p, connect_to, this)) {
763 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
774 /* catch up on send+insert cnts */
776 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
778 /* hook us up to the engine */
780 BootMessage (_("Connect to engine"));
782 _engine.set_session (this);
786 Session::hookup_io ()
788 /* stop graph reordering notifications from
789 causing resorts, etc.
792 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
797 /* we delay creating the auditioner till now because
798 it makes its own connections to ports.
799 the engine has to be running for this to work.
803 auditioner.reset (new Auditioner (*this));
806 catch (failed_constructor& err) {
807 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
811 /* load bundles, which we may have postponed earlier on */
812 if (_bundle_xml_node) {
813 load_bundles (*_bundle_xml_node);
814 delete _bundle_xml_node;
817 /* Tell all IO objects to connect themselves together */
819 IO::enable_connecting ();
821 /* Now reset all panners */
823 Delivery::reset_panners ();
825 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
829 boost::shared_ptr<RouteList> r = routes.reader ();
831 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
833 if ((*x)->is_control() || (*x)->is_master()) {
837 (*x)->listen_via (_control_out,
838 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
843 /* Anyone who cares about input state, wake up and do something */
845 IOConnectionsComplete (); /* EMIT SIGNAL */
847 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
849 /* now handle the whole enchilada as if it was one
855 /* update the full solo state, which can't be
856 correctly determined on a per-route basis, but
857 needs the global overview that only the session
861 update_route_solo_state ();
865 Session::playlist_length_changed ()
867 /* we can't just increase end_location->end() if pl->get_maximum_extent()
868 if larger. if the playlist used to be the longest playlist,
869 and its now shorter, we have to decrease end_location->end(). hence,
870 we have to iterate over all diskstreams and check the
871 playlists currently in use.
877 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
879 boost::shared_ptr<Playlist> playlist;
881 if ((playlist = dstream->playlist()) != 0) {
882 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
885 /* see comment in playlist_length_changed () */
890 Session::record_enabling_legal () const
892 /* this used to be in here, but survey says.... we don't need to restrict it */
893 // if (record_status() == Recording) {
897 if (Config->get_all_safe()) {
904 Session::reset_input_monitor_state ()
906 if (transport_rolling()) {
908 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
910 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
911 if ((*i)->record_enabled ()) {
912 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
913 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
917 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
919 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
920 if ((*i)->record_enabled ()) {
921 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
922 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
929 Session::auto_punch_start_changed (Location* location)
931 replace_event (Event::PunchIn, location->start());
933 if (get_record_enabled() && config.get_punch_in()) {
934 /* capture start has been changed, so save new pending state */
935 save_state ("", true);
940 Session::auto_punch_end_changed (Location* location)
942 nframes_t when_to_stop = location->end();
943 // when_to_stop += _worst_output_latency + _worst_input_latency;
944 replace_event (Event::PunchOut, when_to_stop);
948 Session::auto_punch_changed (Location* location)
950 nframes_t when_to_stop = location->end();
952 replace_event (Event::PunchIn, location->start());
953 //when_to_stop += _worst_output_latency + _worst_input_latency;
954 replace_event (Event::PunchOut, when_to_stop);
958 Session::auto_loop_changed (Location* location)
960 replace_event (Event::AutoLoop, location->end(), location->start());
962 if (transport_rolling() && play_loop) {
964 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
966 if (_transport_frame > location->end()) {
967 // relocate to beginning of loop
968 clear_events (Event::LocateRoll);
970 request_locate (location->start(), true);
973 else if (Config->get_seamless_loop() && !loop_changing) {
975 // schedule a locate-roll to refill the diskstreams at the
977 loop_changing = true;
979 if (location->end() > last_loopend) {
980 clear_events (Event::LocateRoll);
981 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
988 last_loopend = location->end();
992 Session::set_auto_punch_location (Location* location)
996 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
997 auto_punch_start_changed_connection.disconnect();
998 auto_punch_end_changed_connection.disconnect();
999 auto_punch_changed_connection.disconnect();
1000 existing->set_auto_punch (false, this);
1001 remove_event (existing->start(), Event::PunchIn);
1002 clear_events (Event::PunchOut);
1003 auto_punch_location_changed (0);
1008 if (location == 0) {
1012 if (location->end() <= location->start()) {
1013 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1017 auto_punch_start_changed_connection.disconnect();
1018 auto_punch_end_changed_connection.disconnect();
1019 auto_punch_changed_connection.disconnect();
1021 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1022 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1023 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1025 location->set_auto_punch (true, this);
1028 auto_punch_changed (location);
1030 auto_punch_location_changed (location);
1034 Session::set_auto_loop_location (Location* location)
1038 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1039 auto_loop_start_changed_connection.disconnect();
1040 auto_loop_end_changed_connection.disconnect();
1041 auto_loop_changed_connection.disconnect();
1042 existing->set_auto_loop (false, this);
1043 remove_event (existing->end(), Event::AutoLoop);
1044 auto_loop_location_changed (0);
1049 if (location == 0) {
1053 if (location->end() <= location->start()) {
1054 error << _("Session: you can't use a mark for auto loop") << endmsg;
1058 last_loopend = location->end();
1060 auto_loop_start_changed_connection.disconnect();
1061 auto_loop_end_changed_connection.disconnect();
1062 auto_loop_changed_connection.disconnect();
1064 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1065 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1066 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1068 location->set_auto_loop (true, this);
1070 /* take care of our stuff first */
1072 auto_loop_changed (location);
1074 /* now tell everyone else */
1076 auto_loop_location_changed (location);
1080 Session::locations_added (Location *)
1086 Session::locations_changed ()
1088 _locations.apply (*this, &Session::handle_locations_changed);
1092 Session::handle_locations_changed (Locations::LocationList& locations)
1094 Locations::LocationList::iterator i;
1096 bool set_loop = false;
1097 bool set_punch = false;
1099 for (i = locations.begin(); i != locations.end(); ++i) {
1103 if (location->is_auto_punch()) {
1104 set_auto_punch_location (location);
1107 if (location->is_auto_loop()) {
1108 set_auto_loop_location (location);
1112 if (location->is_start()) {
1113 start_location = location;
1115 if (location->is_end()) {
1116 end_location = location;
1121 set_auto_loop_location (0);
1124 set_auto_punch_location (0);
1131 Session::enable_record ()
1133 /* XXX really atomic compare+swap here */
1134 if (g_atomic_int_get (&_record_status) != Recording) {
1135 g_atomic_int_set (&_record_status, Recording);
1136 _last_record_location = _transport_frame;
1137 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1139 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1140 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1141 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1142 if ((*i)->record_enabled ()) {
1143 (*i)->monitor_input (true);
1148 RecordStateChanged ();
1153 Session::disable_record (bool rt_context, bool force)
1157 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1159 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1160 g_atomic_int_set (&_record_status, Disabled);
1162 if (rs == Recording) {
1163 g_atomic_int_set (&_record_status, Enabled);
1167 // FIXME: timestamp correct? [DR]
1168 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1169 // does this /need/ to be sent in all cases?
1171 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1173 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1174 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1176 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1177 if ((*i)->record_enabled ()) {
1178 (*i)->monitor_input (false);
1183 RecordStateChanged (); /* emit signal */
1186 remove_pending_capture_state ();
1192 Session::step_back_from_record ()
1194 /* XXX really atomic compare+swap here */
1195 if (g_atomic_int_get (&_record_status) == Recording) {
1196 g_atomic_int_set (&_record_status, Enabled);
1198 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1199 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1201 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1202 if ((*i)->record_enabled ()) {
1203 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1204 (*i)->monitor_input (false);
1212 Session::maybe_enable_record ()
1214 g_atomic_int_set (&_record_status, Enabled);
1216 /* this function is currently called from somewhere other than an RT thread.
1217 this save_state() call therefore doesn't impact anything.
1220 save_state ("", true);
1222 if (_transport_speed) {
1223 if (!config.get_punch_in()) {
1227 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1228 RecordStateChanged (); /* EMIT SIGNAL */
1235 Session::audible_frame () const
1241 /* the first of these two possible settings for "offset"
1242 mean that the audible frame is stationary until
1243 audio emerges from the latency compensation
1246 the second means that the audible frame is stationary
1247 until audio would emerge from a physical port
1248 in the absence of any plugin latency compensation
1251 offset = _worst_output_latency;
1253 if (offset > current_block_size) {
1254 offset -= current_block_size;
1256 /* XXX is this correct? if we have no external
1257 physical connections and everything is internal
1258 then surely this is zero? still, how
1259 likely is that anyway?
1261 offset = current_block_size;
1264 if (synced_to_jack()) {
1265 tf = _engine.transport_frame();
1267 tf = _transport_frame;
1272 if (!non_realtime_work_pending()) {
1276 /* check to see if we have passed the first guaranteed
1277 audible frame past our last start position. if not,
1278 return that last start point because in terms
1279 of audible frames, we have not moved yet.
1282 if (_transport_speed > 0.0f) {
1284 if (!play_loop || !have_looped) {
1285 if (tf < _last_roll_location + offset) {
1286 return _last_roll_location;
1294 } else if (_transport_speed < 0.0f) {
1296 /* XXX wot? no backward looping? */
1298 if (tf > _last_roll_location - offset) {
1299 return _last_roll_location;
1311 Session::set_frame_rate (nframes_t frames_per_second)
1313 /** \fn void Session::set_frame_size(nframes_t)
1314 the AudioEngine object that calls this guarantees
1315 that it will not be called while we are also in
1316 ::process(). Its fine to do things that block
1320 _base_frame_rate = frames_per_second;
1324 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1328 // XXX we need some equivalent to this, somehow
1329 // SndFileSource::setup_standard_crossfades (frames_per_second);
1333 /* XXX need to reset/reinstantiate all LADSPA plugins */
1337 Session::set_block_size (nframes_t nframes)
1339 /* the AudioEngine guarantees
1340 that it will not be called while we are also in
1341 ::process(). It is therefore fine to do things that block
1346 current_block_size = nframes;
1348 ensure_buffers(_scratch_buffers->available());
1350 delete [] _gain_automation_buffer;
1351 _gain_automation_buffer = new gain_t[nframes];
1353 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1355 boost::shared_ptr<RouteList> r = routes.reader ();
1357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1358 (*i)->set_block_size (nframes);
1361 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1362 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1363 (*i)->set_block_size (nframes);
1366 set_worst_io_latencies ();
1371 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1374 nframes_t fade_frames;
1376 /* Don't allow fade of less 1 frame */
1378 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1385 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1389 default_fade_msecs = fade_msecs;
1390 default_fade_steepness = steepness;
1393 // jlc, WTF is this!
1394 Glib::RWLock::ReaderLock lm (route_lock);
1395 AudioRegion::set_default_fade (steepness, fade_frames);
1400 /* XXX have to do this at some point */
1401 /* foreach region using default fade, reset, then
1402 refill_all_diskstream_buffers ();
1407 struct RouteSorter {
1408 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1409 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1411 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1414 if (r1->fed_by.empty()) {
1415 if (r2->fed_by.empty()) {
1416 /* no ardour-based connections inbound to either route. just use signal order */
1417 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1419 /* r2 has connections, r1 does not; run r1 early */
1423 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1430 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1432 shared_ptr<Route> r2;
1434 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1435 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1439 /* make a copy of the existing list of routes that feed r1 */
1441 set<shared_ptr<Route> > existing = r1->fed_by;
1443 /* for each route that feeds r1, recurse, marking it as feeding
1447 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1450 /* r2 is a route that feeds r1 which somehow feeds base. mark
1451 base as being fed by r2
1454 rbase->fed_by.insert (r2);
1458 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1462 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1466 /* now recurse, so that we can mark base as being fed by
1467 all routes that feed r2
1470 trace_terminal (r2, rbase);
1477 Session::resort_routes ()
1479 /* don't do anything here with signals emitted
1480 by Routes while we are being destroyed.
1483 if (_state_of_the_state & Deletion) {
1490 RCUWriter<RouteList> writer (routes);
1491 shared_ptr<RouteList> r = writer.get_copy ();
1492 resort_routes_using (r);
1493 /* writer goes out of scope and forces update */
1498 Session::resort_routes_using (shared_ptr<RouteList> r)
1500 RouteList::iterator i, j;
1502 for (i = r->begin(); i != r->end(); ++i) {
1504 (*i)->fed_by.clear ();
1506 for (j = r->begin(); j != r->end(); ++j) {
1508 /* although routes can feed themselves, it will
1509 cause an endless recursive descent if we
1510 detect it. so don't bother checking for
1518 if ((*j)->feeds (*i)) {
1519 (*i)->fed_by.insert (*j);
1524 for (i = r->begin(); i != r->end(); ++i) {
1525 trace_terminal (*i, *i);
1532 cerr << "finished route resort\n";
1534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1535 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1542 list<boost::shared_ptr<MidiTrack> >
1543 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1545 char track_name[32];
1546 uint32_t track_id = 0;
1549 RouteList new_routes;
1550 list<boost::shared_ptr<MidiTrack> > ret;
1551 //uint32_t control_id;
1553 // FIXME: need physical I/O and autoconnect stuff for MIDI
1555 /* count existing midi tracks */
1558 shared_ptr<RouteList> r = routes.reader ();
1560 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1561 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1562 if (!(*i)->is_hidden()) {
1564 //channels_used += (*i)->n_inputs().n_midi();
1570 vector<string> physinputs;
1571 vector<string> physoutputs;
1573 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1574 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1576 // control_id = ntracks() + nbusses();
1580 /* check for duplicate route names, since we might have pre-existing
1581 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1582 save, close,restart,add new route - first named route is now
1590 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1592 if (route_by_name (track_name) == 0) {
1596 } while (track_id < (UINT_MAX-1));
1598 shared_ptr<MidiTrack> track;
1601 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1603 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1604 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1609 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1610 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1616 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1620 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1621 port = physinputs[(channels_used+x)%nphysical_in];
1624 if (port.length() && track->connect_input (track->input (x), port, this)) {
1630 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1634 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1635 port = physoutputs[(channels_used+x)%nphysical_out];
1636 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1638 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1642 if (port.length() && track->connect_output (track->output (x), port, this)) {
1647 channels_used += track->n_inputs ().n_midi();
1651 track->midi_diskstream()->non_realtime_input_change();
1652 track->set_route_group (route_group, 0);
1654 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1655 //track->set_remote_control_id (control_id);
1657 new_routes.push_back (track);
1658 ret.push_back (track);
1661 catch (failed_constructor &err) {
1662 error << _("Session: could not create new midi track.") << endmsg;
1665 /* we need to get rid of this, since the track failed to be created */
1666 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1669 RCUWriter<DiskstreamList> writer (diskstreams);
1670 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1671 ds->remove (track->midi_diskstream());
1678 catch (AudioEngine::PortRegistrationFailure& pfe) {
1680 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;
1683 /* we need to get rid of this, since the track failed to be created */
1684 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1687 RCUWriter<DiskstreamList> writer (diskstreams);
1688 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1689 ds->remove (track->midi_diskstream());
1700 if (!new_routes.empty()) {
1701 add_routes (new_routes, false);
1702 save_state (_current_snapshot_name);
1708 list<boost::shared_ptr<AudioTrack> >
1709 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1711 char track_name[32];
1712 uint32_t track_id = 0;
1714 uint32_t channels_used = 0;
1716 RouteList new_routes;
1717 list<boost::shared_ptr<AudioTrack> > ret;
1718 uint32_t control_id;
1720 /* count existing audio tracks */
1723 shared_ptr<RouteList> r = routes.reader ();
1725 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1726 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1727 if (!(*i)->is_hidden()) {
1729 channels_used += (*i)->n_inputs().n_audio();
1735 vector<string> physinputs;
1736 vector<string> physoutputs;
1738 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1739 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1741 control_id = ntracks() + nbusses() + 1;
1745 /* check for duplicate route names, since we might have pre-existing
1746 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1747 save, close,restart,add new route - first named route is now
1755 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1757 if (route_by_name (track_name) == 0) {
1761 } while (track_id < (UINT_MAX-1));
1763 shared_ptr<AudioTrack> track;
1766 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1768 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1769 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1770 input_channels, output_channels)
1775 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1776 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1777 input_channels, output_channels)
1782 if (!physinputs.empty()) {
1783 uint32_t nphysical_in = physinputs.size();
1785 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1789 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1790 port = physinputs[(channels_used+x)%nphysical_in];
1793 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1799 if (!physoutputs.empty()) {
1800 uint32_t nphysical_out = physoutputs.size();
1802 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1805 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1806 port = physoutputs[(channels_used+x)%nphysical_out];
1807 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1808 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1809 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1813 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1819 channels_used += track->n_inputs ().n_audio();
1821 track->set_route_group (route_group, 0);
1823 track->audio_diskstream()->non_realtime_input_change();
1825 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1826 track->set_remote_control_id (control_id);
1829 new_routes.push_back (track);
1830 ret.push_back (track);
1833 catch (failed_constructor &err) {
1834 error << _("Session: could not create new audio track.") << endmsg;
1837 /* we need to get rid of this, since the track failed to be created */
1838 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1841 RCUWriter<DiskstreamList> writer (diskstreams);
1842 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1843 ds->remove (track->audio_diskstream());
1850 catch (AudioEngine::PortRegistrationFailure& pfe) {
1852 error << pfe.what() << endmsg;
1855 /* we need to get rid of this, since the track failed to be created */
1856 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1859 RCUWriter<DiskstreamList> writer (diskstreams);
1860 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1861 ds->remove (track->audio_diskstream());
1872 if (!new_routes.empty()) {
1873 add_routes (new_routes, true);
1880 Session::set_remote_control_ids ()
1882 RemoteModel m = Config->get_remote_model();
1884 shared_ptr<RouteList> r = routes.reader ();
1886 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1887 if ( MixerOrdered == m) {
1888 long order = (*i)->order_key(N_("signal"));
1889 (*i)->set_remote_control_id( order+1 );
1890 } else if ( EditorOrdered == m) {
1891 long order = (*i)->order_key(N_("editor"));
1892 (*i)->set_remote_control_id( order+1 );
1893 } else if ( UserOrdered == m) {
1894 //do nothing ... only changes to remote id's are initiated by user
1901 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1904 uint32_t bus_id = 1;
1906 uint32_t channels_used = 0;
1909 uint32_t control_id;
1911 /* count existing audio busses */
1914 shared_ptr<RouteList> r = routes.reader ();
1916 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1917 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1919 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1922 channels_used += (*i)->n_inputs().n_audio();
1928 vector<string> physinputs;
1929 vector<string> physoutputs;
1931 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1932 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1934 n_physical_audio_outputs = physoutputs.size();
1935 n_physical_audio_inputs = physinputs.size();
1937 control_id = ntracks() + nbusses() + 1;
1942 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1946 if (route_by_name (bus_name) == 0) {
1950 } while (bus_id < (UINT_MAX-1));
1953 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1955 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1956 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1957 input_channels, output_channels)
1963 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1964 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1965 input_channels, output_channels)
1970 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1973 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1974 port = physinputs[((n+x)%n_physical_audio_inputs)];
1977 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1982 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1985 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1986 port = physoutputs[((n+x)%n_physical_outputs)];
1987 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1989 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1993 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1998 channels_used += bus->n_inputs ().n_audio();
2000 bus->set_route_group (route_group, 0);
2001 bus->set_remote_control_id (control_id);
2004 ret.push_back (bus);
2008 catch (failed_constructor &err) {
2009 error << _("Session: could not create new audio route.") << endmsg;
2013 catch (AudioEngine::PortRegistrationFailure& pfe) {
2014 error << pfe.what() << endmsg;
2024 add_routes (ret, true);
2032 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2036 uint32_t control_id;
2038 uint32_t number = 1;
2040 if (!tree.read (template_path.c_str())) {
2044 XMLNode* node = tree.root();
2046 control_id = ntracks() + nbusses() + 1;
2050 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2052 std::string node_name = IO::name_from_state (*node_copy.children().front());
2054 /* generate a new name by adding a number to the end of the template name */
2057 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2061 if (route_by_name (name) == 0) {
2065 } while (number < UINT_MAX);
2067 if (number == UINT_MAX) {
2068 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2072 IO::set_name_in_state (*node_copy.children().front(), name);
2074 Track::zero_diskstream_id_in_xml (node_copy);
2077 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2080 error << _("Session: cannot create track/bus from template description") << endmsg;
2084 if (boost::dynamic_pointer_cast<Track>(route)) {
2085 /* force input/output change signals so that the new diskstream
2086 picks up the configuration of the route. During session
2087 loading this normally happens in a different way.
2089 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2090 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2093 route->set_remote_control_id (control_id);
2096 ret.push_back (route);
2099 catch (failed_constructor &err) {
2100 error << _("Session: could not create new route from template") << endmsg;
2104 catch (AudioEngine::PortRegistrationFailure& pfe) {
2105 error << pfe.what() << endmsg;
2114 add_routes (ret, true);
2121 Session::add_routes (RouteList& new_routes, bool save)
2124 RCUWriter<RouteList> writer (routes);
2125 shared_ptr<RouteList> r = writer.get_copy ();
2126 r->insert (r->end(), new_routes.begin(), new_routes.end());
2129 /* if there is no control out and we're not in the middle of loading,
2130 resort the graph here. if there is a control out, we will resort
2131 toward the end of this method. if we are in the middle of loading,
2132 we will resort when done.
2135 if (!_control_out && IO::connecting_legal) {
2136 resort_routes_using (r);
2140 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2142 boost::weak_ptr<Route> wpr (*x);
2144 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2145 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2146 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2147 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2148 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2149 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2151 if ((*x)->is_master()) {
2155 if ((*x)->is_control()) {
2156 _control_out = (*x);
2160 if (_control_out && IO::connecting_legal) {
2162 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2163 if ((*x)->is_control() || (*x)->is_master()) {
2166 (*x)->listen_via (_control_out,
2167 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2177 save_state (_current_snapshot_name);
2180 RouteAdded (new_routes); /* EMIT SIGNAL */
2184 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2186 boost::shared_ptr<RouteList> r = routes.reader ();
2187 boost::shared_ptr<Send> s;
2191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2192 if (boost::dynamic_pointer_cast<Track>(*i)) {
2193 if ((s = (*i)->internal_send_for (dest)) != 0) {
2194 s->amp()->gain_control()->set_value (0.0);
2201 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2203 boost::shared_ptr<RouteList> r = routes.reader ();
2204 boost::shared_ptr<Send> s;
2208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2209 if (boost::dynamic_pointer_cast<Track>(*i)) {
2210 if ((s = (*i)->internal_send_for (dest)) != 0) {
2211 s->amp()->gain_control()->set_value (1.0);
2218 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2220 boost::shared_ptr<RouteList> r = routes.reader ();
2221 boost::shared_ptr<Send> s;
2225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 if (boost::dynamic_pointer_cast<Track>(*i)) {
2227 if ((s = (*i)->internal_send_for (dest)) != 0) {
2228 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2235 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2237 boost::shared_ptr<RouteList> r = routes.reader ();
2238 boost::shared_ptr<RouteList> t (new RouteList);
2240 /* only send tracks */
2242 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2243 if (boost::dynamic_pointer_cast<Track>(*i)) {
2248 add_internal_sends (dest, p, t);
2253 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2255 if (dest->is_control() || dest->is_master()) {
2259 if (!dest->internal_return()) {
2260 dest->add_internal_return();
2263 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2265 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2269 (*i)->listen_via (dest, p, true, true);
2274 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2276 /* need to do this in case we're rolling at the time, to prevent false underruns */
2277 dstream->do_refill_with_alloc ();
2279 dstream->set_block_size (current_block_size);
2282 RCUWriter<DiskstreamList> writer (diskstreams);
2283 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2284 ds->push_back (dstream);
2285 /* writer goes out of scope, copies ds back to main */
2288 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2289 /* this will connect to future changes, and check the current length */
2290 diskstream_playlist_changed (dstream);
2292 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2294 dstream->prepare ();
2299 Session::remove_route (shared_ptr<Route> route)
2302 RCUWriter<RouteList> writer (routes);
2303 shared_ptr<RouteList> rs = writer.get_copy ();
2307 /* deleting the master out seems like a dumb
2308 idea, but its more of a UI policy issue
2312 if (route == _master_out) {
2313 _master_out = shared_ptr<Route> ();
2316 if (route == _control_out) {
2318 /* cancel control outs for all routes */
2320 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2321 (*r)->drop_listen (_control_out);
2324 _control_out.reset ();
2327 update_route_solo_state ();
2329 /* writer goes out of scope, forces route list update */
2332 boost::shared_ptr<Track> t;
2333 boost::shared_ptr<Diskstream> ds;
2335 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2336 ds = t->diskstream();
2342 RCUWriter<DiskstreamList> dsl (diskstreams);
2343 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2348 find_current_end ();
2350 // We need to disconnect the routes inputs and outputs
2352 route->input()->disconnect (0);
2353 route->output()->disconnect (0);
2355 update_latency_compensation (false, false);
2358 /* get rid of it from the dead wood collection in the route list manager */
2360 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2364 /* try to cause everyone to drop their references */
2366 route->drop_references ();
2368 sync_order_keys (N_("session"));
2370 /* save the new state of the world */
2372 if (save_state (_current_snapshot_name)) {
2373 save_history (_current_snapshot_name);
2378 Session::route_mute_changed (void* /*src*/)
2384 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2386 boost::shared_ptr<Route> route = wpr.lock();
2388 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2392 if (route->listening()) {
2394 } else if (_listen_cnt > 0) {
2400 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2402 if (solo_update_disabled) {
2407 boost::shared_ptr<Route> route = wpr.lock ();
2410 /* should not happen */
2411 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2415 shared_ptr<RouteList> r = routes.reader ();
2418 if (route->soloed()) {
2424 /* now mod the solo level of all other routes except master & control outs
2425 so that they will be silent if appropriate.
2428 solo_update_disabled = true;
2429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2431 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2433 (*i)->mod_solo_level (delta);
2437 /* make sure master is never muted by solo */
2439 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2440 _master_out->mod_solo_level (1);
2443 /* ditto for control outs make sure master is never muted by solo */
2445 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2446 _control_out->mod_solo_level (1);
2449 solo_update_disabled = false;
2450 update_route_solo_state (r);
2451 SoloChanged (); /* EMIT SIGNAL */
2456 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2458 /* now figure out if anything that matters is soloed */
2460 bool something_soloed = false;
2463 r = routes.reader();
2466 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2467 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2468 something_soloed = true;
2473 if (something_soloed != _non_soloed_outs_muted) {
2474 _non_soloed_outs_muted = something_soloed;
2475 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2480 Session::route_by_name (string name)
2482 shared_ptr<RouteList> r = routes.reader ();
2484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2485 if ((*i)->name() == name) {
2490 return shared_ptr<Route> ((Route*) 0);
2494 Session::route_by_id (PBD::ID id)
2496 shared_ptr<RouteList> r = routes.reader ();
2498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2499 if ((*i)->id() == id) {
2504 return shared_ptr<Route> ((Route*) 0);
2508 Session::route_by_remote_id (uint32_t id)
2510 shared_ptr<RouteList> r = routes.reader ();
2512 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2513 if ((*i)->remote_control_id() == id) {
2518 return shared_ptr<Route> ((Route*) 0);
2522 Session::find_current_end ()
2524 if (_state_of_the_state & Loading) {
2528 nframes_t max = get_maximum_extent ();
2530 if (max > end_location->end()) {
2531 end_location->set_end (max);
2533 DurationChanged(); /* EMIT SIGNAL */
2538 Session::get_maximum_extent () const
2543 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2545 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2546 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2548 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2549 if ((me = pl->get_maximum_extent()) > max) {
2557 boost::shared_ptr<Diskstream>
2558 Session::diskstream_by_name (string name)
2560 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2562 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2563 if ((*i)->name() == name) {
2568 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2571 boost::shared_ptr<Diskstream>
2572 Session::diskstream_by_id (const PBD::ID& id)
2574 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2576 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2577 if ((*i)->id() == id) {
2582 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2585 /* Region management */
2588 Session::new_region_name (string old)
2590 string::size_type last_period;
2592 string::size_type len = old.length() + 64;
2595 if ((last_period = old.find_last_of ('.')) == string::npos) {
2597 /* no period present - add one explicitly */
2600 last_period = old.length() - 1;
2605 number = atoi (old.substr (last_period+1).c_str());
2609 while (number < (UINT_MAX-1)) {
2611 RegionList::const_iterator i;
2616 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2619 for (i = regions.begin(); i != regions.end(); ++i) {
2620 if (i->second->name() == sbuf) {
2625 if (i == regions.end()) {
2630 if (number != (UINT_MAX-1)) {
2634 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2639 Session::region_name (string& result, string base, bool newlevel)
2644 if (base.find("/") != string::npos) {
2645 base = base.substr(base.find_last_of("/") + 1);
2650 Glib::Mutex::Lock lm (region_lock);
2652 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2661 string::size_type pos;
2663 pos = base.find_last_of ('.');
2665 /* pos may be npos, but then we just use entire base */
2667 subbase = base.substr (0, pos);
2672 Glib::Mutex::Lock lm (region_lock);
2674 map<string,uint32_t>::iterator x;
2678 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2680 region_name_map[subbase] = 1;
2683 snprintf (buf, sizeof (buf), ".%d", x->second);
2694 Session::add_region (boost::shared_ptr<Region> region)
2696 vector<boost::shared_ptr<Region> > v;
2697 v.push_back (region);
2702 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2707 Glib::Mutex::Lock lm (region_lock);
2709 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2711 boost::shared_ptr<Region> region = *ii;
2715 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2719 RegionList::iterator x;
2721 for (x = regions.begin(); x != regions.end(); ++x) {
2723 if (region->region_list_equivalent (x->second)) {
2728 if (x == regions.end()) {
2730 pair<RegionList::key_type,RegionList::mapped_type> entry;
2732 entry.first = region->id();
2733 entry.second = region;
2735 pair<RegionList::iterator,bool> x = regions.insert (entry);
2747 /* mark dirty because something has changed even if we didn't
2748 add the region to the region list.
2755 vector<boost::weak_ptr<Region> > v;
2756 boost::shared_ptr<Region> first_r;
2758 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2760 boost::shared_ptr<Region> region = *ii;
2764 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2767 v.push_back (region);
2774 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2775 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2777 update_region_name_map (region);
2781 RegionsAdded (v); /* EMIT SIGNAL */
2787 Session::update_region_name_map (boost::shared_ptr<Region> region)
2789 string::size_type last_period = region->name().find_last_of ('.');
2791 if (last_period != string::npos && last_period < region->name().length() - 1) {
2793 string base = region->name().substr (0, last_period);
2794 string number = region->name().substr (last_period+1);
2795 map<string,uint32_t>::iterator x;
2797 /* note that if there is no number, we get zero from atoi,
2801 region_name_map[base] = atoi (number);
2806 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2808 boost::shared_ptr<Region> region (weak_region.lock ());
2814 if (what_changed & Region::HiddenChanged) {
2815 /* relay hidden changes */
2816 RegionHiddenChange (region);
2819 if (what_changed & NameChanged) {
2820 update_region_name_map (region);
2825 Session::remove_region (boost::weak_ptr<Region> weak_region)
2827 RegionList::iterator i;
2828 boost::shared_ptr<Region> region (weak_region.lock ());
2834 bool removed = false;
2837 Glib::Mutex::Lock lm (region_lock);
2839 if ((i = regions.find (region->id())) != regions.end()) {
2845 /* mark dirty because something has changed even if we didn't
2846 remove the region from the region list.
2852 RegionRemoved(region); /* EMIT SIGNAL */
2856 boost::shared_ptr<Region>
2857 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2859 RegionList::iterator i;
2860 boost::shared_ptr<Region> region;
2862 Glib::Mutex::Lock lm (region_lock);
2864 for (i = regions.begin(); i != regions.end(); ++i) {
2868 if (region->whole_file()) {
2870 if (child->source_equivalent (region)) {
2876 return boost::shared_ptr<Region> ();
2880 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2882 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2883 (*i)->get_region_list_equivalent_regions (region, result);
2887 Session::destroy_region (boost::shared_ptr<Region> region)
2889 vector<boost::shared_ptr<Source> > srcs;
2892 if (region->playlist()) {
2893 region->playlist()->destroy_region (region);
2896 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2897 srcs.push_back (region->source (n));
2901 region->drop_references ();
2903 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2905 (*i)->mark_for_remove ();
2906 (*i)->drop_references ();
2908 cerr << "source was not used by any playlist\n";
2915 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2917 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2918 destroy_region (*i);
2924 Session::remove_last_capture ()
2926 list<boost::shared_ptr<Region> > r;
2928 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2930 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2931 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2934 r.insert (r.end(), l.begin(), l.end());
2939 destroy_regions (r);
2941 save_state (_current_snapshot_name);
2947 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2953 /* Source Management */
2956 Session::add_source (boost::shared_ptr<Source> source)
2958 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2959 pair<SourceMap::iterator,bool> result;
2961 entry.first = source->id();
2962 entry.second = source;
2965 Glib::Mutex::Lock lm (source_lock);
2966 result = sources.insert (entry);
2969 if (result.second) {
2970 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2974 boost::shared_ptr<AudioFileSource> afs;
2976 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2977 if (Config->get_auto_analyse_audio()) {
2978 Analyser::queue_source_for_analysis (source, false);
2984 Session::remove_source (boost::weak_ptr<Source> src)
2986 SourceMap::iterator i;
2987 boost::shared_ptr<Source> source = src.lock();
2994 Glib::Mutex::Lock lm (source_lock);
2996 if ((i = sources.find (source->id())) != sources.end()) {
3001 if (!_state_of_the_state & InCleanup) {
3003 /* save state so we don't end up with a session file
3004 referring to non-existent sources.
3007 save_state (_current_snapshot_name);
3011 boost::shared_ptr<Source>
3012 Session::source_by_id (const PBD::ID& id)
3014 Glib::Mutex::Lock lm (source_lock);
3015 SourceMap::iterator i;
3016 boost::shared_ptr<Source> source;
3018 if ((i = sources.find (id)) != sources.end()) {
3025 boost::shared_ptr<Source>
3026 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3028 Glib::Mutex::Lock lm (source_lock);
3030 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3031 cerr << "comparing " << path << " with " << i->second->name() << endl;
3032 boost::shared_ptr<AudioFileSource> afs
3033 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3035 if (afs && afs->path() == path && chn == afs->channel()) {
3039 return boost::shared_ptr<Source>();
3044 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3047 string old_basename = PBD::basename_nosuffix (oldname);
3048 string new_legalized = legalize_for_path (newname);
3050 /* note: we know (or assume) the old path is already valid */
3054 /* destructive file sources have a name of the form:
3056 /path/to/Tnnnn-NAME(%[LR])?.wav
3058 the task here is to replace NAME with the new name.
3061 /* find last slash */
3065 string::size_type slash;
3066 string::size_type dash;
3068 if ((slash = path.find_last_of ('/')) == string::npos) {
3072 dir = path.substr (0, slash+1);
3074 /* '-' is not a legal character for the NAME part of the path */
3076 if ((dash = path.find_last_of ('-')) == string::npos) {
3080 prefix = path.substr (slash+1, dash-(slash+1));
3085 path += new_legalized;
3086 path += ".wav"; /* XXX gag me with a spoon */
3090 /* non-destructive file sources have a name of the form:
3092 /path/to/NAME-nnnnn(%[LR])?.ext
3094 the task here is to replace NAME with the new name.
3099 string::size_type slash;
3100 string::size_type dash;
3101 string::size_type postfix;
3103 /* find last slash */
3105 if ((slash = path.find_last_of ('/')) == string::npos) {
3109 dir = path.substr (0, slash+1);
3111 /* '-' is not a legal character for the NAME part of the path */
3113 if ((dash = path.find_last_of ('-')) == string::npos) {
3117 suffix = path.substr (dash+1);
3119 // Suffix is now everything after the dash. Now we need to eliminate
3120 // the nnnnn part, which is done by either finding a '%' or a '.'
3122 postfix = suffix.find_last_of ("%");
3123 if (postfix == string::npos) {
3124 postfix = suffix.find_last_of ('.');
3127 if (postfix != string::npos) {
3128 suffix = suffix.substr (postfix);
3130 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3134 const uint32_t limit = 10000;
3135 char buf[PATH_MAX+1];
3137 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3139 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3141 if (access (buf, F_OK) != 0) {
3149 error << "FATAL ERROR! Could not find a " << endl;
3157 /** Return the full path (in some session directory) for a new embedded source.
3158 * \a name must be a session-unique name that does not contain slashes
3159 * (e.g. as returned by new_*_source_name)
3162 Session::new_source_path_from_name (DataType type, const string& name)
3164 assert(name.find("/") == string::npos);
3166 SessionDirectory sdir(get_best_session_directory_for_new_source());
3169 if (type == DataType::AUDIO) {
3170 p = sdir.sound_path();
3171 } else if (type == DataType::MIDI) {
3172 p = sdir.midi_path();
3174 error << "Unknown source type, unable to create file path" << endmsg;
3179 return p.to_string();
3183 Session::peak_path (Glib::ustring base) const
3185 sys::path peakfile_path(_session_dir->peak_path());
3186 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3187 return peakfile_path.to_string();
3190 /** Return a unique name based on \a base for a new internal audio source */
3192 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3196 char buf[PATH_MAX+1];
3197 const uint32_t limit = 10000;
3201 legalized = legalize_for_path (base);
3203 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3204 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3206 vector<space_and_path>::iterator i;
3207 uint32_t existing = 0;
3209 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3211 SessionDirectory sdir((*i).path);
3213 spath = sdir.sound_path().to_string();
3218 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3219 spath.c_str(), cnt, legalized.c_str());
3220 } else if (nchan == 2) {
3222 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3223 spath.c_str(), cnt, legalized.c_str());
3225 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3226 spath.c_str(), cnt, legalized.c_str());
3228 } else if (nchan < 26) {
3229 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3230 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3232 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3233 spath.c_str(), cnt, legalized.c_str());
3242 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3243 } else if (nchan == 2) {
3245 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3247 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3249 } else if (nchan < 26) {
3250 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3252 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3256 if (sys::exists(buf)) {
3262 if (existing == 0) {
3267 error << string_compose(
3268 _("There are already %1 recordings for %2, which I consider too many."),
3269 limit, base) << endmsg;
3271 throw failed_constructor();
3275 return Glib::path_get_basename(buf);
3278 /** Create a new embedded audio source */
3279 boost::shared_ptr<AudioFileSource>
3280 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3282 const size_t n_chans = ds.n_channels().n_audio();
3283 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3284 const string path = new_source_path_from_name(DataType::AUDIO, name);
3285 return boost::dynamic_pointer_cast<AudioFileSource> (
3286 SourceFactory::createWritable (
3287 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3290 /** Return a unique name based on \a base for a new internal MIDI source */
3292 Session::new_midi_source_name (const string& base)
3295 char buf[PATH_MAX+1];
3296 const uint32_t limit = 10000;
3300 legalized = legalize_for_path (base);
3302 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3303 for (cnt = 1; cnt <= limit; ++cnt) {
3305 vector<space_and_path>::iterator i;
3306 uint32_t existing = 0;
3308 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3310 SessionDirectory sdir((*i).path);
3312 sys::path p = sdir.midi_path();
3315 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3317 if (sys::exists (buf)) {
3322 if (existing == 0) {
3327 error << string_compose(
3328 _("There are already %1 recordings for %2, which I consider too many."),
3329 limit, base) << endmsg;
3331 throw failed_constructor();
3335 return Glib::path_get_basename(buf);
3339 /** Create a new embedded MIDI source */
3340 boost::shared_ptr<MidiSource>
3341 Session::create_midi_source_for_session (MidiDiskstream& ds)
3343 const string name = new_midi_source_name (ds.name());
3344 const string path = new_source_path_from_name (DataType::MIDI, name);
3346 return boost::dynamic_pointer_cast<SMFSource> (
3347 SourceFactory::createWritable (
3348 DataType::MIDI, *this, path, true, false, frame_rate()));
3352 /* Playlist management */
3354 boost::shared_ptr<Playlist>
3355 Session::playlist_by_name (string name)
3357 Glib::Mutex::Lock lm (playlist_lock);
3358 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3359 if ((*i)->name() == name) {
3363 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3364 if ((*i)->name() == name) {
3369 return boost::shared_ptr<Playlist>();
3373 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3375 Glib::Mutex::Lock lm (playlist_lock);
3376 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3377 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3378 list.push_back (*i);
3381 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3382 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3383 list.push_back (*i);
3389 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3391 if (playlist->hidden()) {
3396 Glib::Mutex::Lock lm (playlist_lock);
3397 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3398 playlists.insert (playlists.begin(), playlist);
3399 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3400 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3405 playlist->release();
3410 PlaylistAdded (playlist); /* EMIT SIGNAL */
3414 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3417 Glib::Mutex::Lock lm (playlist_lock);
3418 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3421 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3428 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3430 boost::shared_ptr<Playlist> pl(wpl.lock());
3436 PlaylistList::iterator x;
3439 /* its not supposed to be visible */
3444 Glib::Mutex::Lock lm (playlist_lock);
3448 unused_playlists.insert (pl);
3450 if ((x = playlists.find (pl)) != playlists.end()) {
3451 playlists.erase (x);
3457 playlists.insert (pl);
3459 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3460 unused_playlists.erase (x);
3467 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3469 if (_state_of_the_state & Deletion) {
3473 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3480 Glib::Mutex::Lock lm (playlist_lock);
3482 PlaylistList::iterator i;
3484 i = find (playlists.begin(), playlists.end(), playlist);
3485 if (i != playlists.end()) {
3486 playlists.erase (i);
3489 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3490 if (i != unused_playlists.end()) {
3491 unused_playlists.erase (i);
3498 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3502 Session::set_audition (boost::shared_ptr<Region> r)
3504 pending_audition_region = r;
3505 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3506 schedule_butler_transport_work ();
3510 Session::audition_playlist ()
3512 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3513 ev->region.reset ();
3518 Session::non_realtime_set_audition ()
3520 if (!pending_audition_region) {
3521 auditioner->audition_current_playlist ();
3523 auditioner->audition_region (pending_audition_region);
3524 pending_audition_region.reset ();
3526 AuditionActive (true); /* EMIT SIGNAL */
3530 Session::audition_region (boost::shared_ptr<Region> r)
3532 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3538 Session::cancel_audition ()
3540 if (auditioner->active()) {
3541 auditioner->cancel_audition ();
3542 AuditionActive (false); /* EMIT SIGNAL */
3547 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3549 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3553 Session::remove_empty_sounds ()
3555 vector<string> audio_filenames;
3557 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3559 Glib::Mutex::Lock lm (source_lock);
3561 TapeFileMatcher tape_file_matcher;
3563 remove_if (audio_filenames.begin(), audio_filenames.end(),
3564 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3566 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3568 sys::path audio_file_path (_session_dir->sound_path());
3570 audio_file_path /= *i;
3572 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3576 sys::remove (audio_file_path);
3577 const string peakfile = peak_path (audio_file_path.to_string());
3578 sys::remove (peakfile);
3580 catch (const sys::filesystem_error& err)
3582 error << err.what() << endmsg;
3589 Session::is_auditioning () const
3591 /* can be called before we have an auditioner object */
3593 return auditioner->active();
3600 Session::set_all_solo (bool yn)
3602 shared_ptr<RouteList> r = routes.reader ();
3604 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3605 if (!(*i)->is_hidden()) {
3606 (*i)->set_solo (yn, this);
3614 Session::set_all_listen (bool yn)
3616 shared_ptr<RouteList> r = routes.reader ();
3618 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3619 if (!(*i)->is_hidden()) {
3620 (*i)->set_listen (yn, this);
3628 Session::set_all_mute (bool yn)
3630 shared_ptr<RouteList> r = routes.reader ();
3632 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3633 if (!(*i)->is_hidden()) {
3634 (*i)->set_mute (yn, this);
3642 Session::n_diskstreams () const
3646 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3648 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3649 if (!(*i)->hidden()) {
3657 Session::graph_reordered ()
3659 /* don't do this stuff if we are setting up connections
3660 from a set_state() call or creating new tracks.
3663 if (_state_of_the_state & InitialConnecting) {
3667 /* every track/bus asked for this to be handled but it was deferred because
3668 we were connecting. do it now.
3671 request_input_change_handling ();
3675 /* force all diskstreams to update their capture offset values to
3676 reflect any changes in latencies within the graph.
3679 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3681 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3682 (*i)->set_capture_offset ();
3687 Session::record_disenable_all ()
3689 record_enable_change_all (false);
3693 Session::record_enable_all ()
3695 record_enable_change_all (true);
3699 Session::record_enable_change_all (bool yn)
3701 shared_ptr<RouteList> r = routes.reader ();
3703 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3704 boost::shared_ptr<Track> t;
3706 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3707 t->set_record_enable (yn, this);
3711 /* since we don't keep rec-enable state, don't mark session dirty */
3715 Session::add_processor (Processor* processor)
3717 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3722 Session::remove_processor (Processor* processor)
3726 PortInsert* port_insert;
3728 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3729 insert_bitset[port_insert->bit_slot()] = false;
3730 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3731 send_bitset[send->bit_slot()] = false;
3732 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3733 return_bitset[send->bit_slot()] = false;
3740 Session::available_capture_duration ()
3742 float sample_bytes_on_disk = 4.0; // keep gcc happy
3744 switch (config.get_native_file_data_format()) {
3746 sample_bytes_on_disk = 4.0;
3750 sample_bytes_on_disk = 3.0;
3754 sample_bytes_on_disk = 2.0;
3758 /* impossible, but keep some gcc versions happy */
3759 fatal << string_compose (_("programming error: %1"),
3760 X_("illegal native file data format"))
3765 double scale = 4096.0 / sample_bytes_on_disk;
3767 if (_total_free_4k_blocks * scale > (double) max_frames) {
3771 return (nframes_t) floor (_total_free_4k_blocks * scale);
3775 Session::add_bundle (shared_ptr<Bundle> bundle)
3778 RCUWriter<BundleList> writer (_bundles);
3779 boost::shared_ptr<BundleList> b = writer.get_copy ();
3780 b->push_back (bundle);
3783 BundleAdded (bundle); /* EMIT SIGNAL */
3789 Session::remove_bundle (shared_ptr<Bundle> bundle)
3791 bool removed = false;
3794 RCUWriter<BundleList> writer (_bundles);
3795 boost::shared_ptr<BundleList> b = writer.get_copy ();
3796 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3798 if (i != b->end()) {
3805 BundleRemoved (bundle); /* EMIT SIGNAL */
3812 Session::bundle_by_name (string name) const
3814 boost::shared_ptr<BundleList> b = _bundles.reader ();
3816 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3817 if ((*i)->name() == name) {
3822 return boost::shared_ptr<Bundle> ();
3826 Session::tempo_map_changed (Change)
3830 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3831 (*i)->update_after_tempo_map_change ();
3834 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3835 (*i)->update_after_tempo_map_change ();
3841 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3842 * the given count with the current block size.
3845 Session::ensure_buffers (ChanCount howmany)
3847 if (current_block_size == 0) {
3848 return; // too early? (is this ok?)
3851 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3852 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3853 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3854 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3855 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3858 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3862 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3864 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3865 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3870 Session::next_insert_id ()
3872 /* this doesn't really loop forever. just think about it */
3875 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3876 if (!insert_bitset[n]) {
3877 insert_bitset[n] = true;
3883 /* none available, so resize and try again */
3885 insert_bitset.resize (insert_bitset.size() + 16, false);
3890 Session::next_send_id ()
3892 /* this doesn't really loop forever. just think about it */
3895 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3896 if (!send_bitset[n]) {
3897 send_bitset[n] = true;
3903 /* none available, so resize and try again */
3905 send_bitset.resize (send_bitset.size() + 16, false);
3910 Session::next_return_id ()
3912 /* this doesn't really loop forever. just think about it */
3915 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3916 if (!return_bitset[n]) {
3917 return_bitset[n] = true;
3923 /* none available, so resize and try again */
3925 return_bitset.resize (return_bitset.size() + 16, false);
3930 Session::mark_send_id (uint32_t id)
3932 if (id >= send_bitset.size()) {
3933 send_bitset.resize (id+16, false);
3935 if (send_bitset[id]) {
3936 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3938 send_bitset[id] = true;
3942 Session::mark_return_id (uint32_t id)
3944 if (id >= return_bitset.size()) {
3945 return_bitset.resize (id+16, false);
3947 if (return_bitset[id]) {
3948 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3950 return_bitset[id] = true;
3954 Session::mark_insert_id (uint32_t id)
3956 if (id >= insert_bitset.size()) {
3957 insert_bitset.resize (id+16, false);
3959 if (insert_bitset[id]) {
3960 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3962 insert_bitset[id] = true;
3965 /* Named Selection management */
3968 Session::named_selection_by_name (string name)
3970 Glib::Mutex::Lock lm (named_selection_lock);
3971 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3972 if ((*i)->name == name) {
3980 Session::add_named_selection (NamedSelection* named_selection)
3983 Glib::Mutex::Lock lm (named_selection_lock);
3984 named_selections.insert (named_selections.begin(), named_selection);
3987 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3993 NamedSelectionAdded (); /* EMIT SIGNAL */
3997 Session::remove_named_selection (NamedSelection* named_selection)
3999 bool removed = false;
4002 Glib::Mutex::Lock lm (named_selection_lock);
4004 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4006 if (i != named_selections.end()) {
4008 named_selections.erase (i);
4015 NamedSelectionRemoved (); /* EMIT SIGNAL */
4020 Session::reset_native_file_format ()
4022 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4024 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4025 (*i)->reset_write_sources (false);
4030 Session::route_name_unique (string n) const
4032 shared_ptr<RouteList> r = routes.reader ();
4034 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4035 if ((*i)->name() == n) {
4044 Session::route_name_internal (string n) const
4046 if (auditioner && auditioner->name() == n) {
4050 if (_click_io && _click_io->name() == n) {
4058 Session::n_playlists () const
4060 Glib::Mutex::Lock lm (playlist_lock);
4061 return playlists.size();
4065 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4067 if (!force && howmany <= _npan_buffers) {
4071 if (_pan_automation_buffer) {
4073 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4074 delete [] _pan_automation_buffer[i];
4077 delete [] _pan_automation_buffer;
4080 _pan_automation_buffer = new pan_t*[howmany];
4082 for (uint32_t i = 0; i < howmany; ++i) {
4083 _pan_automation_buffer[i] = new pan_t[nframes];
4086 _npan_buffers = howmany;
4090 Session::freeze (InterThreadInfo& itt)
4092 shared_ptr<RouteList> r = routes.reader ();
4094 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4096 boost::shared_ptr<Track> t;
4098 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4099 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4109 boost::shared_ptr<Region>
4110 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4111 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4112 InterThreadInfo& itt, bool enable_processing)
4114 boost::shared_ptr<Region> result;
4115 boost::shared_ptr<Playlist> playlist;
4116 boost::shared_ptr<AudioFileSource> fsource;
4118 char buf[PATH_MAX+1];
4119 ChanCount nchans(track.audio_diskstream()->n_channels());
4121 nframes_t this_chunk;
4124 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4125 const string sound_dir = sdir.sound_path().to_string();
4126 nframes_t len = end - start;
4129 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4130 end, start) << endmsg;
4134 // any bigger than this seems to cause stack overflows in called functions
4135 const nframes_t chunk_size = (128 * 1024)/4;
4137 // block all process callback handling
4139 block_processing ();
4141 /* call tree *MUST* hold route_lock */
4143 if ((playlist = track.diskstream()->playlist()) == 0) {
4147 /* external redirects will be a problem */
4149 if (track.has_external_redirects()) {
4153 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4155 for (x = 0; x < 99999; ++x) {
4156 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4157 if (access (buf, F_OK) != 0) {
4163 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4168 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4169 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4172 catch (failed_constructor& err) {
4173 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4177 srcs.push_back (fsource);
4180 /* XXX need to flush all redirects */
4185 /* create a set of reasonably-sized buffers */
4186 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4187 buffers.set_count(nchans);
4189 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4190 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4192 afs->prepare_for_peakfile_writes ();
4195 while (to_do && !itt.cancel) {
4197 this_chunk = min (to_do, chunk_size);
4199 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4204 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4205 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4208 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4214 start += this_chunk;
4215 to_do -= this_chunk;
4217 itt.progress = (float) (1.0 - ((double) to_do / len));
4226 xnow = localtime (&now);
4228 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4229 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4232 afs->update_header (position, *xnow, now);
4233 afs->flush_header ();
4237 /* construct a region to represent the bounced material */
4239 result = RegionFactory::create (srcs, 0,
4240 srcs.front()->length(srcs.front()->timeline_position()),
4241 region_name_from_path (srcs.front()->name(), true));
4246 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4247 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4250 afs->mark_for_remove ();
4253 (*src)->drop_references ();
4257 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4258 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4261 afs->done_with_peakfile_writes ();
4265 unblock_processing ();
4271 Session::get_silent_buffers (ChanCount count)
4273 assert(_silent_buffers->available() >= count);
4274 _silent_buffers->set_count(count);
4276 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4277 for (size_t i= 0; i < count.get(*t); ++i) {
4278 _silent_buffers->get(*t, i).clear();
4282 return *_silent_buffers;
4286 Session::get_scratch_buffers (ChanCount count)
4288 if (count != ChanCount::ZERO) {
4289 assert(_scratch_buffers->available() >= count);
4290 _scratch_buffers->set_count(count);
4292 _scratch_buffers->set_count (_scratch_buffers->available());
4295 return *_scratch_buffers;
4299 Session::get_mix_buffers (ChanCount count)
4301 assert(_mix_buffers->available() >= count);
4302 _mix_buffers->set_count(count);
4303 return *_mix_buffers;
4307 Session::ntracks () const
4310 shared_ptr<RouteList> r = routes.reader ();
4312 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4313 if (boost::dynamic_pointer_cast<Track> (*i)) {
4322 Session::nbusses () const
4325 shared_ptr<RouteList> r = routes.reader ();
4327 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4328 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4337 Session::add_automation_list(AutomationList *al)
4339 automation_lists[al->id()] = al;
4343 Session::compute_initial_length ()
4345 return _engine.frame_rate() * 60 * 5;
4349 Session::sync_order_keys (std::string const & base)
4351 if (!Config->get_sync_all_route_ordering()) {
4352 /* leave order keys as they are */
4356 boost::shared_ptr<RouteList> r = routes.reader ();
4358 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4359 (*i)->sync_order_keys (base);
4362 Route::SyncOrderKeys (base); // EMIT SIGNAL
4366 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4368 Session::have_rec_enabled_diskstream () const
4370 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4373 /** Update the state of our rec-enabled diskstreams flag */
4375 Session::update_have_rec_enabled_diskstream ()
4377 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4378 DiskstreamList::iterator i = dsl->begin ();
4379 while (i != dsl->end () && (*i)->record_enabled () == false) {
4383 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4385 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4387 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4388 RecordStateChanged (); /* EMIT SIGNAL */
4393 Session::listen_position_changed ()
4397 switch (Config->get_listen_position()) {
4398 case AfterFaderListen:
4402 case PreFaderListen:
4407 boost::shared_ptr<RouteList> r = routes.reader ();
4409 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4410 (*i)->put_control_outs_at (p);
4415 Session::solo_control_mode_changed ()
4417 /* cancel all solo or all listen when solo control mode changes */
4419 if (Config->get_solo_control_is_listen_control()) {
4420 set_all_solo (false);
4422 set_all_listen (false);
4427 Session::route_group_changed ()
4429 RouteGroupChanged (); /* EMIT SIGNAL */