2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/filename_extensions.h"
65 #include "ardour/internal_send.h"
66 #include "ardour/io_processor.h"
67 #include "ardour/midi_diskstream.h"
68 #include "ardour/midi_playlist.h"
69 #include "ardour/midi_region.h"
70 #include "ardour/midi_track.h"
71 #include "ardour/named_selection.h"
72 #include "ardour/playlist.h"
73 #include "ardour/plugin_insert.h"
74 #include "ardour/port_insert.h"
75 #include "ardour/processor.h"
76 #include "ardour/recent_sessions.h"
77 #include "ardour/region_factory.h"
78 #include "ardour/return.h"
79 #include "ardour/route_group.h"
80 #include "ardour/send.h"
81 #include "ardour/session.h"
82 #include "ardour/session_directory.h"
83 #include "ardour/session_directory.h"
84 #include "ardour/session_metadata.h"
85 #include "ardour/slave.h"
86 #include "ardour/smf_source.h"
87 #include "ardour/source_factory.h"
88 #include "ardour/tape_file_matcher.h"
89 #include "ardour/tempo.h"
90 #include "ardour/utils.h"
95 using namespace ARDOUR;
97 using boost::shared_ptr;
99 bool Session::_disable_all_loaded_plugins = false;
101 sigc::signal<void,std::string> Session::Dialog;
102 sigc::signal<int> Session::AskAboutPendingState;
103 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
109 sigc::signal<void> Session::AutoBindingOn;
110 sigc::signal<void> Session::AutoBindingOff;
111 sigc::signal<void, std::string, std::string> Session::Exported;
113 Session::Session (AudioEngine &eng,
114 const string& fullpath,
115 const string& snapshot_name,
119 _target_transport_speed (0.0),
120 _requested_return_frame (-1),
121 _scratch_buffers(new BufferSet()),
122 _silent_buffers(new BufferSet()),
123 _mix_buffers(new BufferSet()),
125 _mmc_port (default_mmc_port),
126 _mtc_port (default_mtc_port),
127 _midi_port (default_midi_port),
128 _midi_clock_port (default_midi_clock_port),
129 _session_dir (new SessionDirectory(fullpath)),
130 pending_events (2048),
132 butler_mixdown_buffer (0),
133 butler_gain_buffer (0),
134 post_transport_work((PostTransportWork)0),
135 _send_smpte_update (false),
136 midi_thread (pthread_t (0)),
137 midi_requests (128), // the size of this should match the midi request pool size
138 diskstreams (new DiskstreamList),
139 routes (new RouteList),
140 _total_free_4k_blocks (0),
141 _bundles (new BundleList),
142 _bundle_xml_node (0),
145 click_emphasis_data (0),
147 _metadata (new SessionMetadata()),
148 _have_rec_enabled_diskstream (false)
153 interpolation.add_channel_to (0, 0);
155 if (!eng.connected()) {
156 throw failed_constructor();
159 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
161 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
162 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
164 first_stage_init (fullpath, snapshot_name);
166 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
169 if (create (new_session, mix_template, compute_initial_length())) {
171 throw failed_constructor ();
175 if (second_stage_init (new_session)) {
177 throw failed_constructor ();
180 store_recent_sessions(_name, _path);
182 bool was_dirty = dirty();
184 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
186 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
187 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
190 DirtyChanged (); /* EMIT SIGNAL */
194 Session::Session (AudioEngine &eng,
196 string snapshot_name,
197 AutoConnectOption input_ac,
198 AutoConnectOption output_ac,
199 uint32_t control_out_channels,
200 uint32_t master_out_channels,
201 uint32_t requested_physical_in,
202 uint32_t requested_physical_out,
203 nframes_t initial_length)
206 _target_transport_speed (0.0),
207 _requested_return_frame (-1),
208 _scratch_buffers(new BufferSet()),
209 _silent_buffers(new BufferSet()),
210 _mix_buffers(new BufferSet()),
212 _mmc_port (default_mmc_port),
213 _mtc_port (default_mtc_port),
214 _midi_port (default_midi_port),
215 _midi_clock_port (default_midi_clock_port),
216 _session_dir ( new SessionDirectory(fullpath)),
217 pending_events (2048),
219 butler_mixdown_buffer (0),
220 butler_gain_buffer (0),
221 post_transport_work((PostTransportWork)0),
222 _send_smpte_update (false),
223 midi_thread (pthread_t (0)),
225 diskstreams (new DiskstreamList),
226 routes (new RouteList),
227 _total_free_4k_blocks (0),
228 _bundles (new BundleList),
229 _bundle_xml_node (0),
230 _click_io ((IO *) 0),
232 click_emphasis_data (0),
234 _metadata (new SessionMetadata()),
235 _have_rec_enabled_diskstream (false)
239 interpolation.add_channel_to (0, 0);
241 if (!eng.connected()) {
242 throw failed_constructor();
245 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
247 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
248 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
250 if (n_physical_inputs) {
251 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
254 if (n_physical_outputs) {
255 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
258 first_stage_init (fullpath, snapshot_name);
260 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
263 if (create (new_session, string(), initial_length)) {
265 throw failed_constructor ();
270 /* set up Master Out and Control Out if necessary */
275 if (master_out_channels) {
276 ChanCount count(DataType::AUDIO, master_out_channels);
277 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
278 r->input()->ensure_io (count, false, this);
279 r->output()->ensure_io (count, false, this);
280 r->set_remote_control_id (control_id);
284 /* prohibit auto-connect to master, because there isn't one */
285 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
288 if (control_out_channels) {
289 ChanCount count(DataType::AUDIO, control_out_channels);
290 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
291 r->input()->ensure_io (count, false, this);
292 r->output()->ensure_io (count, false, this);
293 r->set_remote_control_id (control_id++);
299 add_routes (rl, false);
304 if (no_auto_connect()) {
305 input_ac = AutoConnectOption (0);
306 output_ac = AutoConnectOption (0);
309 Config->set_input_auto_connect (input_ac);
310 Config->set_output_auto_connect (output_ac);
312 if (second_stage_init (new_session)) {
314 throw failed_constructor ();
317 store_recent_sessions (_name, _path);
319 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
321 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
332 /* if we got to here, leaving pending capture state around
336 remove_pending_capture_state ();
338 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
340 _engine.remove_session ();
342 GoingAway (); /* EMIT SIGNAL */
348 /* clear history so that no references to objects are held any more */
352 /* clear state tree so that no references to objects are held any more */
356 terminate_butler_thread ();
357 //terminate_midi_thread ();
359 if (click_data != default_click) {
360 delete [] click_data;
363 if (click_emphasis_data != default_click_emphasis) {
364 delete [] click_emphasis_data;
369 delete _scratch_buffers;
370 delete _silent_buffers;
373 AudioDiskstream::free_working_buffers();
375 Route::SyncOrderKeys.clear();
377 #undef TRACK_DESTRUCTION
378 #ifdef TRACK_DESTRUCTION
379 cerr << "delete named selections\n";
380 #endif /* TRACK_DESTRUCTION */
381 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
382 NamedSelectionList::iterator tmp;
391 #ifdef TRACK_DESTRUCTION
392 cerr << "delete playlists\n";
393 #endif /* TRACK_DESTRUCTION */
394 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
395 PlaylistList::iterator tmp;
400 (*i)->drop_references ();
405 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
406 PlaylistList::iterator tmp;
411 (*i)->drop_references ();
417 unused_playlists.clear ();
419 #ifdef TRACK_DESTRUCTION
420 cerr << "delete regions\n";
421 #endif /* TRACK_DESTRUCTION */
423 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
424 RegionList::iterator tmp;
429 i->second->drop_references ();
436 #ifdef TRACK_DESTRUCTION
437 cerr << "delete routes\n";
438 #endif /* TRACK_DESTRUCTION */
440 RCUWriter<RouteList> writer (routes);
441 boost::shared_ptr<RouteList> r = writer.get_copy ();
442 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
443 (*i)->drop_references ();
446 /* writer goes out of scope and updates master */
451 #ifdef TRACK_DESTRUCTION
452 cerr << "delete diskstreams\n";
453 #endif /* TRACK_DESTRUCTION */
455 RCUWriter<DiskstreamList> dwriter (diskstreams);
456 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
457 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
458 (*i)->drop_references ();
462 diskstreams.flush ();
464 #ifdef TRACK_DESTRUCTION
465 cerr << "delete audio sources\n";
466 #endif /* TRACK_DESTRUCTION */
467 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
468 SourceMap::iterator tmp;
473 i->second->drop_references ();
480 #ifdef TRACK_DESTRUCTION
481 cerr << "delete route groups\n";
482 #endif /* TRACK_DESTRUCTION */
483 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
487 delete [] butler_mixdown_buffer;
488 delete [] butler_gain_buffer;
490 Crossfade::set_buffer_size (0);
496 Session::set_worst_io_latencies ()
498 _worst_output_latency = 0;
499 _worst_input_latency = 0;
501 if (!_engine.connected()) {
505 boost::shared_ptr<RouteList> r = routes.reader ();
507 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
508 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
509 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
514 Session::when_engine_running ()
516 string first_physical_output;
518 BootMessage (_("Set block size and sample rate"));
520 set_block_size (_engine.frames_per_cycle());
521 set_frame_rate (_engine.frame_rate());
523 BootMessage (_("Using configuration"));
525 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
527 /* every time we reconnect, recompute worst case output latencies */
529 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
531 if (synced_to_jack()) {
532 _engine.transport_stop ();
535 if (config.get_jack_time_master()) {
536 _engine.transport_locate (_transport_frame);
544 _click_io.reset (new ClickIO (*this, "click"));
546 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
548 /* existing state for Click */
550 if (_click_io->set_state (*child->children().front()) == 0) {
552 _clicking = Config->get_clicking ();
556 error << _("could not setup Click I/O") << endmsg;
562 /* default state for Click: dual-mono to first 2 physical outputs */
564 for (int physport = 0; physport < 2; ++physport) {
565 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
567 if (physical_output.length()) {
568 if (_click_io->add_port (physical_output, this)) {
569 // relax, even though its an error
574 if (_click_io->n_ports () > ChanCount::ZERO) {
575 _clicking = Config->get_clicking ();
580 catch (failed_constructor& err) {
581 error << _("cannot setup Click I/O") << endmsg;
584 BootMessage (_("Compute I/O Latencies"));
586 set_worst_io_latencies ();
589 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
592 BootMessage (_("Set up standard connections"));
594 /* Create a set of Bundle objects that map
595 to the physical I/O currently available. We create both
596 mono and stereo bundles, so that the common cases of mono
597 and stereo tracks get bundles to put in their mixer strip
598 in / out menus. There may be a nicer way of achieving that;
599 it doesn't really scale that well to higher channel counts
602 /* mono output bundles */
604 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
606 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
608 shared_ptr<Bundle> c (new Bundle (buf, true));
609 c->add_channel (_("mono"));
610 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
615 /* stereo output bundles */
617 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
618 if (np + 1 < n_physical_outputs) {
620 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
621 shared_ptr<Bundle> c (new Bundle (buf, true));
622 c->add_channel (_("L"));
623 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
624 c->add_channel (_("R"));
625 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
631 /* mono input bundles */
633 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
635 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
637 shared_ptr<Bundle> c (new Bundle (buf, false));
638 c->add_channel (_("mono"));
639 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
644 /* stereo input bundles */
646 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
647 if (np + 1 < n_physical_inputs) {
649 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
651 shared_ptr<Bundle> c (new Bundle (buf, false));
652 c->add_channel (_("L"));
653 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
654 c->add_channel (_("R"));
655 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
661 BootMessage (_("Setup signal flow and plugins"));
665 if (!no_auto_connect()) {
667 if (_master_out && Config->get_auto_connect_standard_busses()) {
669 /* if requested auto-connect the outputs to the first N physical ports.
672 uint32_t limit = _master_out->n_outputs().n_total();
674 for (uint32_t n = 0; n < limit; ++n) {
675 Port* p = _master_out->output()->nth (n);
676 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
678 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
679 if (_master_out->output()->connect (p, connect_to, this)) {
680 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
690 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
691 are undefined, at best.
694 /* control out listens to master bus (but ignores it
695 under some conditions)
698 uint32_t limit = _control_out->n_inputs().n_audio();
701 for (uint32_t n = 0; n < limit; ++n) {
702 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
703 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
706 string connect_to = o->name();
707 if (_control_out->input()->connect (p, connect_to, this)) {
708 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
716 /* if control out is not connected,
717 connect control out to physical outs, but use ones after the master if possible
720 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
722 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
724 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
727 _control_out->output()->connect_ports_to_bundle (b, this);
729 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
730 Config->get_monitor_bus_preferred_bundle())
736 /* XXX this logic is wrong for mixed port types */
738 uint32_t shift = _master_out->n_outputs().n_audio();
739 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
740 limit = _control_out->n_outputs().n_audio();
742 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
744 for (uint32_t n = 0; n < limit; ++n) {
746 Port* p = _control_out->output()->nth (n);
747 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
749 if (!connect_to.empty()) {
750 if (_control_out->output()->connect (p, connect_to, this)) {
751 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
762 /* catch up on send+insert cnts */
764 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
766 /* hook us up to the engine */
768 BootMessage (_("Connect to engine"));
770 _engine.set_session (this);
774 Session::hookup_io ()
776 /* stop graph reordering notifications from
777 causing resorts, etc.
780 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
785 /* we delay creating the auditioner till now because
786 it makes its own connections to ports.
787 the engine has to be running for this to work.
791 auditioner.reset (new Auditioner (*this));
794 catch (failed_constructor& err) {
795 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
799 /* load bundles, which we may have postponed earlier on */
800 if (_bundle_xml_node) {
801 load_bundles (*_bundle_xml_node);
802 delete _bundle_xml_node;
805 /* Tell all IO objects to connect themselves together */
807 IO::enable_connecting ();
809 /* Now reset all panners */
811 Delivery::reset_panners ();
813 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
817 boost::shared_ptr<RouteList> r = routes.reader ();
819 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
821 if ((*x)->is_control() || (*x)->is_master()) {
825 (*x)->listen_via (_control_out,
826 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
831 /* Anyone who cares about input state, wake up and do something */
833 IOConnectionsComplete (); /* EMIT SIGNAL */
835 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
837 /* now handle the whole enchilada as if it was one
843 /* update the full solo state, which can't be
844 correctly determined on a per-route basis, but
845 needs the global overview that only the session
849 update_route_solo_state ();
853 Session::playlist_length_changed ()
855 /* we can't just increase end_location->end() if pl->get_maximum_extent()
856 if larger. if the playlist used to be the longest playlist,
857 and its now shorter, we have to decrease end_location->end(). hence,
858 we have to iterate over all diskstreams and check the
859 playlists currently in use.
865 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
867 boost::shared_ptr<Playlist> playlist;
869 if ((playlist = dstream->playlist()) != 0) {
870 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
873 /* see comment in playlist_length_changed () */
878 Session::record_enabling_legal () const
880 /* this used to be in here, but survey says.... we don't need to restrict it */
881 // if (record_status() == Recording) {
885 if (Config->get_all_safe()) {
892 Session::reset_input_monitor_state ()
894 if (transport_rolling()) {
896 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
898 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
899 if ((*i)->record_enabled ()) {
900 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
901 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
905 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
907 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
908 if ((*i)->record_enabled ()) {
909 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
910 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
917 Session::auto_punch_start_changed (Location* location)
919 replace_event (Event::PunchIn, location->start());
921 if (get_record_enabled() && config.get_punch_in()) {
922 /* capture start has been changed, so save new pending state */
923 save_state ("", true);
928 Session::auto_punch_end_changed (Location* location)
930 nframes_t when_to_stop = location->end();
931 // when_to_stop += _worst_output_latency + _worst_input_latency;
932 replace_event (Event::PunchOut, when_to_stop);
936 Session::auto_punch_changed (Location* location)
938 nframes_t when_to_stop = location->end();
940 replace_event (Event::PunchIn, location->start());
941 //when_to_stop += _worst_output_latency + _worst_input_latency;
942 replace_event (Event::PunchOut, when_to_stop);
946 Session::auto_loop_changed (Location* location)
948 replace_event (Event::AutoLoop, location->end(), location->start());
950 if (transport_rolling() && play_loop) {
952 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
954 if (_transport_frame > location->end()) {
955 // relocate to beginning of loop
956 clear_events (Event::LocateRoll);
958 request_locate (location->start(), true);
961 else if (Config->get_seamless_loop() && !loop_changing) {
963 // schedule a locate-roll to refill the diskstreams at the
965 loop_changing = true;
967 if (location->end() > last_loopend) {
968 clear_events (Event::LocateRoll);
969 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
976 last_loopend = location->end();
980 Session::set_auto_punch_location (Location* location)
984 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
985 auto_punch_start_changed_connection.disconnect();
986 auto_punch_end_changed_connection.disconnect();
987 auto_punch_changed_connection.disconnect();
988 existing->set_auto_punch (false, this);
989 remove_event (existing->start(), Event::PunchIn);
990 clear_events (Event::PunchOut);
991 auto_punch_location_changed (0);
1000 if (location->end() <= location->start()) {
1001 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1005 auto_punch_start_changed_connection.disconnect();
1006 auto_punch_end_changed_connection.disconnect();
1007 auto_punch_changed_connection.disconnect();
1009 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1010 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1011 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1013 location->set_auto_punch (true, this);
1016 auto_punch_changed (location);
1018 auto_punch_location_changed (location);
1022 Session::set_auto_loop_location (Location* location)
1026 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1027 auto_loop_start_changed_connection.disconnect();
1028 auto_loop_end_changed_connection.disconnect();
1029 auto_loop_changed_connection.disconnect();
1030 existing->set_auto_loop (false, this);
1031 remove_event (existing->end(), Event::AutoLoop);
1032 auto_loop_location_changed (0);
1037 if (location == 0) {
1041 if (location->end() <= location->start()) {
1042 error << _("Session: you can't use a mark for auto loop") << endmsg;
1046 last_loopend = location->end();
1048 auto_loop_start_changed_connection.disconnect();
1049 auto_loop_end_changed_connection.disconnect();
1050 auto_loop_changed_connection.disconnect();
1052 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1053 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1054 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1056 location->set_auto_loop (true, this);
1058 /* take care of our stuff first */
1060 auto_loop_changed (location);
1062 /* now tell everyone else */
1064 auto_loop_location_changed (location);
1068 Session::locations_added (Location *)
1074 Session::locations_changed ()
1076 _locations.apply (*this, &Session::handle_locations_changed);
1080 Session::handle_locations_changed (Locations::LocationList& locations)
1082 Locations::LocationList::iterator i;
1084 bool set_loop = false;
1085 bool set_punch = false;
1087 for (i = locations.begin(); i != locations.end(); ++i) {
1091 if (location->is_auto_punch()) {
1092 set_auto_punch_location (location);
1095 if (location->is_auto_loop()) {
1096 set_auto_loop_location (location);
1100 if (location->is_start()) {
1101 start_location = location;
1103 if (location->is_end()) {
1104 end_location = location;
1109 set_auto_loop_location (0);
1112 set_auto_punch_location (0);
1119 Session::enable_record ()
1121 /* XXX really atomic compare+swap here */
1122 if (g_atomic_int_get (&_record_status) != Recording) {
1123 g_atomic_int_set (&_record_status, Recording);
1124 _last_record_location = _transport_frame;
1125 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1127 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1128 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1129 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1130 if ((*i)->record_enabled ()) {
1131 (*i)->monitor_input (true);
1136 RecordStateChanged ();
1141 Session::disable_record (bool rt_context, bool force)
1145 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1147 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1148 g_atomic_int_set (&_record_status, Disabled);
1150 if (rs == Recording) {
1151 g_atomic_int_set (&_record_status, Enabled);
1155 // FIXME: timestamp correct? [DR]
1156 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1157 // does this /need/ to be sent in all cases?
1159 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1161 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1162 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1164 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1165 if ((*i)->record_enabled ()) {
1166 (*i)->monitor_input (false);
1171 RecordStateChanged (); /* emit signal */
1174 remove_pending_capture_state ();
1180 Session::step_back_from_record ()
1182 /* XXX really atomic compare+swap here */
1183 if (g_atomic_int_get (&_record_status) == Recording) {
1184 g_atomic_int_set (&_record_status, Enabled);
1186 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1187 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1189 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1190 if ((*i)->record_enabled ()) {
1191 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1192 (*i)->monitor_input (false);
1200 Session::maybe_enable_record ()
1202 g_atomic_int_set (&_record_status, Enabled);
1204 /* this function is currently called from somewhere other than an RT thread.
1205 this save_state() call therefore doesn't impact anything.
1208 save_state ("", true);
1210 if (_transport_speed) {
1211 if (!config.get_punch_in()) {
1215 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1216 RecordStateChanged (); /* EMIT SIGNAL */
1223 Session::audible_frame () const
1229 /* the first of these two possible settings for "offset"
1230 mean that the audible frame is stationary until
1231 audio emerges from the latency compensation
1234 the second means that the audible frame is stationary
1235 until audio would emerge from a physical port
1236 in the absence of any plugin latency compensation
1239 offset = _worst_output_latency;
1241 if (offset > current_block_size) {
1242 offset -= current_block_size;
1244 /* XXX is this correct? if we have no external
1245 physical connections and everything is internal
1246 then surely this is zero? still, how
1247 likely is that anyway?
1249 offset = current_block_size;
1252 if (synced_to_jack()) {
1253 tf = _engine.transport_frame();
1255 tf = _transport_frame;
1260 if (!non_realtime_work_pending()) {
1264 /* check to see if we have passed the first guaranteed
1265 audible frame past our last start position. if not,
1266 return that last start point because in terms
1267 of audible frames, we have not moved yet.
1270 if (_transport_speed > 0.0f) {
1272 if (!play_loop || !have_looped) {
1273 if (tf < _last_roll_location + offset) {
1274 return _last_roll_location;
1282 } else if (_transport_speed < 0.0f) {
1284 /* XXX wot? no backward looping? */
1286 if (tf > _last_roll_location - offset) {
1287 return _last_roll_location;
1299 Session::set_frame_rate (nframes_t frames_per_second)
1301 /** \fn void Session::set_frame_size(nframes_t)
1302 the AudioEngine object that calls this guarantees
1303 that it will not be called while we are also in
1304 ::process(). Its fine to do things that block
1308 _base_frame_rate = frames_per_second;
1312 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1316 // XXX we need some equivalent to this, somehow
1317 // SndFileSource::setup_standard_crossfades (frames_per_second);
1321 /* XXX need to reset/reinstantiate all LADSPA plugins */
1325 Session::set_block_size (nframes_t nframes)
1327 /* the AudioEngine guarantees
1328 that it will not be called while we are also in
1329 ::process(). It is therefore fine to do things that block
1334 current_block_size = nframes;
1336 ensure_buffers(_scratch_buffers->available());
1338 delete [] _gain_automation_buffer;
1339 _gain_automation_buffer = new gain_t[nframes];
1341 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1343 boost::shared_ptr<RouteList> r = routes.reader ();
1345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1346 (*i)->set_block_size (nframes);
1349 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1350 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1351 (*i)->set_block_size (nframes);
1354 set_worst_io_latencies ();
1359 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1362 nframes_t fade_frames;
1364 /* Don't allow fade of less 1 frame */
1366 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1373 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1377 default_fade_msecs = fade_msecs;
1378 default_fade_steepness = steepness;
1381 // jlc, WTF is this!
1382 Glib::RWLock::ReaderLock lm (route_lock);
1383 AudioRegion::set_default_fade (steepness, fade_frames);
1388 /* XXX have to do this at some point */
1389 /* foreach region using default fade, reset, then
1390 refill_all_diskstream_buffers ();
1395 struct RouteSorter {
1396 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1397 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1399 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1402 if (r1->fed_by.empty()) {
1403 if (r2->fed_by.empty()) {
1404 /* no ardour-based connections inbound to either route. just use signal order */
1405 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1407 /* r2 has connections, r1 does not; run r1 early */
1411 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1418 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1420 shared_ptr<Route> r2;
1422 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1423 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1427 /* make a copy of the existing list of routes that feed r1 */
1429 set<shared_ptr<Route> > existing = r1->fed_by;
1431 /* for each route that feeds r1, recurse, marking it as feeding
1435 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1438 /* r2 is a route that feeds r1 which somehow feeds base. mark
1439 base as being fed by r2
1442 rbase->fed_by.insert (r2);
1446 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1450 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1454 /* now recurse, so that we can mark base as being fed by
1455 all routes that feed r2
1458 trace_terminal (r2, rbase);
1465 Session::resort_routes ()
1467 /* don't do anything here with signals emitted
1468 by Routes while we are being destroyed.
1471 if (_state_of_the_state & Deletion) {
1478 RCUWriter<RouteList> writer (routes);
1479 shared_ptr<RouteList> r = writer.get_copy ();
1480 resort_routes_using (r);
1481 /* writer goes out of scope and forces update */
1486 Session::resort_routes_using (shared_ptr<RouteList> r)
1488 RouteList::iterator i, j;
1490 for (i = r->begin(); i != r->end(); ++i) {
1492 (*i)->fed_by.clear ();
1494 for (j = r->begin(); j != r->end(); ++j) {
1496 /* although routes can feed themselves, it will
1497 cause an endless recursive descent if we
1498 detect it. so don't bother checking for
1506 if ((*j)->feeds (*i)) {
1507 (*i)->fed_by.insert (*j);
1512 for (i = r->begin(); i != r->end(); ++i) {
1513 trace_terminal (*i, *i);
1520 cerr << "finished route resort\n";
1522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1523 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1530 list<boost::shared_ptr<MidiTrack> >
1531 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1533 char track_name[32];
1534 uint32_t track_id = 0;
1537 RouteList new_routes;
1538 list<boost::shared_ptr<MidiTrack> > ret;
1539 //uint32_t control_id;
1541 // FIXME: need physical I/O and autoconnect stuff for MIDI
1543 /* count existing midi tracks */
1546 shared_ptr<RouteList> r = routes.reader ();
1548 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1549 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1550 if (!(*i)->is_hidden()) {
1552 //channels_used += (*i)->n_inputs().n_midi();
1558 vector<string> physinputs;
1559 vector<string> physoutputs;
1561 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1562 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1564 // control_id = ntracks() + nbusses();
1568 /* check for duplicate route names, since we might have pre-existing
1569 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1570 save, close,restart,add new route - first named route is now
1578 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1580 if (route_by_name (track_name) == 0) {
1584 } while (track_id < (UINT_MAX-1));
1586 shared_ptr<MidiTrack> track;
1589 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1591 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1592 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1597 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1598 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1604 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1608 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1609 port = physinputs[(channels_used+x)%nphysical_in];
1612 if (port.length() && track->connect_input (track->input (x), port, this)) {
1618 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1622 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1623 port = physoutputs[(channels_used+x)%nphysical_out];
1624 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1626 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1630 if (port.length() && track->connect_output (track->output (x), port, this)) {
1635 channels_used += track->n_inputs ().n_midi();
1639 track->midi_diskstream()->non_realtime_input_change();
1640 track->set_route_group (route_group, 0);
1642 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1643 //track->set_remote_control_id (control_id);
1645 new_routes.push_back (track);
1646 ret.push_back (track);
1649 catch (failed_constructor &err) {
1650 error << _("Session: could not create new midi track.") << endmsg;
1653 /* we need to get rid of this, since the track failed to be created */
1654 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1657 RCUWriter<DiskstreamList> writer (diskstreams);
1658 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1659 ds->remove (track->midi_diskstream());
1666 catch (AudioEngine::PortRegistrationFailure& pfe) {
1668 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;
1671 /* we need to get rid of this, since the track failed to be created */
1672 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1675 RCUWriter<DiskstreamList> writer (diskstreams);
1676 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1677 ds->remove (track->midi_diskstream());
1688 if (!new_routes.empty()) {
1689 add_routes (new_routes, false);
1690 save_state (_current_snapshot_name);
1696 list<boost::shared_ptr<AudioTrack> >
1697 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1699 char track_name[32];
1700 uint32_t track_id = 0;
1702 uint32_t channels_used = 0;
1704 RouteList new_routes;
1705 list<boost::shared_ptr<AudioTrack> > ret;
1706 uint32_t control_id;
1708 /* count existing audio tracks */
1711 shared_ptr<RouteList> r = routes.reader ();
1713 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1714 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1715 if (!(*i)->is_hidden()) {
1717 channels_used += (*i)->n_inputs().n_audio();
1723 vector<string> physinputs;
1724 vector<string> physoutputs;
1726 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1727 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1729 control_id = ntracks() + nbusses() + 1;
1733 /* check for duplicate route names, since we might have pre-existing
1734 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1735 save, close,restart,add new route - first named route is now
1743 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1745 if (route_by_name (track_name) == 0) {
1749 } while (track_id < (UINT_MAX-1));
1751 shared_ptr<AudioTrack> track;
1754 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1756 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1757 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1758 input_channels, output_channels)
1763 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1764 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1765 input_channels, output_channels)
1770 if (!physinputs.empty()) {
1771 uint32_t nphysical_in = physinputs.size();
1773 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1777 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1778 port = physinputs[(channels_used+x)%nphysical_in];
1781 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1787 if (!physoutputs.empty()) {
1788 uint32_t nphysical_out = physoutputs.size();
1790 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1793 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1794 port = physoutputs[(channels_used+x)%nphysical_out];
1795 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1796 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1797 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1801 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1807 channels_used += track->n_inputs ().n_audio();
1809 track->set_route_group (route_group, 0);
1811 track->audio_diskstream()->non_realtime_input_change();
1813 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1814 track->set_remote_control_id (control_id);
1817 new_routes.push_back (track);
1818 ret.push_back (track);
1821 catch (failed_constructor &err) {
1822 error << _("Session: could not create new audio track.") << endmsg;
1825 /* we need to get rid of this, since the track failed to be created */
1826 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1829 RCUWriter<DiskstreamList> writer (diskstreams);
1830 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1831 ds->remove (track->audio_diskstream());
1838 catch (AudioEngine::PortRegistrationFailure& pfe) {
1840 error << pfe.what() << endmsg;
1843 /* we need to get rid of this, since the track failed to be created */
1844 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1847 RCUWriter<DiskstreamList> writer (diskstreams);
1848 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1849 ds->remove (track->audio_diskstream());
1860 if (!new_routes.empty()) {
1861 add_routes (new_routes, true);
1868 Session::set_remote_control_ids ()
1870 RemoteModel m = Config->get_remote_model();
1872 shared_ptr<RouteList> r = routes.reader ();
1874 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1875 if ( MixerOrdered == m) {
1876 long order = (*i)->order_key(N_("signal"));
1877 (*i)->set_remote_control_id( order+1 );
1878 } else if ( EditorOrdered == m) {
1879 long order = (*i)->order_key(N_("editor"));
1880 (*i)->set_remote_control_id( order+1 );
1881 } else if ( UserOrdered == m) {
1882 //do nothing ... only changes to remote id's are initiated by user
1889 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1892 uint32_t bus_id = 1;
1894 uint32_t channels_used = 0;
1897 uint32_t control_id;
1899 /* count existing audio busses */
1902 shared_ptr<RouteList> r = routes.reader ();
1904 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1905 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1907 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1910 channels_used += (*i)->n_inputs().n_audio();
1916 vector<string> physinputs;
1917 vector<string> physoutputs;
1919 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1920 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1922 n_physical_audio_outputs = physoutputs.size();
1923 n_physical_audio_inputs = physinputs.size();
1925 control_id = ntracks() + nbusses() + 1;
1930 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1934 if (route_by_name (bus_name) == 0) {
1938 } while (bus_id < (UINT_MAX-1));
1941 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1943 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1944 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1945 input_channels, output_channels)
1951 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1952 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1953 input_channels, output_channels)
1958 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1961 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1962 port = physinputs[((n+x)%n_physical_audio_inputs)];
1965 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1970 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1973 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1974 port = physoutputs[((n+x)%n_physical_outputs)];
1975 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1977 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1981 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1986 channels_used += bus->n_inputs ().n_audio();
1988 bus->set_route_group (route_group, 0);
1989 bus->set_remote_control_id (control_id);
1992 ret.push_back (bus);
1996 catch (failed_constructor &err) {
1997 error << _("Session: could not create new audio route.") << endmsg;
2001 catch (AudioEngine::PortRegistrationFailure& pfe) {
2002 error << pfe.what() << endmsg;
2012 add_routes (ret, true);
2020 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2024 uint32_t control_id;
2026 uint32_t number = 1;
2028 if (!tree.read (template_path.c_str())) {
2032 XMLNode* node = tree.root();
2034 control_id = ntracks() + nbusses() + 1;
2038 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2040 std::string node_name = IO::name_from_state (*node_copy.children().front());
2042 /* generate a new name by adding a number to the end of the template name */
2045 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2049 if (route_by_name (name) == 0) {
2053 } while (number < UINT_MAX);
2055 if (number == UINT_MAX) {
2056 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2060 IO::set_name_in_state (*node_copy.children().front(), name);
2062 Track::zero_diskstream_id_in_xml (node_copy);
2065 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2068 error << _("Session: cannot create track/bus from template description") << endmsg;
2072 if (boost::dynamic_pointer_cast<Track>(route)) {
2073 /* force input/output change signals so that the new diskstream
2074 picks up the configuration of the route. During session
2075 loading this normally happens in a different way.
2077 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2078 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2081 route->set_remote_control_id (control_id);
2084 ret.push_back (route);
2087 catch (failed_constructor &err) {
2088 error << _("Session: could not create new route from template") << endmsg;
2092 catch (AudioEngine::PortRegistrationFailure& pfe) {
2093 error << pfe.what() << endmsg;
2102 add_routes (ret, true);
2109 Session::add_routes (RouteList& new_routes, bool save)
2112 RCUWriter<RouteList> writer (routes);
2113 shared_ptr<RouteList> r = writer.get_copy ();
2114 r->insert (r->end(), new_routes.begin(), new_routes.end());
2117 /* if there is no control out and we're not in the middle of loading,
2118 resort the graph here. if there is a control out, we will resort
2119 toward the end of this method. if we are in the middle of loading,
2120 we will resort when done.
2123 if (!_control_out && IO::connecting_legal) {
2124 resort_routes_using (r);
2128 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2130 boost::weak_ptr<Route> wpr (*x);
2132 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2133 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2134 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2135 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2136 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2137 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2139 if ((*x)->is_master()) {
2143 if ((*x)->is_control()) {
2144 _control_out = (*x);
2148 if (_control_out && IO::connecting_legal) {
2150 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2151 if ((*x)->is_control() || (*x)->is_master()) {
2154 (*x)->listen_via (_control_out,
2155 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2165 save_state (_current_snapshot_name);
2168 RouteAdded (new_routes); /* EMIT SIGNAL */
2172 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2174 boost::shared_ptr<RouteList> r = routes.reader ();
2175 boost::shared_ptr<Send> s;
2179 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2180 if (boost::dynamic_pointer_cast<Track>(*i)) {
2181 if ((s = (*i)->internal_send_for (dest)) != 0) {
2182 s->amp()->gain_control()->set_value (0.0);
2189 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2191 boost::shared_ptr<RouteList> r = routes.reader ();
2192 boost::shared_ptr<Send> s;
2196 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2197 if (boost::dynamic_pointer_cast<Track>(*i)) {
2198 if ((s = (*i)->internal_send_for (dest)) != 0) {
2199 s->amp()->gain_control()->set_value (1.0);
2206 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2208 boost::shared_ptr<RouteList> r = routes.reader ();
2209 boost::shared_ptr<Send> s;
2213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2214 if (boost::dynamic_pointer_cast<Track>(*i)) {
2215 if ((s = (*i)->internal_send_for (dest)) != 0) {
2216 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2223 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2225 boost::shared_ptr<RouteList> r = routes.reader ();
2226 boost::shared_ptr<RouteList> t (new RouteList);
2228 /* only send tracks */
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if (boost::dynamic_pointer_cast<Track>(*i)) {
2236 add_internal_sends (dest, p, t);
2241 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2243 if (dest->is_control() || dest->is_master()) {
2247 if (!dest->internal_return()) {
2248 dest->add_internal_return();
2251 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2253 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2257 (*i)->listen_via (dest, p, true, true);
2262 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2264 /* need to do this in case we're rolling at the time, to prevent false underruns */
2265 dstream->do_refill_with_alloc ();
2267 dstream->set_block_size (current_block_size);
2270 RCUWriter<DiskstreamList> writer (diskstreams);
2271 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2272 ds->push_back (dstream);
2273 /* writer goes out of scope, copies ds back to main */
2276 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2277 /* this will connect to future changes, and check the current length */
2278 diskstream_playlist_changed (dstream);
2280 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2282 dstream->prepare ();
2287 Session::remove_route (shared_ptr<Route> route)
2290 RCUWriter<RouteList> writer (routes);
2291 shared_ptr<RouteList> rs = writer.get_copy ();
2295 /* deleting the master out seems like a dumb
2296 idea, but its more of a UI policy issue
2300 if (route == _master_out) {
2301 _master_out = shared_ptr<Route> ();
2304 if (route == _control_out) {
2306 /* cancel control outs for all routes */
2308 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2309 (*r)->drop_listen (_control_out);
2312 _control_out.reset ();
2315 update_route_solo_state ();
2317 /* writer goes out of scope, forces route list update */
2320 boost::shared_ptr<Track> t;
2321 boost::shared_ptr<Diskstream> ds;
2323 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2324 ds = t->diskstream();
2330 RCUWriter<DiskstreamList> dsl (diskstreams);
2331 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2336 find_current_end ();
2338 // We need to disconnect the routes inputs and outputs
2340 route->input()->disconnect (0);
2341 route->output()->disconnect (0);
2343 update_latency_compensation (false, false);
2346 /* get rid of it from the dead wood collection in the route list manager */
2348 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2352 /* try to cause everyone to drop their references */
2354 route->drop_references ();
2356 sync_order_keys (N_("session"));
2358 /* save the new state of the world */
2360 if (save_state (_current_snapshot_name)) {
2361 save_history (_current_snapshot_name);
2366 Session::route_mute_changed (void* /*src*/)
2372 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2374 boost::shared_ptr<Route> route = wpr.lock();
2376 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2380 if (route->listening()) {
2382 } else if (_listen_cnt > 0) {
2388 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2390 if (solo_update_disabled) {
2395 boost::shared_ptr<Route> route = wpr.lock ();
2398 /* should not happen */
2399 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2403 shared_ptr<RouteList> r = routes.reader ();
2406 if (route->soloed()) {
2412 /* now mod the solo level of all other routes except master & control outs
2413 so that they will be silent if appropriate.
2416 solo_update_disabled = true;
2417 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2419 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2421 (*i)->mod_solo_level (delta);
2425 /* make sure master is never muted by solo */
2427 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2428 _master_out->mod_solo_level (1);
2431 /* ditto for control outs make sure master is never muted by solo */
2433 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2434 _control_out->mod_solo_level (1);
2437 solo_update_disabled = false;
2438 update_route_solo_state (r);
2439 SoloChanged (); /* EMIT SIGNAL */
2444 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2446 /* now figure out if anything that matters is soloed */
2448 bool something_soloed = false;
2451 r = routes.reader();
2454 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2455 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2456 something_soloed = true;
2461 if (something_soloed != _non_soloed_outs_muted) {
2462 _non_soloed_outs_muted = something_soloed;
2463 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2468 Session::route_by_name (string name)
2470 shared_ptr<RouteList> r = routes.reader ();
2472 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2473 if ((*i)->name() == name) {
2478 return shared_ptr<Route> ((Route*) 0);
2482 Session::route_by_id (PBD::ID id)
2484 shared_ptr<RouteList> r = routes.reader ();
2486 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2487 if ((*i)->id() == id) {
2492 return shared_ptr<Route> ((Route*) 0);
2496 Session::route_by_remote_id (uint32_t id)
2498 shared_ptr<RouteList> r = routes.reader ();
2500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2501 if ((*i)->remote_control_id() == id) {
2506 return shared_ptr<Route> ((Route*) 0);
2510 Session::find_current_end ()
2512 if (_state_of_the_state & Loading) {
2516 nframes_t max = get_maximum_extent ();
2518 if (max > end_location->end()) {
2519 end_location->set_end (max);
2521 DurationChanged(); /* EMIT SIGNAL */
2526 Session::get_maximum_extent () const
2531 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2533 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2534 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2536 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2537 if ((me = pl->get_maximum_extent()) > max) {
2545 boost::shared_ptr<Diskstream>
2546 Session::diskstream_by_name (string name)
2548 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2550 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2551 if ((*i)->name() == name) {
2556 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2559 boost::shared_ptr<Diskstream>
2560 Session::diskstream_by_id (const PBD::ID& id)
2562 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2564 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2565 if ((*i)->id() == id) {
2570 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2573 /* Region management */
2576 Session::new_region_name (string old)
2578 string::size_type last_period;
2580 string::size_type len = old.length() + 64;
2583 if ((last_period = old.find_last_of ('.')) == string::npos) {
2585 /* no period present - add one explicitly */
2588 last_period = old.length() - 1;
2593 number = atoi (old.substr (last_period+1).c_str());
2597 while (number < (UINT_MAX-1)) {
2599 RegionList::const_iterator i;
2604 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2607 for (i = regions.begin(); i != regions.end(); ++i) {
2608 if (i->second->name() == sbuf) {
2613 if (i == regions.end()) {
2618 if (number != (UINT_MAX-1)) {
2622 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2627 Session::region_name (string& result, string base, bool newlevel)
2632 if (base.find("/") != string::npos) {
2633 base = base.substr(base.find_last_of("/") + 1);
2638 Glib::Mutex::Lock lm (region_lock);
2640 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2649 string::size_type pos;
2651 pos = base.find_last_of ('.');
2653 /* pos may be npos, but then we just use entire base */
2655 subbase = base.substr (0, pos);
2660 Glib::Mutex::Lock lm (region_lock);
2662 map<string,uint32_t>::iterator x;
2666 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2668 region_name_map[subbase] = 1;
2671 snprintf (buf, sizeof (buf), ".%d", x->second);
2682 Session::add_region (boost::shared_ptr<Region> region)
2684 vector<boost::shared_ptr<Region> > v;
2685 v.push_back (region);
2690 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2695 Glib::Mutex::Lock lm (region_lock);
2697 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2699 boost::shared_ptr<Region> region = *ii;
2703 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2707 RegionList::iterator x;
2709 for (x = regions.begin(); x != regions.end(); ++x) {
2711 if (region->region_list_equivalent (x->second)) {
2716 if (x == regions.end()) {
2718 pair<RegionList::key_type,RegionList::mapped_type> entry;
2720 entry.first = region->id();
2721 entry.second = region;
2723 pair<RegionList::iterator,bool> x = regions.insert (entry);
2735 /* mark dirty because something has changed even if we didn't
2736 add the region to the region list.
2743 vector<boost::weak_ptr<Region> > v;
2744 boost::shared_ptr<Region> first_r;
2746 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2748 boost::shared_ptr<Region> region = *ii;
2752 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2755 v.push_back (region);
2762 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2763 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2765 update_region_name_map (region);
2769 RegionsAdded (v); /* EMIT SIGNAL */
2775 Session::update_region_name_map (boost::shared_ptr<Region> region)
2777 string::size_type last_period = region->name().find_last_of ('.');
2779 if (last_period != string::npos && last_period < region->name().length() - 1) {
2781 string base = region->name().substr (0, last_period);
2782 string number = region->name().substr (last_period+1);
2783 map<string,uint32_t>::iterator x;
2785 /* note that if there is no number, we get zero from atoi,
2789 region_name_map[base] = atoi (number);
2794 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2796 boost::shared_ptr<Region> region (weak_region.lock ());
2802 if (what_changed & Region::HiddenChanged) {
2803 /* relay hidden changes */
2804 RegionHiddenChange (region);
2807 if (what_changed & NameChanged) {
2808 update_region_name_map (region);
2813 Session::remove_region (boost::weak_ptr<Region> weak_region)
2815 RegionList::iterator i;
2816 boost::shared_ptr<Region> region (weak_region.lock ());
2822 bool removed = false;
2825 Glib::Mutex::Lock lm (region_lock);
2827 if ((i = regions.find (region->id())) != regions.end()) {
2833 /* mark dirty because something has changed even if we didn't
2834 remove the region from the region list.
2840 RegionRemoved(region); /* EMIT SIGNAL */
2844 boost::shared_ptr<Region>
2845 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2847 RegionList::iterator i;
2848 boost::shared_ptr<Region> region;
2850 Glib::Mutex::Lock lm (region_lock);
2852 for (i = regions.begin(); i != regions.end(); ++i) {
2856 if (region->whole_file()) {
2858 if (child->source_equivalent (region)) {
2864 return boost::shared_ptr<Region> ();
2868 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2870 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2871 (*i)->get_region_list_equivalent_regions (region, result);
2875 Session::destroy_region (boost::shared_ptr<Region> region)
2877 vector<boost::shared_ptr<Source> > srcs;
2880 if (region->playlist()) {
2881 region->playlist()->destroy_region (region);
2884 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2885 srcs.push_back (region->source (n));
2889 region->drop_references ();
2891 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2893 (*i)->mark_for_remove ();
2894 (*i)->drop_references ();
2896 cerr << "source was not used by any playlist\n";
2903 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2905 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2906 destroy_region (*i);
2912 Session::remove_last_capture ()
2914 list<boost::shared_ptr<Region> > r;
2916 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2918 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2919 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2922 r.insert (r.end(), l.begin(), l.end());
2927 destroy_regions (r);
2929 save_state (_current_snapshot_name);
2935 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2941 /* Source Management */
2944 Session::add_source (boost::shared_ptr<Source> source)
2946 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2947 pair<SourceMap::iterator,bool> result;
2949 entry.first = source->id();
2950 entry.second = source;
2953 Glib::Mutex::Lock lm (source_lock);
2954 result = sources.insert (entry);
2957 if (result.second) {
2958 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2962 boost::shared_ptr<AudioFileSource> afs;
2964 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2965 if (Config->get_auto_analyse_audio()) {
2966 Analyser::queue_source_for_analysis (source, false);
2972 Session::remove_source (boost::weak_ptr<Source> src)
2974 SourceMap::iterator i;
2975 boost::shared_ptr<Source> source = src.lock();
2982 Glib::Mutex::Lock lm (source_lock);
2984 if ((i = sources.find (source->id())) != sources.end()) {
2989 if (!_state_of_the_state & InCleanup) {
2991 /* save state so we don't end up with a session file
2992 referring to non-existent sources.
2995 save_state (_current_snapshot_name);
2999 boost::shared_ptr<Source>
3000 Session::source_by_id (const PBD::ID& id)
3002 Glib::Mutex::Lock lm (source_lock);
3003 SourceMap::iterator i;
3004 boost::shared_ptr<Source> source;
3006 if ((i = sources.find (id)) != sources.end()) {
3013 boost::shared_ptr<Source>
3014 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3016 Glib::Mutex::Lock lm (source_lock);
3018 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3019 cerr << "comparing " << path << " with " << i->second->name() << endl;
3020 boost::shared_ptr<AudioFileSource> afs
3021 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3023 if (afs && afs->path() == path && chn == afs->channel()) {
3027 return boost::shared_ptr<Source>();
3032 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3035 string old_basename = PBD::basename_nosuffix (oldname);
3036 string new_legalized = legalize_for_path (newname);
3038 /* note: we know (or assume) the old path is already valid */
3042 /* destructive file sources have a name of the form:
3044 /path/to/Tnnnn-NAME(%[LR])?.wav
3046 the task here is to replace NAME with the new name.
3049 /* find last slash */
3053 string::size_type slash;
3054 string::size_type dash;
3056 if ((slash = path.find_last_of ('/')) == string::npos) {
3060 dir = path.substr (0, slash+1);
3062 /* '-' is not a legal character for the NAME part of the path */
3064 if ((dash = path.find_last_of ('-')) == string::npos) {
3068 prefix = path.substr (slash+1, dash-(slash+1));
3073 path += new_legalized;
3074 path += ".wav"; /* XXX gag me with a spoon */
3078 /* non-destructive file sources have a name of the form:
3080 /path/to/NAME-nnnnn(%[LR])?.ext
3082 the task here is to replace NAME with the new name.
3087 string::size_type slash;
3088 string::size_type dash;
3089 string::size_type postfix;
3091 /* find last slash */
3093 if ((slash = path.find_last_of ('/')) == string::npos) {
3097 dir = path.substr (0, slash+1);
3099 /* '-' is not a legal character for the NAME part of the path */
3101 if ((dash = path.find_last_of ('-')) == string::npos) {
3105 suffix = path.substr (dash+1);
3107 // Suffix is now everything after the dash. Now we need to eliminate
3108 // the nnnnn part, which is done by either finding a '%' or a '.'
3110 postfix = suffix.find_last_of ("%");
3111 if (postfix == string::npos) {
3112 postfix = suffix.find_last_of ('.');
3115 if (postfix != string::npos) {
3116 suffix = suffix.substr (postfix);
3118 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3122 const uint32_t limit = 10000;
3123 char buf[PATH_MAX+1];
3125 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3127 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3129 if (access (buf, F_OK) != 0) {
3137 error << "FATAL ERROR! Could not find a " << endl;
3145 /** Return the full path (in some session directory) for a new embedded source.
3146 * \a name must be a session-unique name that does not contain slashes
3147 * (e.g. as returned by new_*_source_name)
3150 Session::new_source_path_from_name (DataType type, const string& name)
3152 assert(name.find("/") == string::npos);
3154 SessionDirectory sdir(get_best_session_directory_for_new_source());
3157 if (type == DataType::AUDIO) {
3158 p = sdir.sound_path();
3159 } else if (type == DataType::MIDI) {
3160 p = sdir.midi_path();
3162 error << "Unknown source type, unable to create file path" << endmsg;
3167 return p.to_string();
3171 Session::peak_path (Glib::ustring base) const
3173 sys::path peakfile_path(_session_dir->peak_path());
3174 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3175 return peakfile_path.to_string();
3178 /** Return a unique name based on \a base for a new internal audio source */
3180 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3184 char buf[PATH_MAX+1];
3185 const uint32_t limit = 10000;
3189 legalized = legalize_for_path (base);
3191 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3192 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3194 vector<space_and_path>::iterator i;
3195 uint32_t existing = 0;
3197 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3199 SessionDirectory sdir((*i).path);
3201 spath = sdir.sound_path().to_string();
3206 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3207 spath.c_str(), cnt, legalized.c_str());
3208 } else if (nchan == 2) {
3210 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3211 spath.c_str(), cnt, legalized.c_str());
3213 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3214 spath.c_str(), cnt, legalized.c_str());
3216 } else if (nchan < 26) {
3217 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3218 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3220 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3221 spath.c_str(), cnt, legalized.c_str());
3230 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3231 } else if (nchan == 2) {
3233 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3235 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3237 } else if (nchan < 26) {
3238 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3240 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3244 if (sys::exists(buf)) {
3250 if (existing == 0) {
3255 error << string_compose(
3256 _("There are already %1 recordings for %2, which I consider too many."),
3257 limit, base) << endmsg;
3259 throw failed_constructor();
3263 return Glib::path_get_basename(buf);
3266 /** Create a new embedded audio source */
3267 boost::shared_ptr<AudioFileSource>
3268 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3270 const size_t n_chans = ds.n_channels().n_audio();
3271 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3272 const string path = new_source_path_from_name(DataType::AUDIO, name);
3273 return boost::dynamic_pointer_cast<AudioFileSource> (
3274 SourceFactory::createWritable (
3275 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3278 /** Return a unique name based on \a base for a new internal MIDI source */
3280 Session::new_midi_source_name (const string& base)
3283 char buf[PATH_MAX+1];
3284 const uint32_t limit = 10000;
3288 legalized = legalize_for_path (base);
3290 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3291 for (cnt = 1; cnt <= limit; ++cnt) {
3293 vector<space_and_path>::iterator i;
3294 uint32_t existing = 0;
3296 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3298 SessionDirectory sdir((*i).path);
3300 sys::path p = sdir.midi_path();
3303 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3305 if (sys::exists (buf)) {
3310 if (existing == 0) {
3315 error << string_compose(
3316 _("There are already %1 recordings for %2, which I consider too many."),
3317 limit, base) << endmsg;
3319 throw failed_constructor();
3323 return Glib::path_get_basename(buf);
3327 /** Create a new embedded MIDI source */
3328 boost::shared_ptr<MidiSource>
3329 Session::create_midi_source_for_session (MidiDiskstream& ds)
3331 const string name = new_midi_source_name (ds.name());
3332 const string path = new_source_path_from_name (DataType::MIDI, name);
3334 return boost::dynamic_pointer_cast<SMFSource> (
3335 SourceFactory::createWritable (
3336 DataType::MIDI, *this, path, true, false, frame_rate()));
3340 /* Playlist management */
3342 boost::shared_ptr<Playlist>
3343 Session::playlist_by_name (string name)
3345 Glib::Mutex::Lock lm (playlist_lock);
3346 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3347 if ((*i)->name() == name) {
3351 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3352 if ((*i)->name() == name) {
3357 return boost::shared_ptr<Playlist>();
3361 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3363 Glib::Mutex::Lock lm (playlist_lock);
3364 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3365 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3366 list.push_back (*i);
3369 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3370 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3371 list.push_back (*i);
3377 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3379 if (playlist->hidden()) {
3384 Glib::Mutex::Lock lm (playlist_lock);
3385 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3386 playlists.insert (playlists.begin(), playlist);
3387 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3388 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3393 playlist->release();
3398 PlaylistAdded (playlist); /* EMIT SIGNAL */
3402 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3405 Glib::Mutex::Lock lm (playlist_lock);
3406 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3409 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3416 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3418 boost::shared_ptr<Playlist> pl(wpl.lock());
3424 PlaylistList::iterator x;
3427 /* its not supposed to be visible */
3432 Glib::Mutex::Lock lm (playlist_lock);
3436 unused_playlists.insert (pl);
3438 if ((x = playlists.find (pl)) != playlists.end()) {
3439 playlists.erase (x);
3445 playlists.insert (pl);
3447 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3448 unused_playlists.erase (x);
3455 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3457 if (_state_of_the_state & Deletion) {
3461 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3468 Glib::Mutex::Lock lm (playlist_lock);
3470 PlaylistList::iterator i;
3472 i = find (playlists.begin(), playlists.end(), playlist);
3473 if (i != playlists.end()) {
3474 playlists.erase (i);
3477 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3478 if (i != unused_playlists.end()) {
3479 unused_playlists.erase (i);
3486 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3490 Session::set_audition (boost::shared_ptr<Region> r)
3492 pending_audition_region = r;
3493 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3494 schedule_butler_transport_work ();
3498 Session::audition_playlist ()
3500 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3501 ev->region.reset ();
3506 Session::non_realtime_set_audition ()
3508 if (!pending_audition_region) {
3509 auditioner->audition_current_playlist ();
3511 auditioner->audition_region (pending_audition_region);
3512 pending_audition_region.reset ();
3514 AuditionActive (true); /* EMIT SIGNAL */
3518 Session::audition_region (boost::shared_ptr<Region> r)
3520 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3526 Session::cancel_audition ()
3528 if (auditioner->active()) {
3529 auditioner->cancel_audition ();
3530 AuditionActive (false); /* EMIT SIGNAL */
3535 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3537 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3541 Session::remove_empty_sounds ()
3543 vector<string> audio_filenames;
3545 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3547 Glib::Mutex::Lock lm (source_lock);
3549 TapeFileMatcher tape_file_matcher;
3551 remove_if (audio_filenames.begin(), audio_filenames.end(),
3552 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3554 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3556 sys::path audio_file_path (_session_dir->sound_path());
3558 audio_file_path /= *i;
3560 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3564 sys::remove (audio_file_path);
3565 const string peakfile = peak_path (audio_file_path.to_string());
3566 sys::remove (peakfile);
3568 catch (const sys::filesystem_error& err)
3570 error << err.what() << endmsg;
3577 Session::is_auditioning () const
3579 /* can be called before we have an auditioner object */
3581 return auditioner->active();
3588 Session::set_all_solo (bool yn)
3590 shared_ptr<RouteList> r = routes.reader ();
3592 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3593 if (!(*i)->is_hidden()) {
3594 (*i)->set_solo (yn, this);
3602 Session::set_all_listen (bool yn)
3604 shared_ptr<RouteList> r = routes.reader ();
3606 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3607 if (!(*i)->is_hidden()) {
3608 (*i)->set_listen (yn, this);
3616 Session::set_all_mute (bool yn)
3618 shared_ptr<RouteList> r = routes.reader ();
3620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3621 if (!(*i)->is_hidden()) {
3622 (*i)->set_mute (yn, this);
3630 Session::n_diskstreams () const
3634 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3636 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3637 if (!(*i)->hidden()) {
3645 Session::graph_reordered ()
3647 /* don't do this stuff if we are setting up connections
3648 from a set_state() call or creating new tracks.
3651 if (_state_of_the_state & InitialConnecting) {
3655 /* every track/bus asked for this to be handled but it was deferred because
3656 we were connecting. do it now.
3659 request_input_change_handling ();
3663 /* force all diskstreams to update their capture offset values to
3664 reflect any changes in latencies within the graph.
3667 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3669 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3670 (*i)->set_capture_offset ();
3675 Session::record_disenable_all ()
3677 record_enable_change_all (false);
3681 Session::record_enable_all ()
3683 record_enable_change_all (true);
3687 Session::record_enable_change_all (bool yn)
3689 shared_ptr<RouteList> r = routes.reader ();
3691 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3692 boost::shared_ptr<Track> t;
3694 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3695 t->set_record_enable (yn, this);
3699 /* since we don't keep rec-enable state, don't mark session dirty */
3703 Session::add_processor (Processor* processor)
3705 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3710 Session::remove_processor (Processor* processor)
3714 PortInsert* port_insert;
3716 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3717 insert_bitset[port_insert->bit_slot()] = false;
3718 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3719 send_bitset[send->bit_slot()] = false;
3720 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3721 return_bitset[send->bit_slot()] = false;
3728 Session::available_capture_duration ()
3730 float sample_bytes_on_disk = 4.0; // keep gcc happy
3732 switch (config.get_native_file_data_format()) {
3734 sample_bytes_on_disk = 4.0;
3738 sample_bytes_on_disk = 3.0;
3742 sample_bytes_on_disk = 2.0;
3746 /* impossible, but keep some gcc versions happy */
3747 fatal << string_compose (_("programming error: %1"),
3748 X_("illegal native file data format"))
3753 double scale = 4096.0 / sample_bytes_on_disk;
3755 if (_total_free_4k_blocks * scale > (double) max_frames) {
3759 return (nframes_t) floor (_total_free_4k_blocks * scale);
3763 Session::add_bundle (shared_ptr<Bundle> bundle)
3766 RCUWriter<BundleList> writer (_bundles);
3767 boost::shared_ptr<BundleList> b = writer.get_copy ();
3768 b->push_back (bundle);
3771 BundleAdded (bundle); /* EMIT SIGNAL */
3777 Session::remove_bundle (shared_ptr<Bundle> bundle)
3779 bool removed = false;
3782 RCUWriter<BundleList> writer (_bundles);
3783 boost::shared_ptr<BundleList> b = writer.get_copy ();
3784 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3786 if (i != b->end()) {
3793 BundleRemoved (bundle); /* EMIT SIGNAL */
3800 Session::bundle_by_name (string name) const
3802 boost::shared_ptr<BundleList> b = _bundles.reader ();
3804 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3805 if ((*i)->name() == name) {
3810 return boost::shared_ptr<Bundle> ();
3814 Session::tempo_map_changed (Change)
3818 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3819 (*i)->update_after_tempo_map_change ();
3822 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3823 (*i)->update_after_tempo_map_change ();
3829 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3830 * the given count with the current block size.
3833 Session::ensure_buffers (ChanCount howmany)
3835 if (current_block_size == 0) {
3836 return; // too early? (is this ok?)
3839 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3840 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3841 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3842 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3843 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3846 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3850 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3852 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3853 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3858 Session::next_insert_id ()
3860 /* this doesn't really loop forever. just think about it */
3863 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3864 if (!insert_bitset[n]) {
3865 insert_bitset[n] = true;
3871 /* none available, so resize and try again */
3873 insert_bitset.resize (insert_bitset.size() + 16, false);
3878 Session::next_send_id ()
3880 /* this doesn't really loop forever. just think about it */
3883 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3884 if (!send_bitset[n]) {
3885 send_bitset[n] = true;
3891 /* none available, so resize and try again */
3893 send_bitset.resize (send_bitset.size() + 16, false);
3898 Session::next_return_id ()
3900 /* this doesn't really loop forever. just think about it */
3903 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3904 if (!return_bitset[n]) {
3905 return_bitset[n] = true;
3911 /* none available, so resize and try again */
3913 return_bitset.resize (return_bitset.size() + 16, false);
3918 Session::mark_send_id (uint32_t id)
3920 if (id >= send_bitset.size()) {
3921 send_bitset.resize (id+16, false);
3923 if (send_bitset[id]) {
3924 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3926 send_bitset[id] = true;
3930 Session::mark_return_id (uint32_t id)
3932 if (id >= return_bitset.size()) {
3933 return_bitset.resize (id+16, false);
3935 if (return_bitset[id]) {
3936 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3938 return_bitset[id] = true;
3942 Session::mark_insert_id (uint32_t id)
3944 if (id >= insert_bitset.size()) {
3945 insert_bitset.resize (id+16, false);
3947 if (insert_bitset[id]) {
3948 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3950 insert_bitset[id] = true;
3953 /* Named Selection management */
3956 Session::named_selection_by_name (string name)
3958 Glib::Mutex::Lock lm (named_selection_lock);
3959 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3960 if ((*i)->name == name) {
3968 Session::add_named_selection (NamedSelection* named_selection)
3971 Glib::Mutex::Lock lm (named_selection_lock);
3972 named_selections.insert (named_selections.begin(), named_selection);
3975 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3981 NamedSelectionAdded (); /* EMIT SIGNAL */
3985 Session::remove_named_selection (NamedSelection* named_selection)
3987 bool removed = false;
3990 Glib::Mutex::Lock lm (named_selection_lock);
3992 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3994 if (i != named_selections.end()) {
3996 named_selections.erase (i);
4003 NamedSelectionRemoved (); /* EMIT SIGNAL */
4008 Session::reset_native_file_format ()
4010 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4012 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4013 (*i)->reset_write_sources (false);
4018 Session::route_name_unique (string n) const
4020 shared_ptr<RouteList> r = routes.reader ();
4022 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4023 if ((*i)->name() == n) {
4032 Session::route_name_internal (string n) const
4034 if (auditioner && auditioner->name() == n) {
4038 if (_click_io && _click_io->name() == n) {
4046 Session::n_playlists () const
4048 Glib::Mutex::Lock lm (playlist_lock);
4049 return playlists.size();
4053 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4055 if (!force && howmany <= _npan_buffers) {
4059 if (_pan_automation_buffer) {
4061 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4062 delete [] _pan_automation_buffer[i];
4065 delete [] _pan_automation_buffer;
4068 _pan_automation_buffer = new pan_t*[howmany];
4070 for (uint32_t i = 0; i < howmany; ++i) {
4071 _pan_automation_buffer[i] = new pan_t[nframes];
4074 _npan_buffers = howmany;
4078 Session::freeze (InterThreadInfo& itt)
4080 shared_ptr<RouteList> r = routes.reader ();
4082 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4084 boost::shared_ptr<Track> t;
4086 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4087 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4097 boost::shared_ptr<Region>
4098 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4099 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4100 InterThreadInfo& itt, bool enable_processing)
4102 boost::shared_ptr<Region> result;
4103 boost::shared_ptr<Playlist> playlist;
4104 boost::shared_ptr<AudioFileSource> fsource;
4106 char buf[PATH_MAX+1];
4107 ChanCount nchans(track.audio_diskstream()->n_channels());
4109 nframes_t this_chunk;
4112 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4113 const string sound_dir = sdir.sound_path().to_string();
4114 nframes_t len = end - start;
4117 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4118 end, start) << endmsg;
4122 // any bigger than this seems to cause stack overflows in called functions
4123 const nframes_t chunk_size = (128 * 1024)/4;
4125 // block all process callback handling
4127 block_processing ();
4129 /* call tree *MUST* hold route_lock */
4131 if ((playlist = track.diskstream()->playlist()) == 0) {
4135 /* external redirects will be a problem */
4137 if (track.has_external_redirects()) {
4141 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4143 for (x = 0; x < 99999; ++x) {
4144 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4145 if (access (buf, F_OK) != 0) {
4151 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4156 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4157 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4160 catch (failed_constructor& err) {
4161 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4165 srcs.push_back (fsource);
4168 /* XXX need to flush all redirects */
4173 /* create a set of reasonably-sized buffers */
4174 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4175 buffers.set_count(nchans);
4177 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4178 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4180 afs->prepare_for_peakfile_writes ();
4183 while (to_do && !itt.cancel) {
4185 this_chunk = min (to_do, chunk_size);
4187 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4192 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4193 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4196 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4202 start += this_chunk;
4203 to_do -= this_chunk;
4205 itt.progress = (float) (1.0 - ((double) to_do / len));
4214 xnow = localtime (&now);
4216 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4217 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4220 afs->update_header (position, *xnow, now);
4221 afs->flush_header ();
4225 /* construct a region to represent the bounced material */
4227 result = RegionFactory::create (srcs, 0,
4228 srcs.front()->length(srcs.front()->timeline_position()),
4229 region_name_from_path (srcs.front()->name(), true));
4234 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4235 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4238 afs->mark_for_remove ();
4241 (*src)->drop_references ();
4245 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4246 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4249 afs->done_with_peakfile_writes ();
4253 unblock_processing ();
4259 Session::get_silent_buffers (ChanCount count)
4261 assert(_silent_buffers->available() >= count);
4262 _silent_buffers->set_count(count);
4264 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4265 for (size_t i= 0; i < count.get(*t); ++i) {
4266 _silent_buffers->get(*t, i).clear();
4270 return *_silent_buffers;
4274 Session::get_scratch_buffers (ChanCount count)
4276 if (count != ChanCount::ZERO) {
4277 assert(_scratch_buffers->available() >= count);
4278 _scratch_buffers->set_count(count);
4280 _scratch_buffers->set_count (_scratch_buffers->available());
4283 return *_scratch_buffers;
4287 Session::get_mix_buffers (ChanCount count)
4289 assert(_mix_buffers->available() >= count);
4290 _mix_buffers->set_count(count);
4291 return *_mix_buffers;
4295 Session::ntracks () const
4298 shared_ptr<RouteList> r = routes.reader ();
4300 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4301 if (boost::dynamic_pointer_cast<Track> (*i)) {
4310 Session::nbusses () const
4313 shared_ptr<RouteList> r = routes.reader ();
4315 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4316 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4325 Session::add_automation_list(AutomationList *al)
4327 automation_lists[al->id()] = al;
4331 Session::compute_initial_length ()
4333 return _engine.frame_rate() * 60 * 5;
4337 Session::sync_order_keys (std::string const & base)
4339 if (!Config->get_sync_all_route_ordering()) {
4340 /* leave order keys as they are */
4344 boost::shared_ptr<RouteList> r = routes.reader ();
4346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4347 (*i)->sync_order_keys (base);
4350 Route::SyncOrderKeys (base); // EMIT SIGNAL
4354 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4356 Session::have_rec_enabled_diskstream () const
4358 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4361 /** Update the state of our rec-enabled diskstreams flag */
4363 Session::update_have_rec_enabled_diskstream ()
4365 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4366 DiskstreamList::iterator i = dsl->begin ();
4367 while (i != dsl->end () && (*i)->record_enabled () == false) {
4371 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4373 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4375 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4376 RecordStateChanged (); /* EMIT SIGNAL */
4381 Session::listen_position_changed ()
4385 switch (Config->get_listen_position()) {
4386 case AfterFaderListen:
4390 case PreFaderListen:
4395 boost::shared_ptr<RouteList> r = routes.reader ();
4397 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4398 (*i)->put_control_outs_at (p);
4403 Session::solo_control_mode_changed ()
4405 /* cancel all solo or all listen when solo control mode changes */
4407 if (Config->get_solo_control_is_listen_control()) {
4408 set_all_solo (false);
4410 set_all_listen (false);
4415 Session::route_group_changed ()
4417 RouteGroupChanged (); /* EMIT SIGNAL */