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/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_port.h"
50 #include "ardour/audio_track.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/audiofilesource.h"
53 #include "ardour/audioplaylist.h"
54 #include "ardour/audioregion.h"
55 #include "ardour/auditioner.h"
56 #include "ardour/buffer_set.h"
57 #include "ardour/bundle.h"
58 #include "ardour/click.h"
59 #include "ardour/configuration.h"
60 #include "ardour/crossfade.h"
61 #include "ardour/cycle_timer.h"
62 #include "ardour/data_type.h"
63 #include "ardour/filename_extensions.h"
64 #include "ardour/io_processor.h"
65 #include "ardour/midi_diskstream.h"
66 #include "ardour/midi_playlist.h"
67 #include "ardour/midi_region.h"
68 #include "ardour/midi_track.h"
69 #include "ardour/named_selection.h"
70 #include "ardour/playlist.h"
71 #include "ardour/plugin_insert.h"
72 #include "ardour/port_insert.h"
73 #include "ardour/processor.h"
74 #include "ardour/recent_sessions.h"
75 #include "ardour/region_factory.h"
76 #include "ardour/return.h"
77 #include "ardour/route_group.h"
78 #include "ardour/send.h"
79 #include "ardour/session.h"
80 #include "ardour/session_directory.h"
81 #include "ardour/session_directory.h"
82 #include "ardour/session_metadata.h"
83 #include "ardour/slave.h"
84 #include "ardour/smf_source.h"
85 #include "ardour/source_factory.h"
86 #include "ardour/tape_file_matcher.h"
87 #include "ardour/tempo.h"
88 #include "ardour/utils.h"
93 using namespace ARDOUR;
95 using boost::shared_ptr;
97 bool Session::_disable_all_loaded_plugins = false;
99 sigc::signal<void,std::string> Session::Dialog;
100 sigc::signal<int> Session::AskAboutPendingState;
101 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
102 sigc::signal<void> Session::SendFeedback;
104 sigc::signal<void> Session::SMPTEOffsetChanged;
105 sigc::signal<void> Session::StartTimeChanged;
106 sigc::signal<void> Session::EndTimeChanged;
107 sigc::signal<void> Session::AutoBindingOn;
108 sigc::signal<void> Session::AutoBindingOff;
109 sigc::signal<void, std::string, std::string> Session::Exported;
111 Session::Session (AudioEngine &eng,
112 const string& fullpath,
113 const string& snapshot_name,
117 _target_transport_speed (0.0),
118 _requested_return_frame (-1),
119 _scratch_buffers(new BufferSet()),
120 _silent_buffers(new BufferSet()),
121 _mix_buffers(new BufferSet()),
123 _mmc_port (default_mmc_port),
124 _mtc_port (default_mtc_port),
125 _midi_port (default_midi_port),
126 _midi_clock_port (default_midi_clock_port),
127 _session_dir (new SessionDirectory(fullpath)),
128 pending_events (2048),
130 butler_mixdown_buffer (0),
131 butler_gain_buffer (0),
132 post_transport_work((PostTransportWork)0),
133 _send_smpte_update (false),
134 midi_thread (pthread_t (0)),
135 midi_requests (128), // the size of this should match the midi request pool size
136 diskstreams (new DiskstreamList),
137 routes (new RouteList),
138 _total_free_4k_blocks (0),
139 _bundles (new BundleList),
140 _bundle_xml_node (0),
143 click_emphasis_data (0),
145 _metadata (new SessionMetadata()),
146 _have_rec_enabled_diskstream (false)
151 interpolation.add_channel_to (0, 0);
153 if (!eng.connected()) {
154 throw failed_constructor();
157 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
159 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
160 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
162 first_stage_init (fullpath, snapshot_name);
164 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
167 if (create (new_session, mix_template, compute_initial_length())) {
169 throw failed_constructor ();
173 if (second_stage_init (new_session)) {
175 throw failed_constructor ();
178 store_recent_sessions(_name, _path);
180 bool was_dirty = dirty();
182 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
184 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
185 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
188 DirtyChanged (); /* EMIT SIGNAL */
192 Session::Session (AudioEngine &eng,
194 string snapshot_name,
195 AutoConnectOption input_ac,
196 AutoConnectOption output_ac,
197 uint32_t control_out_channels,
198 uint32_t master_out_channels,
199 uint32_t requested_physical_in,
200 uint32_t requested_physical_out,
201 nframes_t initial_length)
204 _target_transport_speed (0.0),
205 _requested_return_frame (-1),
206 _scratch_buffers(new BufferSet()),
207 _silent_buffers(new BufferSet()),
208 _mix_buffers(new BufferSet()),
210 _mmc_port (default_mmc_port),
211 _mtc_port (default_mtc_port),
212 _midi_port (default_midi_port),
213 _midi_clock_port (default_midi_clock_port),
214 _session_dir ( new SessionDirectory(fullpath)),
215 pending_events (2048),
217 butler_mixdown_buffer (0),
218 butler_gain_buffer (0),
219 post_transport_work((PostTransportWork)0),
220 _send_smpte_update (false),
221 midi_thread (pthread_t (0)),
223 diskstreams (new DiskstreamList),
224 routes (new RouteList),
225 _total_free_4k_blocks (0),
226 _bundles (new BundleList),
227 _bundle_xml_node (0),
228 _click_io ((IO *) 0),
230 click_emphasis_data (0),
232 _metadata (new SessionMetadata()),
233 _have_rec_enabled_diskstream (false)
237 interpolation.add_channel_to (0, 0);
239 if (!eng.connected()) {
240 throw failed_constructor();
243 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
245 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
246 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
248 if (n_physical_inputs) {
249 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
252 if (n_physical_outputs) {
253 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
256 first_stage_init (fullpath, snapshot_name);
258 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
261 if (create (new_session, string(), initial_length)) {
263 throw failed_constructor ();
268 /* set up Master Out and Control Out if necessary */
273 if (master_out_channels) {
274 ChanCount count(DataType::AUDIO, master_out_channels);
275 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
276 r->input()->ensure_io (count, false, this);
277 r->output()->ensure_io (count, false, this);
278 r->set_remote_control_id (control_id);
282 /* prohibit auto-connect to master, because there isn't one */
283 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
286 if (control_out_channels) {
287 ChanCount count(DataType::AUDIO, control_out_channels);
288 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
289 r->input()->ensure_io (count, false, this);
290 r->output()->ensure_io (count, false, this);
291 r->set_remote_control_id (control_id++);
297 add_routes (rl, false);
302 if (no_auto_connect()) {
303 input_ac = AutoConnectOption (0);
304 output_ac = AutoConnectOption (0);
307 Config->set_input_auto_connect (input_ac);
308 Config->set_output_auto_connect (output_ac);
310 if (second_stage_init (new_session)) {
312 throw failed_constructor ();
315 store_recent_sessions (_name, _path);
317 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
319 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
330 /* if we got to here, leaving pending capture state around
334 remove_pending_capture_state ();
336 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
338 _engine.remove_session ();
340 GoingAway (); /* EMIT SIGNAL */
346 /* clear history so that no references to objects are held any more */
350 /* clear state tree so that no references to objects are held any more */
354 terminate_butler_thread ();
355 //terminate_midi_thread ();
357 if (click_data != default_click) {
358 delete [] click_data;
361 if (click_emphasis_data != default_click_emphasis) {
362 delete [] click_emphasis_data;
367 delete _scratch_buffers;
368 delete _silent_buffers;
371 AudioDiskstream::free_working_buffers();
373 Route::SyncOrderKeys.clear();
375 #undef TRACK_DESTRUCTION
376 #ifdef TRACK_DESTRUCTION
377 cerr << "delete named selections\n";
378 #endif /* TRACK_DESTRUCTION */
379 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
380 NamedSelectionList::iterator tmp;
389 #ifdef TRACK_DESTRUCTION
390 cerr << "delete playlists\n";
391 #endif /* TRACK_DESTRUCTION */
392 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
393 PlaylistList::iterator tmp;
398 (*i)->drop_references ();
403 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
404 PlaylistList::iterator tmp;
409 (*i)->drop_references ();
415 unused_playlists.clear ();
417 #ifdef TRACK_DESTRUCTION
418 cerr << "delete regions\n";
419 #endif /* TRACK_DESTRUCTION */
421 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
422 RegionList::iterator tmp;
427 i->second->drop_references ();
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete routes\n";
436 #endif /* TRACK_DESTRUCTION */
438 RCUWriter<RouteList> writer (routes);
439 boost::shared_ptr<RouteList> r = writer.get_copy ();
440 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
441 (*i)->drop_references ();
444 /* writer goes out of scope and updates master */
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete diskstreams\n";
451 #endif /* TRACK_DESTRUCTION */
453 RCUWriter<DiskstreamList> dwriter (diskstreams);
454 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
455 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
456 (*i)->drop_references ();
460 diskstreams.flush ();
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete audio sources\n";
464 #endif /* TRACK_DESTRUCTION */
465 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
466 SourceMap::iterator tmp;
471 i->second->drop_references ();
478 #ifdef TRACK_DESTRUCTION
479 cerr << "delete route groups\n";
480 #endif /* TRACK_DESTRUCTION */
481 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
485 delete [] butler_mixdown_buffer;
486 delete [] butler_gain_buffer;
488 Crossfade::set_buffer_size (0);
494 Session::set_worst_io_latencies ()
496 _worst_output_latency = 0;
497 _worst_input_latency = 0;
499 if (!_engine.connected()) {
503 boost::shared_ptr<RouteList> r = routes.reader ();
505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
506 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
507 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
512 Session::when_engine_running ()
514 string first_physical_output;
516 BootMessage (_("Set block size and sample rate"));
518 set_block_size (_engine.frames_per_cycle());
519 set_frame_rate (_engine.frame_rate());
521 BootMessage (_("Using configuration"));
523 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
525 /* every time we reconnect, recompute worst case output latencies */
527 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
529 if (synced_to_jack()) {
530 _engine.transport_stop ();
533 if (config.get_jack_time_master()) {
534 _engine.transport_locate (_transport_frame);
542 _click_io.reset (new ClickIO (*this, "click"));
544 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
546 /* existing state for Click */
548 if (_click_io->set_state (*child->children().front()) == 0) {
550 _clicking = Config->get_clicking ();
554 error << _("could not setup Click I/O") << endmsg;
560 /* default state for Click: dual-mono to first 2 physical outputs */
562 for (int physport = 0; physport < 2; ++physport) {
563 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
565 if (physical_output.length()) {
566 if (_click_io->add_port (physical_output, this)) {
567 // relax, even though its an error
572 if (_click_io->n_ports () > ChanCount::ZERO) {
573 _clicking = Config->get_clicking ();
578 catch (failed_constructor& err) {
579 error << _("cannot setup Click I/O") << endmsg;
582 BootMessage (_("Compute I/O Latencies"));
584 set_worst_io_latencies ();
587 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
590 BootMessage (_("Set up standard connections"));
592 /* Create a set of Bundle objects that map
593 to the physical I/O currently available. We create both
594 mono and stereo bundles, so that the common cases of mono
595 and stereo tracks get bundles to put in their mixer strip
596 in / out menus. There may be a nicer way of achieving that;
597 it doesn't really scale that well to higher channel counts
600 /* mono output bundles */
602 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
604 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
606 shared_ptr<Bundle> c (new Bundle (buf, true));
607 c->add_channel (_("mono"));
608 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
613 /* stereo output bundles */
615 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
616 if (np + 1 < n_physical_outputs) {
618 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
619 shared_ptr<Bundle> c (new Bundle (buf, true));
620 c->add_channel (_("L"));
621 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
622 c->add_channel (_("R"));
623 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
629 /* mono input bundles */
631 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
633 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
635 shared_ptr<Bundle> c (new Bundle (buf, false));
636 c->add_channel (_("mono"));
637 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
642 /* stereo input bundles */
644 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
645 if (np + 1 < n_physical_inputs) {
647 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
649 shared_ptr<Bundle> c (new Bundle (buf, false));
650 c->add_channel (_("L"));
651 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
652 c->add_channel (_("R"));
653 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
659 BootMessage (_("Setup signal flow and plugins"));
663 if (!no_auto_connect()) {
665 if (_master_out && Config->get_auto_connect_standard_busses()) {
667 /* if requested auto-connect the outputs to the first N physical ports.
670 uint32_t limit = _master_out->n_outputs().n_total();
672 for (uint32_t n = 0; n < limit; ++n) {
673 Port* p = _master_out->output()->nth (n);
674 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
676 if (!connect_to.empty()) {
677 if (_master_out->output()->connect (p, connect_to, this)) {
678 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
688 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
689 are undefined, at best.
692 /* control out listens to master bus (but ignores it
693 under some conditions)
696 uint32_t limit = _control_out->n_inputs().n_audio();
699 for (uint32_t n = 0; n < limit; ++n) {
700 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
701 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
704 string connect_to = o->name();
705 if (_control_out->input()->connect (p, connect_to, this)) {
706 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
714 /* if control out is not connected,
715 connect control out to physical outs, but use ones after the master if possible
718 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
720 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
722 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
725 _control_out->output()->connect_ports_to_bundle (b, this);
727 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
728 Config->get_monitor_bus_preferred_bundle())
734 /* XXX this logic is wrong for mixed port types */
736 uint32_t shift = _master_out->n_outputs().n_audio();
737 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
738 limit = _control_out->n_outputs().n_audio();
740 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
742 for (uint32_t n = 0; n < limit; ++n) {
744 Port* p = _control_out->output()->nth (n);
745 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
747 if (!connect_to.empty()) {
748 if (_control_out->output()->connect (p, connect_to, this)) {
749 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
760 /* catch up on send+insert cnts */
762 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
764 /* hook us up to the engine */
766 BootMessage (_("Connect to engine"));
768 _engine.set_session (this);
772 Session::hookup_io ()
774 /* stop graph reordering notifications from
775 causing resorts, etc.
778 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
783 /* we delay creating the auditioner till now because
784 it makes its own connections to ports.
785 the engine has to be running for this to work.
789 auditioner.reset (new Auditioner (*this));
792 catch (failed_constructor& err) {
793 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
797 /* load bundles, which we may have postponed earlier on */
798 if (_bundle_xml_node) {
799 load_bundles (*_bundle_xml_node);
800 delete _bundle_xml_node;
803 /* Tell all IO objects to connect themselves together */
805 IO::enable_connecting ();
807 /* Now reset all panners */
809 Delivery::reset_panners ();
811 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
815 boost::shared_ptr<RouteList> r = routes.reader ();
817 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
819 if ((*x)->is_control() || (*x)->is_master()) {
823 (*x)->listen_via (_control_out,
824 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
829 /* Anyone who cares about input state, wake up and do something */
831 IOConnectionsComplete (); /* EMIT SIGNAL */
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
835 /* now handle the whole enchilada as if it was one
841 /* update the full solo state, which can't be
842 correctly determined on a per-route basis, but
843 needs the global overview that only the session
847 update_route_solo_state ();
851 Session::playlist_length_changed ()
853 /* we can't just increase end_location->end() if pl->get_maximum_extent()
854 if larger. if the playlist used to be the longest playlist,
855 and its now shorter, we have to decrease end_location->end(). hence,
856 we have to iterate over all diskstreams and check the
857 playlists currently in use.
863 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
865 boost::shared_ptr<Playlist> playlist;
867 if ((playlist = dstream->playlist()) != 0) {
868 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
871 /* see comment in playlist_length_changed () */
876 Session::record_enabling_legal () const
878 /* this used to be in here, but survey says.... we don't need to restrict it */
879 // if (record_status() == Recording) {
883 if (Config->get_all_safe()) {
890 Session::reset_input_monitor_state ()
892 if (transport_rolling()) {
894 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
896 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
897 if ((*i)->record_enabled ()) {
898 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
899 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
903 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
905 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
906 if ((*i)->record_enabled ()) {
907 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
908 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
915 Session::auto_punch_start_changed (Location* location)
917 replace_event (Event::PunchIn, location->start());
919 if (get_record_enabled() && config.get_punch_in()) {
920 /* capture start has been changed, so save new pending state */
921 save_state ("", true);
926 Session::auto_punch_end_changed (Location* location)
928 nframes_t when_to_stop = location->end();
929 // when_to_stop += _worst_output_latency + _worst_input_latency;
930 replace_event (Event::PunchOut, when_to_stop);
934 Session::auto_punch_changed (Location* location)
936 nframes_t when_to_stop = location->end();
938 replace_event (Event::PunchIn, location->start());
939 //when_to_stop += _worst_output_latency + _worst_input_latency;
940 replace_event (Event::PunchOut, when_to_stop);
944 Session::auto_loop_changed (Location* location)
946 replace_event (Event::AutoLoop, location->end(), location->start());
948 if (transport_rolling() && play_loop) {
950 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
952 if (_transport_frame > location->end()) {
953 // relocate to beginning of loop
954 clear_events (Event::LocateRoll);
956 request_locate (location->start(), true);
959 else if (Config->get_seamless_loop() && !loop_changing) {
961 // schedule a locate-roll to refill the diskstreams at the
963 loop_changing = true;
965 if (location->end() > last_loopend) {
966 clear_events (Event::LocateRoll);
967 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
974 last_loopend = location->end();
978 Session::set_auto_punch_location (Location* location)
982 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
983 auto_punch_start_changed_connection.disconnect();
984 auto_punch_end_changed_connection.disconnect();
985 auto_punch_changed_connection.disconnect();
986 existing->set_auto_punch (false, this);
987 remove_event (existing->start(), Event::PunchIn);
988 clear_events (Event::PunchOut);
989 auto_punch_location_changed (0);
998 if (location->end() <= location->start()) {
999 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1003 auto_punch_start_changed_connection.disconnect();
1004 auto_punch_end_changed_connection.disconnect();
1005 auto_punch_changed_connection.disconnect();
1007 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1008 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1009 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1011 location->set_auto_punch (true, this);
1014 auto_punch_changed (location);
1016 auto_punch_location_changed (location);
1020 Session::set_auto_loop_location (Location* location)
1024 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1025 auto_loop_start_changed_connection.disconnect();
1026 auto_loop_end_changed_connection.disconnect();
1027 auto_loop_changed_connection.disconnect();
1028 existing->set_auto_loop (false, this);
1029 remove_event (existing->end(), Event::AutoLoop);
1030 auto_loop_location_changed (0);
1035 if (location == 0) {
1039 if (location->end() <= location->start()) {
1040 error << _("Session: you can't use a mark for auto loop") << endmsg;
1044 last_loopend = location->end();
1046 auto_loop_start_changed_connection.disconnect();
1047 auto_loop_end_changed_connection.disconnect();
1048 auto_loop_changed_connection.disconnect();
1050 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1051 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1052 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1054 location->set_auto_loop (true, this);
1056 /* take care of our stuff first */
1058 auto_loop_changed (location);
1060 /* now tell everyone else */
1062 auto_loop_location_changed (location);
1066 Session::locations_added (Location* ignored)
1072 Session::locations_changed ()
1074 _locations.apply (*this, &Session::handle_locations_changed);
1078 Session::handle_locations_changed (Locations::LocationList& locations)
1080 Locations::LocationList::iterator i;
1082 bool set_loop = false;
1083 bool set_punch = false;
1085 for (i = locations.begin(); i != locations.end(); ++i) {
1089 if (location->is_auto_punch()) {
1090 set_auto_punch_location (location);
1093 if (location->is_auto_loop()) {
1094 set_auto_loop_location (location);
1098 if (location->is_start()) {
1099 start_location = location;
1101 if (location->is_end()) {
1102 end_location = location;
1107 set_auto_loop_location (0);
1110 set_auto_punch_location (0);
1117 Session::enable_record ()
1119 /* XXX really atomic compare+swap here */
1120 if (g_atomic_int_get (&_record_status) != Recording) {
1121 g_atomic_int_set (&_record_status, Recording);
1122 _last_record_location = _transport_frame;
1123 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1125 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1126 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1127 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1128 if ((*i)->record_enabled ()) {
1129 (*i)->monitor_input (true);
1134 RecordStateChanged ();
1139 Session::disable_record (bool rt_context, bool force)
1143 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1145 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1146 g_atomic_int_set (&_record_status, Disabled);
1148 if (rs == Recording) {
1149 g_atomic_int_set (&_record_status, Enabled);
1153 // FIXME: timestamp correct? [DR]
1154 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1155 // does this /need/ to be sent in all cases?
1157 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1159 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1160 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1162 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1163 if ((*i)->record_enabled ()) {
1164 (*i)->monitor_input (false);
1169 RecordStateChanged (); /* emit signal */
1172 remove_pending_capture_state ();
1178 Session::step_back_from_record ()
1180 /* XXX really atomic compare+swap here */
1181 if (g_atomic_int_get (&_record_status) == Recording) {
1182 g_atomic_int_set (&_record_status, Enabled);
1184 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1185 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1187 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1188 if ((*i)->record_enabled ()) {
1189 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1190 (*i)->monitor_input (false);
1198 Session::maybe_enable_record ()
1200 g_atomic_int_set (&_record_status, Enabled);
1202 /* this function is currently called from somewhere other than an RT thread.
1203 this save_state() call therefore doesn't impact anything.
1206 save_state ("", true);
1208 if (_transport_speed) {
1209 if (!config.get_punch_in()) {
1213 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1214 RecordStateChanged (); /* EMIT SIGNAL */
1221 Session::audible_frame () const
1227 /* the first of these two possible settings for "offset"
1228 mean that the audible frame is stationary until
1229 audio emerges from the latency compensation
1232 the second means that the audible frame is stationary
1233 until audio would emerge from a physical port
1234 in the absence of any plugin latency compensation
1237 offset = _worst_output_latency;
1239 if (offset > current_block_size) {
1240 offset -= current_block_size;
1242 /* XXX is this correct? if we have no external
1243 physical connections and everything is internal
1244 then surely this is zero? still, how
1245 likely is that anyway?
1247 offset = current_block_size;
1250 if (synced_to_jack()) {
1251 tf = _engine.transport_frame();
1253 tf = _transport_frame;
1258 if (!non_realtime_work_pending()) {
1262 /* check to see if we have passed the first guaranteed
1263 audible frame past our last start position. if not,
1264 return that last start point because in terms
1265 of audible frames, we have not moved yet.
1268 if (_transport_speed > 0.0f) {
1270 if (!play_loop || !have_looped) {
1271 if (tf < _last_roll_location + offset) {
1272 return _last_roll_location;
1280 } else if (_transport_speed < 0.0f) {
1282 /* XXX wot? no backward looping? */
1284 if (tf > _last_roll_location - offset) {
1285 return _last_roll_location;
1297 Session::set_frame_rate (nframes_t frames_per_second)
1299 /** \fn void Session::set_frame_size(nframes_t)
1300 the AudioEngine object that calls this guarantees
1301 that it will not be called while we are also in
1302 ::process(). Its fine to do things that block
1306 _base_frame_rate = frames_per_second;
1310 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1314 // XXX we need some equivalent to this, somehow
1315 // SndFileSource::setup_standard_crossfades (frames_per_second);
1319 /* XXX need to reset/reinstantiate all LADSPA plugins */
1323 Session::set_block_size (nframes_t nframes)
1325 /* the AudioEngine guarantees
1326 that it will not be called while we are also in
1327 ::process(). It is therefore fine to do things that block
1332 current_block_size = nframes;
1334 ensure_buffers(_scratch_buffers->available());
1336 delete [] _gain_automation_buffer;
1337 _gain_automation_buffer = new gain_t[nframes];
1339 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1341 boost::shared_ptr<RouteList> r = routes.reader ();
1343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1344 (*i)->set_block_size (nframes);
1347 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1348 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1349 (*i)->set_block_size (nframes);
1352 set_worst_io_latencies ();
1357 Session::set_default_fade (float steepness, float fade_msecs)
1360 nframes_t fade_frames;
1362 /* Don't allow fade of less 1 frame */
1364 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1371 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1375 default_fade_msecs = fade_msecs;
1376 default_fade_steepness = steepness;
1379 // jlc, WTF is this!
1380 Glib::RWLock::ReaderLock lm (route_lock);
1381 AudioRegion::set_default_fade (steepness, fade_frames);
1386 /* XXX have to do this at some point */
1387 /* foreach region using default fade, reset, then
1388 refill_all_diskstream_buffers ();
1393 struct RouteSorter {
1394 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1395 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1397 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1400 if (r1->fed_by.empty()) {
1401 if (r2->fed_by.empty()) {
1402 /* no ardour-based connections inbound to either route. just use signal order */
1403 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1405 /* r2 has connections, r1 does not; run r1 early */
1409 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1416 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1418 shared_ptr<Route> r2;
1420 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1421 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1425 /* make a copy of the existing list of routes that feed r1 */
1427 set<shared_ptr<Route> > existing = r1->fed_by;
1429 /* for each route that feeds r1, recurse, marking it as feeding
1433 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1436 /* r2 is a route that feeds r1 which somehow feeds base. mark
1437 base as being fed by r2
1440 rbase->fed_by.insert (r2);
1444 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1448 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1452 /* now recurse, so that we can mark base as being fed by
1453 all routes that feed r2
1456 trace_terminal (r2, rbase);
1463 Session::resort_routes ()
1465 /* don't do anything here with signals emitted
1466 by Routes while we are being destroyed.
1469 if (_state_of_the_state & Deletion) {
1476 RCUWriter<RouteList> writer (routes);
1477 shared_ptr<RouteList> r = writer.get_copy ();
1478 resort_routes_using (r);
1479 /* writer goes out of scope and forces update */
1484 Session::resort_routes_using (shared_ptr<RouteList> r)
1486 RouteList::iterator i, j;
1488 for (i = r->begin(); i != r->end(); ++i) {
1490 (*i)->fed_by.clear ();
1492 for (j = r->begin(); j != r->end(); ++j) {
1494 /* although routes can feed themselves, it will
1495 cause an endless recursive descent if we
1496 detect it. so don't bother checking for
1504 if ((*j)->feeds (*i)) {
1505 (*i)->fed_by.insert (*j);
1510 for (i = r->begin(); i != r->end(); ++i) {
1511 trace_terminal (*i, *i);
1518 cerr << "finished route resort\n";
1520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1521 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1528 list<boost::shared_ptr<MidiTrack> >
1529 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1531 char track_name[32];
1532 uint32_t track_id = 0;
1535 RouteList new_routes;
1536 list<boost::shared_ptr<MidiTrack> > ret;
1537 //uint32_t control_id;
1539 // FIXME: need physical I/O and autoconnect stuff for MIDI
1541 /* count existing midi tracks */
1544 shared_ptr<RouteList> r = routes.reader ();
1546 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1547 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1548 if (!(*i)->is_hidden()) {
1550 //channels_used += (*i)->n_inputs().n_midi();
1556 vector<string> physinputs;
1557 vector<string> physoutputs;
1559 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1560 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1562 // control_id = ntracks() + nbusses();
1566 /* check for duplicate route names, since we might have pre-existing
1567 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1568 save, close,restart,add new route - first named route is now
1576 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1578 if (route_by_name (track_name) == 0) {
1582 } while (track_id < (UINT_MAX-1));
1584 shared_ptr<MidiTrack> track;
1587 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1589 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1590 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1595 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, 1), false, this)) {
1596 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1602 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1606 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1607 port = physinputs[(channels_used+x)%nphysical_in];
1610 if (port.length() && track->connect_input (track->input (x), port, this)) {
1616 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1620 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1621 port = physoutputs[(channels_used+x)%nphysical_out];
1622 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1624 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1628 if (port.length() && track->connect_output (track->output (x), port, this)) {
1633 channels_used += track->n_inputs ().n_midi();
1637 track->midi_diskstream()->non_realtime_input_change();
1638 track->set_route_group (route_group, 0);
1640 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1641 //track->set_remote_control_id (control_id);
1643 new_routes.push_back (track);
1644 ret.push_back (track);
1647 catch (failed_constructor &err) {
1648 error << _("Session: could not create new midi track.") << endmsg;
1651 /* we need to get rid of this, since the track failed to be created */
1652 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1655 RCUWriter<DiskstreamList> writer (diskstreams);
1656 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1657 ds->remove (track->midi_diskstream());
1664 catch (AudioEngine::PortRegistrationFailure& pfe) {
1666 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;
1669 /* we need to get rid of this, since the track failed to be created */
1670 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1673 RCUWriter<DiskstreamList> writer (diskstreams);
1674 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1675 ds->remove (track->midi_diskstream());
1686 if (!new_routes.empty()) {
1687 add_routes (new_routes, false);
1688 save_state (_current_snapshot_name);
1694 list<boost::shared_ptr<AudioTrack> >
1695 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1697 char track_name[32];
1698 uint32_t track_id = 0;
1700 uint32_t channels_used = 0;
1702 RouteList new_routes;
1703 list<boost::shared_ptr<AudioTrack> > ret;
1704 uint32_t control_id;
1706 /* count existing audio tracks */
1709 shared_ptr<RouteList> r = routes.reader ();
1711 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1712 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1713 if (!(*i)->is_hidden()) {
1715 channels_used += (*i)->n_inputs().n_audio();
1721 vector<string> physinputs;
1722 vector<string> physoutputs;
1724 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1725 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1727 control_id = ntracks() + nbusses() + 1;
1731 /* check for duplicate route names, since we might have pre-existing
1732 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1733 save, close,restart,add new route - first named route is now
1741 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1743 if (route_by_name (track_name) == 0) {
1747 } while (track_id < (UINT_MAX-1));
1749 shared_ptr<AudioTrack> track;
1752 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1754 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1755 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1756 input_channels, output_channels)
1761 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1762 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1763 input_channels, output_channels)
1768 if (!physinputs.empty()) {
1769 uint32_t nphysical_in = physinputs.size();
1771 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1775 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1776 port = physinputs[(channels_used+x)%nphysical_in];
1779 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1785 if (!physoutputs.empty()) {
1786 uint32_t nphysical_out = physoutputs.size();
1788 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1791 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1792 port = physoutputs[(channels_used+x)%nphysical_out];
1793 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1794 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1795 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1799 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1805 channels_used += track->n_inputs ().n_audio();
1807 track->set_route_group (route_group, 0);
1809 track->audio_diskstream()->non_realtime_input_change();
1811 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1812 track->set_remote_control_id (control_id);
1815 new_routes.push_back (track);
1816 ret.push_back (track);
1819 catch (failed_constructor &err) {
1820 error << _("Session: could not create new audio track.") << endmsg;
1823 /* we need to get rid of this, since the track failed to be created */
1824 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1827 RCUWriter<DiskstreamList> writer (diskstreams);
1828 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1829 ds->remove (track->audio_diskstream());
1836 catch (AudioEngine::PortRegistrationFailure& pfe) {
1838 error << pfe.what() << endmsg;
1841 /* we need to get rid of this, since the track failed to be created */
1842 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1845 RCUWriter<DiskstreamList> writer (diskstreams);
1846 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1847 ds->remove (track->audio_diskstream());
1858 if (!new_routes.empty()) {
1859 add_routes (new_routes, true);
1866 Session::set_remote_control_ids ()
1868 RemoteModel m = Config->get_remote_model();
1870 shared_ptr<RouteList> r = routes.reader ();
1872 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1873 if ( MixerOrdered == m) {
1874 long order = (*i)->order_key(N_("signal"));
1875 (*i)->set_remote_control_id( order+1 );
1876 } else if ( EditorOrdered == m) {
1877 long order = (*i)->order_key(N_("editor"));
1878 (*i)->set_remote_control_id( order+1 );
1879 } else if ( UserOrdered == m) {
1880 //do nothing ... only changes to remote id's are initiated by user
1887 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1890 uint32_t bus_id = 1;
1892 uint32_t channels_used = 0;
1895 uint32_t control_id;
1897 /* count existing audio busses */
1900 shared_ptr<RouteList> r = routes.reader ();
1902 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1903 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1905 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1908 channels_used += (*i)->n_inputs().n_audio();
1914 vector<string> physinputs;
1915 vector<string> physoutputs;
1917 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1918 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1920 n_physical_audio_outputs = physoutputs.size();
1921 n_physical_audio_inputs = physinputs.size();
1923 control_id = ntracks() + nbusses() + 1;
1928 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1932 if (route_by_name (bus_name) == 0) {
1936 } while (bus_id < (UINT_MAX-1));
1939 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1941 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1942 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1943 input_channels, output_channels)
1949 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1950 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1951 input_channels, output_channels)
1956 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1959 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1960 port = physinputs[((n+x)%n_physical_audio_inputs)];
1963 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1968 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1971 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1972 port = physoutputs[((n+x)%n_physical_outputs)];
1973 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1975 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1979 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1984 channels_used += bus->n_inputs ().n_audio();
1986 bus->set_route_group (route_group, 0);
1987 bus->set_remote_control_id (control_id);
1990 ret.push_back (bus);
1994 catch (failed_constructor &err) {
1995 error << _("Session: could not create new audio route.") << endmsg;
1999 catch (AudioEngine::PortRegistrationFailure& pfe) {
2000 error << pfe.what() << endmsg;
2010 add_routes (ret, true);
2018 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2022 uint32_t control_id;
2024 uint32_t number = 1;
2026 if (!tree.read (template_path.c_str())) {
2030 XMLNode* node = tree.root();
2032 control_id = ntracks() + nbusses() + 1;
2036 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2038 std::string node_name = IO::name_from_state (*node_copy.children().front());
2040 /* generate a new name by adding a number to the end of the template name */
2043 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2047 if (route_by_name (name) == 0) {
2051 } while (number < UINT_MAX);
2053 if (number == UINT_MAX) {
2054 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2058 IO::set_name_in_state (*node_copy.children().front(), name);
2060 Track::zero_diskstream_id_in_xml (node_copy);
2063 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2066 error << _("Session: cannot create track/bus from template description") << endmsg;
2070 if (boost::dynamic_pointer_cast<Track>(route)) {
2071 /* force input/output change signals so that the new diskstream
2072 picks up the configuration of the route. During session
2073 loading this normally happens in a different way.
2075 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2076 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2079 route->set_remote_control_id (control_id);
2082 ret.push_back (route);
2085 catch (failed_constructor &err) {
2086 error << _("Session: could not create new route from template") << endmsg;
2090 catch (AudioEngine::PortRegistrationFailure& pfe) {
2091 error << pfe.what() << endmsg;
2100 add_routes (ret, true);
2107 Session::add_routes (RouteList& new_routes, bool save)
2110 RCUWriter<RouteList> writer (routes);
2111 shared_ptr<RouteList> r = writer.get_copy ();
2112 r->insert (r->end(), new_routes.begin(), new_routes.end());
2115 /* if there is no control out and we're not in the middle of loading,
2116 resort the graph here. if there is a control out, we will resort
2117 toward the end of this method. if we are in the middle of loading,
2118 we will resort when done.
2121 if (!_control_out && IO::connecting_legal) {
2122 resort_routes_using (r);
2126 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2128 boost::weak_ptr<Route> wpr (*x);
2130 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2131 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2132 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2133 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2134 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2135 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2137 if ((*x)->is_master()) {
2141 if ((*x)->is_control()) {
2142 _control_out = (*x);
2146 if (_control_out && IO::connecting_legal) {
2148 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2149 if ((*x)->is_control() || (*x)->is_master()) {
2152 (*x)->listen_via (_control_out,
2153 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2163 save_state (_current_snapshot_name);
2166 RouteAdded (new_routes); /* EMIT SIGNAL */
2170 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2172 boost::shared_ptr<RouteList> r = routes.reader ();
2173 boost::shared_ptr<RouteList> t (new RouteList);
2175 /* only send tracks */
2177 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2178 if (boost::dynamic_pointer_cast<Track>(*i)) {
2183 add_internal_sends (dest, p, t);
2187 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2189 if (dest->is_control() || dest->is_master()) {
2193 if (!dest->internal_return()) {
2194 dest->add_internal_return();
2197 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2199 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2203 (*i)->listen_via (dest, p, true, true);
2208 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2210 /* need to do this in case we're rolling at the time, to prevent false underruns */
2211 dstream->do_refill_with_alloc ();
2213 dstream->set_block_size (current_block_size);
2216 RCUWriter<DiskstreamList> writer (diskstreams);
2217 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2218 ds->push_back (dstream);
2219 /* writer goes out of scope, copies ds back to main */
2222 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2223 /* this will connect to future changes, and check the current length */
2224 diskstream_playlist_changed (dstream);
2226 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2228 dstream->prepare ();
2233 Session::remove_route (shared_ptr<Route> route)
2236 RCUWriter<RouteList> writer (routes);
2237 shared_ptr<RouteList> rs = writer.get_copy ();
2241 /* deleting the master out seems like a dumb
2242 idea, but its more of a UI policy issue
2246 if (route == _master_out) {
2247 _master_out = shared_ptr<Route> ();
2250 if (route == _control_out) {
2252 /* cancel control outs for all routes */
2254 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2255 (*r)->drop_listen (_control_out);
2258 _control_out.reset ();
2261 update_route_solo_state ();
2263 /* writer goes out of scope, forces route list update */
2266 boost::shared_ptr<Track> t;
2267 boost::shared_ptr<Diskstream> ds;
2269 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2270 ds = t->diskstream();
2276 RCUWriter<DiskstreamList> dsl (diskstreams);
2277 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2282 find_current_end ();
2284 // We need to disconnect the routes inputs and outputs
2286 route->input()->disconnect (0);
2287 route->output()->disconnect (0);
2289 update_latency_compensation (false, false);
2292 /* get rid of it from the dead wood collection in the route list manager */
2294 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2298 /* try to cause everyone to drop their references */
2300 route->drop_references ();
2302 sync_order_keys (N_("session"));
2304 /* save the new state of the world */
2306 if (save_state (_current_snapshot_name)) {
2307 save_history (_current_snapshot_name);
2312 Session::route_mute_changed (void* src)
2318 Session::route_listen_changed (void* src, boost::weak_ptr<Route> wpr)
2320 boost::shared_ptr<Route> route = wpr.lock();
2322 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2326 if (route->listening()) {
2328 } else if (_listen_cnt > 0) {
2334 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2336 if (solo_update_disabled) {
2341 boost::shared_ptr<Route> route = wpr.lock ();
2344 /* should not happen */
2345 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2349 shared_ptr<RouteList> r = routes.reader ();
2352 if (route->soloed()) {
2358 /* now mod the solo level of all other routes except master & control outs
2359 so that they will be silent if appropriate.
2362 solo_update_disabled = true;
2363 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2365 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2367 (*i)->mod_solo_level (delta);
2371 /* make sure master is never muted by solo */
2373 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2374 _master_out->mod_solo_level (1);
2377 /* ditto for control outs make sure master is never muted by solo */
2379 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2380 _control_out->mod_solo_level (1);
2383 solo_update_disabled = false;
2384 update_route_solo_state (r);
2385 SoloChanged (); /* EMIT SIGNAL */
2390 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2392 /* now figure out if anything that matters is soloed */
2394 bool something_soloed = false;
2397 r = routes.reader();
2400 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2401 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2402 something_soloed = true;
2407 if (something_soloed != _non_soloed_outs_muted) {
2408 _non_soloed_outs_muted = something_soloed;
2409 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2414 Session::route_by_name (string name)
2416 shared_ptr<RouteList> r = routes.reader ();
2418 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2419 if ((*i)->name() == name) {
2424 return shared_ptr<Route> ((Route*) 0);
2428 Session::route_by_id (PBD::ID id)
2430 shared_ptr<RouteList> r = routes.reader ();
2432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2433 if ((*i)->id() == id) {
2438 return shared_ptr<Route> ((Route*) 0);
2442 Session::route_by_remote_id (uint32_t id)
2444 shared_ptr<RouteList> r = routes.reader ();
2446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2447 if ((*i)->remote_control_id() == id) {
2452 return shared_ptr<Route> ((Route*) 0);
2456 Session::find_current_end ()
2458 if (_state_of_the_state & Loading) {
2462 nframes_t max = get_maximum_extent ();
2464 if (max > end_location->end()) {
2465 end_location->set_end (max);
2467 DurationChanged(); /* EMIT SIGNAL */
2472 Session::get_maximum_extent () const
2477 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2479 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2480 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2482 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2483 if ((me = pl->get_maximum_extent()) > max) {
2491 boost::shared_ptr<Diskstream>
2492 Session::diskstream_by_name (string name)
2494 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2496 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2497 if ((*i)->name() == name) {
2502 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2505 boost::shared_ptr<Diskstream>
2506 Session::diskstream_by_id (const PBD::ID& id)
2508 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2510 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2511 if ((*i)->id() == id) {
2516 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2519 /* Region management */
2522 Session::new_region_name (string old)
2524 string::size_type last_period;
2526 string::size_type len = old.length() + 64;
2529 if ((last_period = old.find_last_of ('.')) == string::npos) {
2531 /* no period present - add one explicitly */
2534 last_period = old.length() - 1;
2539 number = atoi (old.substr (last_period+1).c_str());
2543 while (number < (UINT_MAX-1)) {
2545 RegionList::const_iterator i;
2550 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2553 for (i = regions.begin(); i != regions.end(); ++i) {
2554 if (i->second->name() == sbuf) {
2559 if (i == regions.end()) {
2564 if (number != (UINT_MAX-1)) {
2568 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2573 Session::region_name (string& result, string base, bool newlevel)
2578 if (base.find("/") != string::npos) {
2579 base = base.substr(base.find_last_of("/") + 1);
2584 Glib::Mutex::Lock lm (region_lock);
2586 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2595 string::size_type pos;
2597 pos = base.find_last_of ('.');
2599 /* pos may be npos, but then we just use entire base */
2601 subbase = base.substr (0, pos);
2606 Glib::Mutex::Lock lm (region_lock);
2608 map<string,uint32_t>::iterator x;
2612 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2614 region_name_map[subbase] = 1;
2617 snprintf (buf, sizeof (buf), ".%d", x->second);
2628 Session::add_region (boost::shared_ptr<Region> region)
2630 vector<boost::shared_ptr<Region> > v;
2631 v.push_back (region);
2636 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2641 Glib::Mutex::Lock lm (region_lock);
2643 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2645 boost::shared_ptr<Region> region = *ii;
2649 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2653 RegionList::iterator x;
2655 for (x = regions.begin(); x != regions.end(); ++x) {
2657 if (region->region_list_equivalent (x->second)) {
2662 if (x == regions.end()) {
2664 pair<RegionList::key_type,RegionList::mapped_type> entry;
2666 entry.first = region->id();
2667 entry.second = region;
2669 pair<RegionList::iterator,bool> x = regions.insert (entry);
2681 /* mark dirty because something has changed even if we didn't
2682 add the region to the region list.
2689 vector<boost::weak_ptr<Region> > v;
2690 boost::shared_ptr<Region> first_r;
2692 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2694 boost::shared_ptr<Region> region = *ii;
2698 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2701 v.push_back (region);
2708 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2709 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2711 update_region_name_map (region);
2715 RegionsAdded (v); /* EMIT SIGNAL */
2721 Session::update_region_name_map (boost::shared_ptr<Region> region)
2723 string::size_type last_period = region->name().find_last_of ('.');
2725 if (last_period != string::npos && last_period < region->name().length() - 1) {
2727 string base = region->name().substr (0, last_period);
2728 string number = region->name().substr (last_period+1);
2729 map<string,uint32_t>::iterator x;
2731 /* note that if there is no number, we get zero from atoi,
2735 region_name_map[base] = atoi (number);
2740 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2742 boost::shared_ptr<Region> region (weak_region.lock ());
2748 if (what_changed & Region::HiddenChanged) {
2749 /* relay hidden changes */
2750 RegionHiddenChange (region);
2753 if (what_changed & NameChanged) {
2754 update_region_name_map (region);
2759 Session::remove_region (boost::weak_ptr<Region> weak_region)
2761 RegionList::iterator i;
2762 boost::shared_ptr<Region> region (weak_region.lock ());
2768 bool removed = false;
2771 Glib::Mutex::Lock lm (region_lock);
2773 if ((i = regions.find (region->id())) != regions.end()) {
2779 /* mark dirty because something has changed even if we didn't
2780 remove the region from the region list.
2786 RegionRemoved(region); /* EMIT SIGNAL */
2790 boost::shared_ptr<Region>
2791 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2793 RegionList::iterator i;
2794 boost::shared_ptr<Region> region;
2796 Glib::Mutex::Lock lm (region_lock);
2798 for (i = regions.begin(); i != regions.end(); ++i) {
2802 if (region->whole_file()) {
2804 if (child->source_equivalent (region)) {
2810 return boost::shared_ptr<Region> ();
2814 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2816 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2817 (*i)->get_region_list_equivalent_regions (region, result);
2821 Session::destroy_region (boost::shared_ptr<Region> region)
2823 vector<boost::shared_ptr<Source> > srcs;
2826 if (region->playlist()) {
2827 region->playlist()->destroy_region (region);
2830 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2831 srcs.push_back (region->source (n));
2835 region->drop_references ();
2837 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2839 (*i)->mark_for_remove ();
2840 (*i)->drop_references ();
2842 cerr << "source was not used by any playlist\n";
2849 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2851 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2852 destroy_region (*i);
2858 Session::remove_last_capture ()
2860 list<boost::shared_ptr<Region> > r;
2862 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2864 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2865 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2868 r.insert (r.end(), l.begin(), l.end());
2873 destroy_regions (r);
2875 save_state (_current_snapshot_name);
2881 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2887 /* Source Management */
2890 Session::add_source (boost::shared_ptr<Source> source)
2892 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2893 pair<SourceMap::iterator,bool> result;
2895 entry.first = source->id();
2896 entry.second = source;
2899 Glib::Mutex::Lock lm (source_lock);
2900 result = sources.insert (entry);
2903 if (result.second) {
2904 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2908 boost::shared_ptr<AudioFileSource> afs;
2910 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2911 if (Config->get_auto_analyse_audio()) {
2912 Analyser::queue_source_for_analysis (source, false);
2918 Session::remove_source (boost::weak_ptr<Source> src)
2920 SourceMap::iterator i;
2921 boost::shared_ptr<Source> source = src.lock();
2928 Glib::Mutex::Lock lm (source_lock);
2930 if ((i = sources.find (source->id())) != sources.end()) {
2935 if (!_state_of_the_state & InCleanup) {
2937 /* save state so we don't end up with a session file
2938 referring to non-existent sources.
2941 save_state (_current_snapshot_name);
2945 boost::shared_ptr<Source>
2946 Session::source_by_id (const PBD::ID& id)
2948 Glib::Mutex::Lock lm (source_lock);
2949 SourceMap::iterator i;
2950 boost::shared_ptr<Source> source;
2952 if ((i = sources.find (id)) != sources.end()) {
2959 boost::shared_ptr<Source>
2960 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2962 Glib::Mutex::Lock lm (source_lock);
2964 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2965 cerr << "comparing " << path << " with " << i->second->name() << endl;
2966 boost::shared_ptr<AudioFileSource> afs
2967 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2969 if (afs && afs->path() == path && chn == afs->channel()) {
2973 return boost::shared_ptr<Source>();
2978 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2981 string old_basename = PBD::basename_nosuffix (oldname);
2982 string new_legalized = legalize_for_path (newname);
2984 /* note: we know (or assume) the old path is already valid */
2988 /* destructive file sources have a name of the form:
2990 /path/to/Tnnnn-NAME(%[LR])?.wav
2992 the task here is to replace NAME with the new name.
2995 /* find last slash */
2999 string::size_type slash;
3000 string::size_type dash;
3002 if ((slash = path.find_last_of ('/')) == string::npos) {
3006 dir = path.substr (0, slash+1);
3008 /* '-' is not a legal character for the NAME part of the path */
3010 if ((dash = path.find_last_of ('-')) == string::npos) {
3014 prefix = path.substr (slash+1, dash-(slash+1));
3019 path += new_legalized;
3020 path += ".wav"; /* XXX gag me with a spoon */
3024 /* non-destructive file sources have a name of the form:
3026 /path/to/NAME-nnnnn(%[LR])?.ext
3028 the task here is to replace NAME with the new name.
3033 string::size_type slash;
3034 string::size_type dash;
3035 string::size_type postfix;
3037 /* find last slash */
3039 if ((slash = path.find_last_of ('/')) == string::npos) {
3043 dir = path.substr (0, slash+1);
3045 /* '-' is not a legal character for the NAME part of the path */
3047 if ((dash = path.find_last_of ('-')) == string::npos) {
3051 suffix = path.substr (dash+1);
3053 // Suffix is now everything after the dash. Now we need to eliminate
3054 // the nnnnn part, which is done by either finding a '%' or a '.'
3056 postfix = suffix.find_last_of ("%");
3057 if (postfix == string::npos) {
3058 postfix = suffix.find_last_of ('.');
3061 if (postfix != string::npos) {
3062 suffix = suffix.substr (postfix);
3064 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3068 const uint32_t limit = 10000;
3069 char buf[PATH_MAX+1];
3071 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3073 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3075 if (access (buf, F_OK) != 0) {
3083 error << "FATAL ERROR! Could not find a " << endl;
3091 /** Return the full path (in some session directory) for a new embedded source.
3092 * \a name must be a session-unique name that does not contain slashes
3093 * (e.g. as returned by new_*_source_name)
3096 Session::new_source_path_from_name (DataType type, const string& name)
3098 assert(name.find("/") == string::npos);
3100 SessionDirectory sdir(get_best_session_directory_for_new_source());
3103 if (type == DataType::AUDIO) {
3104 p = sdir.sound_path();
3105 } else if (type == DataType::MIDI) {
3106 p = sdir.midi_path();
3108 error << "Unknown source type, unable to create file path" << endmsg;
3113 return p.to_string();
3117 Session::peak_path (Glib::ustring base) const
3119 sys::path peakfile_path(_session_dir->peak_path());
3120 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3121 return peakfile_path.to_string();
3124 /** Return a unique name based on \a base for a new internal audio source */
3126 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3130 char buf[PATH_MAX+1];
3131 const uint32_t limit = 10000;
3135 legalized = legalize_for_path (base);
3137 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3138 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3140 vector<space_and_path>::iterator i;
3141 uint32_t existing = 0;
3143 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3145 SessionDirectory sdir((*i).path);
3147 spath = sdir.sound_path().to_string();
3152 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3153 spath.c_str(), cnt, legalized.c_str());
3154 } else if (nchan == 2) {
3156 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3157 spath.c_str(), cnt, legalized.c_str());
3159 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3160 spath.c_str(), cnt, legalized.c_str());
3162 } else if (nchan < 26) {
3163 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3164 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3166 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3167 spath.c_str(), cnt, legalized.c_str());
3176 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3177 } else if (nchan == 2) {
3179 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3181 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3183 } else if (nchan < 26) {
3184 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3186 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3190 if (sys::exists(buf)) {
3196 if (existing == 0) {
3201 error << string_compose(
3202 _("There are already %1 recordings for %2, which I consider too many."),
3203 limit, base) << endmsg;
3205 throw failed_constructor();
3209 return Glib::path_get_basename(buf);
3212 /** Create a new embedded audio source */
3213 boost::shared_ptr<AudioFileSource>
3214 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3216 const size_t n_chans = ds.n_channels().n_audio();
3217 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3218 const string path = new_source_path_from_name(DataType::AUDIO, name);
3219 return boost::dynamic_pointer_cast<AudioFileSource> (
3220 SourceFactory::createWritable (
3221 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3224 /** Return a unique name based on \a base for a new internal MIDI source */
3226 Session::new_midi_source_name (const string& base)
3229 char buf[PATH_MAX+1];
3230 const uint32_t limit = 10000;
3234 legalized = legalize_for_path (base);
3236 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3237 for (cnt = 1; cnt <= limit; ++cnt) {
3239 vector<space_and_path>::iterator i;
3240 uint32_t existing = 0;
3242 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3244 SessionDirectory sdir((*i).path);
3246 sys::path p = sdir.midi_path();
3249 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3251 if (sys::exists (buf)) {
3256 if (existing == 0) {
3261 error << string_compose(
3262 _("There are already %1 recordings for %2, which I consider too many."),
3263 limit, base) << endmsg;
3265 throw failed_constructor();
3269 return Glib::path_get_basename(buf);
3273 /** Create a new embedded MIDI source */
3274 boost::shared_ptr<MidiSource>
3275 Session::create_midi_source_for_session (MidiDiskstream& ds)
3277 const string name = new_midi_source_name (ds.name());
3278 const string path = new_source_path_from_name (DataType::MIDI, name);
3280 return boost::dynamic_pointer_cast<SMFSource> (
3281 SourceFactory::createWritable (
3282 DataType::MIDI, *this, path, true, false, frame_rate()));
3286 /* Playlist management */
3288 boost::shared_ptr<Playlist>
3289 Session::playlist_by_name (string name)
3291 Glib::Mutex::Lock lm (playlist_lock);
3292 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3293 if ((*i)->name() == name) {
3297 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3298 if ((*i)->name() == name) {
3303 return boost::shared_ptr<Playlist>();
3307 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3309 Glib::Mutex::Lock lm (playlist_lock);
3310 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3311 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3312 list.push_back (*i);
3315 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3316 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3317 list.push_back (*i);
3323 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3325 if (playlist->hidden()) {
3330 Glib::Mutex::Lock lm (playlist_lock);
3331 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3332 playlists.insert (playlists.begin(), playlist);
3333 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3334 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3339 playlist->release();
3344 PlaylistAdded (playlist); /* EMIT SIGNAL */
3348 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3351 Glib::Mutex::Lock lm (playlist_lock);
3352 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3355 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3362 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3364 boost::shared_ptr<Playlist> pl(wpl.lock());
3370 PlaylistList::iterator x;
3373 /* its not supposed to be visible */
3378 Glib::Mutex::Lock lm (playlist_lock);
3382 unused_playlists.insert (pl);
3384 if ((x = playlists.find (pl)) != playlists.end()) {
3385 playlists.erase (x);
3391 playlists.insert (pl);
3393 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3394 unused_playlists.erase (x);
3401 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3403 if (_state_of_the_state & Deletion) {
3407 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3414 Glib::Mutex::Lock lm (playlist_lock);
3416 PlaylistList::iterator i;
3418 i = find (playlists.begin(), playlists.end(), playlist);
3419 if (i != playlists.end()) {
3420 playlists.erase (i);
3423 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3424 if (i != unused_playlists.end()) {
3425 unused_playlists.erase (i);
3432 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3436 Session::set_audition (boost::shared_ptr<Region> r)
3438 pending_audition_region = r;
3439 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3440 schedule_butler_transport_work ();
3444 Session::audition_playlist ()
3446 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3447 ev->region.reset ();
3452 Session::non_realtime_set_audition ()
3454 if (!pending_audition_region) {
3455 auditioner->audition_current_playlist ();
3457 auditioner->audition_region (pending_audition_region);
3458 pending_audition_region.reset ();
3460 AuditionActive (true); /* EMIT SIGNAL */
3464 Session::audition_region (boost::shared_ptr<Region> r)
3466 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3472 Session::cancel_audition ()
3474 if (auditioner->active()) {
3475 auditioner->cancel_audition ();
3476 AuditionActive (false); /* EMIT SIGNAL */
3481 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3483 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3487 Session::remove_empty_sounds ()
3489 vector<string> audio_filenames;
3491 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3493 Glib::Mutex::Lock lm (source_lock);
3495 TapeFileMatcher tape_file_matcher;
3497 remove_if (audio_filenames.begin(), audio_filenames.end(),
3498 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3500 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3502 sys::path audio_file_path (_session_dir->sound_path());
3504 audio_file_path /= *i;
3506 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3510 sys::remove (audio_file_path);
3511 const string peakfile = peak_path (audio_file_path.to_string());
3512 sys::remove (peakfile);
3514 catch (const sys::filesystem_error& err)
3516 error << err.what() << endmsg;
3523 Session::is_auditioning () const
3525 /* can be called before we have an auditioner object */
3527 return auditioner->active();
3534 Session::set_all_solo (bool yn)
3536 shared_ptr<RouteList> r = routes.reader ();
3538 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3539 if (!(*i)->is_hidden()) {
3540 (*i)->set_solo (yn, this);
3548 Session::set_all_listen (bool yn)
3550 shared_ptr<RouteList> r = routes.reader ();
3552 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3553 if (!(*i)->is_hidden()) {
3554 (*i)->set_listen (yn, this);
3562 Session::set_all_mute (bool yn)
3564 shared_ptr<RouteList> r = routes.reader ();
3566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3567 if (!(*i)->is_hidden()) {
3568 (*i)->set_mute (yn, this);
3576 Session::n_diskstreams () const
3580 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3582 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3583 if (!(*i)->hidden()) {
3591 Session::graph_reordered ()
3593 /* don't do this stuff if we are setting up connections
3594 from a set_state() call or creating new tracks.
3597 if (_state_of_the_state & InitialConnecting) {
3601 /* every track/bus asked for this to be handled but it was deferred because
3602 we were connecting. do it now.
3605 request_input_change_handling ();
3609 /* force all diskstreams to update their capture offset values to
3610 reflect any changes in latencies within the graph.
3613 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3615 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3616 (*i)->set_capture_offset ();
3621 Session::record_disenable_all ()
3623 record_enable_change_all (false);
3627 Session::record_enable_all ()
3629 record_enable_change_all (true);
3633 Session::record_enable_change_all (bool yn)
3635 shared_ptr<RouteList> r = routes.reader ();
3637 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3638 boost::shared_ptr<Track> t;
3640 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3641 t->set_record_enable (yn, this);
3645 /* since we don't keep rec-enable state, don't mark session dirty */
3649 Session::add_processor (Processor* processor)
3651 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3656 Session::remove_processor (Processor* processor)
3660 PortInsert* port_insert;
3662 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3663 insert_bitset[port_insert->bit_slot()] = false;
3664 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3665 send_bitset[send->bit_slot()] = false;
3666 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3667 return_bitset[send->bit_slot()] = false;
3674 Session::available_capture_duration ()
3676 float sample_bytes_on_disk = 4.0; // keep gcc happy
3678 switch (config.get_native_file_data_format()) {
3680 sample_bytes_on_disk = 4.0;
3684 sample_bytes_on_disk = 3.0;
3688 sample_bytes_on_disk = 2.0;
3692 /* impossible, but keep some gcc versions happy */
3693 fatal << string_compose (_("programming error: %1"),
3694 X_("illegal native file data format"))
3699 double scale = 4096.0 / sample_bytes_on_disk;
3701 if (_total_free_4k_blocks * scale > (double) max_frames) {
3705 return (nframes_t) floor (_total_free_4k_blocks * scale);
3709 Session::add_bundle (shared_ptr<Bundle> bundle)
3712 RCUWriter<BundleList> writer (_bundles);
3713 boost::shared_ptr<BundleList> b = writer.get_copy ();
3714 b->push_back (bundle);
3717 BundleAdded (bundle); /* EMIT SIGNAL */
3723 Session::remove_bundle (shared_ptr<Bundle> bundle)
3725 bool removed = false;
3728 RCUWriter<BundleList> writer (_bundles);
3729 boost::shared_ptr<BundleList> b = writer.get_copy ();
3730 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3732 if (i != b->end()) {
3739 BundleRemoved (bundle); /* EMIT SIGNAL */
3746 Session::bundle_by_name (string name) const
3748 boost::shared_ptr<BundleList> b = _bundles.reader ();
3750 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3751 if ((*i)->name() == name) {
3756 return boost::shared_ptr<Bundle> ();
3760 Session::tempo_map_changed (Change ignored)
3764 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3765 (*i)->update_after_tempo_map_change ();
3768 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3769 (*i)->update_after_tempo_map_change ();
3775 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3776 * the given count with the current block size.
3779 Session::ensure_buffers (ChanCount howmany)
3781 if (current_block_size == 0) {
3782 return; // too early? (is this ok?)
3785 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3786 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3787 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3788 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3789 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3792 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3796 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3798 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3799 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3804 Session::next_insert_id ()
3806 /* this doesn't really loop forever. just think about it */
3809 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3810 if (!insert_bitset[n]) {
3811 insert_bitset[n] = true;
3817 /* none available, so resize and try again */
3819 insert_bitset.resize (insert_bitset.size() + 16, false);
3824 Session::next_send_id ()
3826 /* this doesn't really loop forever. just think about it */
3829 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3830 if (!send_bitset[n]) {
3831 send_bitset[n] = true;
3837 /* none available, so resize and try again */
3839 send_bitset.resize (send_bitset.size() + 16, false);
3844 Session::next_return_id ()
3846 /* this doesn't really loop forever. just think about it */
3849 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3850 if (!return_bitset[n]) {
3851 return_bitset[n] = true;
3857 /* none available, so resize and try again */
3859 return_bitset.resize (return_bitset.size() + 16, false);
3864 Session::mark_send_id (uint32_t id)
3866 if (id >= send_bitset.size()) {
3867 send_bitset.resize (id+16, false);
3869 if (send_bitset[id]) {
3870 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3872 send_bitset[id] = true;
3876 Session::mark_return_id (uint32_t id)
3878 if (id >= return_bitset.size()) {
3879 return_bitset.resize (id+16, false);
3881 if (return_bitset[id]) {
3882 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3884 return_bitset[id] = true;
3888 Session::mark_insert_id (uint32_t id)
3890 if (id >= insert_bitset.size()) {
3891 insert_bitset.resize (id+16, false);
3893 if (insert_bitset[id]) {
3894 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3896 insert_bitset[id] = true;
3899 /* Named Selection management */
3902 Session::named_selection_by_name (string name)
3904 Glib::Mutex::Lock lm (named_selection_lock);
3905 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3906 if ((*i)->name == name) {
3914 Session::add_named_selection (NamedSelection* named_selection)
3917 Glib::Mutex::Lock lm (named_selection_lock);
3918 named_selections.insert (named_selections.begin(), named_selection);
3921 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3927 NamedSelectionAdded (); /* EMIT SIGNAL */
3931 Session::remove_named_selection (NamedSelection* named_selection)
3933 bool removed = false;
3936 Glib::Mutex::Lock lm (named_selection_lock);
3938 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3940 if (i != named_selections.end()) {
3942 named_selections.erase (i);
3949 NamedSelectionRemoved (); /* EMIT SIGNAL */
3954 Session::reset_native_file_format ()
3956 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3958 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3959 (*i)->reset_write_sources (false);
3964 Session::route_name_unique (string n) const
3966 shared_ptr<RouteList> r = routes.reader ();
3968 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3969 if ((*i)->name() == n) {
3978 Session::route_name_internal (string n) const
3980 if (auditioner && auditioner->name() == n) {
3984 if (_click_io && _click_io->name() == n) {
3992 Session::n_playlists () const
3994 Glib::Mutex::Lock lm (playlist_lock);
3995 return playlists.size();
3999 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4001 if (!force && howmany <= _npan_buffers) {
4005 if (_pan_automation_buffer) {
4007 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4008 delete [] _pan_automation_buffer[i];
4011 delete [] _pan_automation_buffer;
4014 _pan_automation_buffer = new pan_t*[howmany];
4016 for (uint32_t i = 0; i < howmany; ++i) {
4017 _pan_automation_buffer[i] = new pan_t[nframes];
4020 _npan_buffers = howmany;
4024 Session::freeze (InterThreadInfo& itt)
4026 shared_ptr<RouteList> r = routes.reader ();
4028 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4030 boost::shared_ptr<Track> t;
4032 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4033 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4043 boost::shared_ptr<Region>
4044 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4045 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4046 InterThreadInfo& itt, bool enable_processing)
4048 boost::shared_ptr<Region> result;
4049 boost::shared_ptr<Playlist> playlist;
4050 boost::shared_ptr<AudioFileSource> fsource;
4052 char buf[PATH_MAX+1];
4053 ChanCount nchans(track.audio_diskstream()->n_channels());
4055 nframes_t this_chunk;
4058 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4059 const string sound_dir = sdir.sound_path().to_string();
4060 nframes_t len = end - start;
4063 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4064 end, start) << endmsg;
4068 // any bigger than this seems to cause stack overflows in called functions
4069 const nframes_t chunk_size = (128 * 1024)/4;
4071 // block all process callback handling
4073 block_processing ();
4075 /* call tree *MUST* hold route_lock */
4077 if ((playlist = track.diskstream()->playlist()) == 0) {
4081 /* external redirects will be a problem */
4083 if (track.has_external_redirects()) {
4087 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4089 for (x = 0; x < 99999; ++x) {
4090 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4091 if (access (buf, F_OK) != 0) {
4097 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4102 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4103 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4106 catch (failed_constructor& err) {
4107 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4111 srcs.push_back (fsource);
4114 /* XXX need to flush all redirects */
4119 /* create a set of reasonably-sized buffers */
4120 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4121 buffers.set_count(nchans);
4123 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4124 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4126 afs->prepare_for_peakfile_writes ();
4129 while (to_do && !itt.cancel) {
4131 this_chunk = min (to_do, chunk_size);
4133 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4138 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4139 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4142 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4148 start += this_chunk;
4149 to_do -= this_chunk;
4151 itt.progress = (float) (1.0 - ((double) to_do / len));
4160 xnow = localtime (&now);
4162 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4163 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4166 afs->update_header (position, *xnow, now);
4167 afs->flush_header ();
4171 /* construct a region to represent the bounced material */
4173 result = RegionFactory::create (srcs, 0,
4174 srcs.front()->length(srcs.front()->timeline_position()),
4175 region_name_from_path (srcs.front()->name(), true));
4180 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4181 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4184 afs->mark_for_remove ();
4187 (*src)->drop_references ();
4191 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4192 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4195 afs->done_with_peakfile_writes ();
4199 unblock_processing ();
4205 Session::get_silent_buffers (ChanCount count)
4207 assert(_silent_buffers->available() >= count);
4208 _silent_buffers->set_count(count);
4210 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4211 for (size_t i= 0; i < count.get(*t); ++i) {
4212 _silent_buffers->get(*t, i).clear();
4216 return *_silent_buffers;
4220 Session::get_scratch_buffers (ChanCount count)
4222 if (count != ChanCount::ZERO) {
4223 assert(_scratch_buffers->available() >= count);
4224 _scratch_buffers->set_count(count);
4226 _scratch_buffers->set_count (_scratch_buffers->available());
4229 return *_scratch_buffers;
4233 Session::get_mix_buffers (ChanCount count)
4235 assert(_mix_buffers->available() >= count);
4236 _mix_buffers->set_count(count);
4237 return *_mix_buffers;
4241 Session::ntracks () const
4244 shared_ptr<RouteList> r = routes.reader ();
4246 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4247 if (boost::dynamic_pointer_cast<Track> (*i)) {
4256 Session::nbusses () const
4259 shared_ptr<RouteList> r = routes.reader ();
4261 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4262 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4271 Session::add_automation_list(AutomationList *al)
4273 automation_lists[al->id()] = al;
4277 Session::compute_initial_length ()
4279 return _engine.frame_rate() * 60 * 5;
4283 Session::sync_order_keys (std::string const & base)
4285 if (!Config->get_sync_all_route_ordering()) {
4286 /* leave order keys as they are */
4290 boost::shared_ptr<RouteList> r = routes.reader ();
4292 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4293 (*i)->sync_order_keys (base);
4296 Route::SyncOrderKeys (base); // EMIT SIGNAL
4300 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4302 Session::have_rec_enabled_diskstream () const
4304 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4307 /** Update the state of our rec-enabled diskstreams flag */
4309 Session::update_have_rec_enabled_diskstream ()
4311 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4312 DiskstreamList::iterator i = dsl->begin ();
4313 while (i != dsl->end () && (*i)->record_enabled () == false) {
4317 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4319 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4321 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4322 RecordStateChanged (); /* EMIT SIGNAL */
4327 Session::listen_position_changed ()
4331 switch (Config->get_listen_position()) {
4332 case AfterFaderListen:
4336 case PreFaderListen:
4341 boost::shared_ptr<RouteList> r = routes.reader ();
4343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4344 (*i)->put_control_outs_at (p);
4349 Session::solo_control_mode_changed ()
4351 /* cancel all solo or all listen when solo control mode changes */
4353 if (Config->get_solo_control_is_listen_control()) {
4354 set_all_solo (false);
4356 set_all_listen (false);
4361 Session::route_group_changed ()
4363 RouteGroupChanged (); /* EMIT SIGNAL */