2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/butler.h"
60 #include "ardour/click.h"
61 #include "ardour/configuration.h"
62 #include "ardour/crossfade.h"
63 #include "ardour/cycle_timer.h"
64 #include "ardour/data_type.h"
65 #include "ardour/filename_extensions.h"
66 #include "ardour/internal_send.h"
67 #include "ardour/io_processor.h"
68 #include "ardour/midi_diskstream.h"
69 #include "ardour/midi_playlist.h"
70 #include "ardour/midi_region.h"
71 #include "ardour/midi_track.h"
72 #include "ardour/named_selection.h"
73 #include "ardour/playlist.h"
74 #include "ardour/plugin_insert.h"
75 #include "ardour/port_insert.h"
76 #include "ardour/processor.h"
77 #include "ardour/recent_sessions.h"
78 #include "ardour/region_factory.h"
79 #include "ardour/return.h"
80 #include "ardour/route_group.h"
81 #include "ardour/send.h"
82 #include "ardour/session.h"
83 #include "ardour/session_directory.h"
84 #include "ardour/session_directory.h"
85 #include "ardour/session_metadata.h"
86 #include "ardour/slave.h"
87 #include "ardour/smf_source.h"
88 #include "ardour/source_factory.h"
89 #include "ardour/tape_file_matcher.h"
90 #include "ardour/tempo.h"
91 #include "ardour/utils.h"
96 using namespace ARDOUR;
98 using boost::shared_ptr;
100 bool Session::_disable_all_loaded_plugins = false;
102 sigc::signal<void,std::string> Session::Dialog;
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
105 sigc::signal<void> Session::SendFeedback;
107 sigc::signal<void> Session::SMPTEOffsetChanged;
108 sigc::signal<void> Session::StartTimeChanged;
109 sigc::signal<void> Session::EndTimeChanged;
110 sigc::signal<void> Session::AutoBindingOn;
111 sigc::signal<void> Session::AutoBindingOff;
112 sigc::signal<void, std::string, std::string> Session::Exported;
114 Session::Session (AudioEngine &eng,
115 const string& fullpath,
116 const string& snapshot_name,
120 _target_transport_speed (0.0),
121 _requested_return_frame (-1),
122 _scratch_buffers(new BufferSet()),
123 _silent_buffers(new BufferSet()),
124 _mix_buffers(new BufferSet()),
126 _mmc_port (default_mmc_port),
127 _mtc_port (default_mtc_port),
128 _midi_port (default_midi_port),
129 _midi_clock_port (default_midi_clock_port),
130 _session_dir (new SessionDirectory(fullpath)),
131 pending_events (2048),
133 butler (new Butler ()),
134 post_transport_work((PostTransportWork)0),
135 _send_smpte_update (false),
136 midi_thread (pthread_t (0)),
137 midi_requests (128), // the size of this should match the midi request pool size
138 diskstreams (new DiskstreamList),
139 routes (new RouteList),
140 _total_free_4k_blocks (0),
141 _bundles (new BundleList),
142 _bundle_xml_node (0),
145 click_emphasis_data (0),
147 _metadata (new SessionMetadata()),
148 _have_rec_enabled_diskstream (false)
153 interpolation.add_channel_to (0, 0);
155 if (!eng.connected()) {
156 throw failed_constructor();
159 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
161 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
162 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
164 first_stage_init (fullpath, snapshot_name);
166 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
169 if (create (new_session, mix_template, compute_initial_length())) {
171 throw failed_constructor ();
175 if (second_stage_init (new_session)) {
177 throw failed_constructor ();
180 store_recent_sessions(_name, _path);
182 bool was_dirty = dirty();
184 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
186 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
187 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
190 DirtyChanged (); /* EMIT SIGNAL */
194 Session::Session (AudioEngine &eng,
196 string snapshot_name,
197 AutoConnectOption input_ac,
198 AutoConnectOption output_ac,
199 uint32_t control_out_channels,
200 uint32_t master_out_channels,
201 uint32_t requested_physical_in,
202 uint32_t requested_physical_out,
203 nframes_t initial_length)
206 _target_transport_speed (0.0),
207 _requested_return_frame (-1),
208 _scratch_buffers(new BufferSet()),
209 _silent_buffers(new BufferSet()),
210 _mix_buffers(new BufferSet()),
212 _mmc_port (default_mmc_port),
213 _mtc_port (default_mtc_port),
214 _midi_port (default_midi_port),
215 _midi_clock_port (default_midi_clock_port),
216 _session_dir ( new SessionDirectory(fullpath)),
217 pending_events (2048),
219 butler (new Butler ()),
220 post_transport_work((PostTransportWork)0),
221 _send_smpte_update (false),
222 midi_thread (pthread_t (0)),
224 diskstreams (new DiskstreamList),
225 routes (new RouteList),
226 _total_free_4k_blocks (0),
227 _bundles (new BundleList),
228 _bundle_xml_node (0),
229 _click_io ((IO *) 0),
231 click_emphasis_data (0),
233 _metadata (new SessionMetadata()),
234 _have_rec_enabled_diskstream (false)
238 interpolation.add_channel_to (0, 0);
240 if (!eng.connected()) {
241 throw failed_constructor();
244 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
246 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
247 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
249 if (n_physical_inputs) {
250 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
253 if (n_physical_outputs) {
254 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
257 first_stage_init (fullpath, snapshot_name);
259 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
262 if (create (new_session, string(), initial_length)) {
264 throw failed_constructor ();
269 /* set up Master Out and Control Out if necessary */
274 if (master_out_channels) {
275 ChanCount count(DataType::AUDIO, master_out_channels);
276 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
277 r->input()->ensure_io (count, false, this);
278 r->output()->ensure_io (count, false, this);
279 r->set_remote_control_id (control_id);
283 /* prohibit auto-connect to master, because there isn't one */
284 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
287 if (control_out_channels) {
288 ChanCount count(DataType::AUDIO, control_out_channels);
289 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
290 r->input()->ensure_io (count, false, this);
291 r->output()->ensure_io (count, false, this);
292 r->set_remote_control_id (control_id++);
298 add_routes (rl, false);
303 if (no_auto_connect()) {
304 input_ac = AutoConnectOption (0);
305 output_ac = AutoConnectOption (0);
308 Config->set_input_auto_connect (input_ac);
309 Config->set_output_auto_connect (output_ac);
311 if (second_stage_init (new_session)) {
313 throw failed_constructor ();
316 store_recent_sessions (_name, _path);
318 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
320 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
331 /* if we got to here, leaving pending capture state around
335 remove_pending_capture_state ();
337 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
339 _engine.remove_session ();
341 GoingAway (); /* EMIT SIGNAL */
347 /* clear history so that no references to objects are held any more */
351 /* clear state tree so that no references to objects are held any more */
355 /* reset dynamic state version back to default */
357 Stateful::loading_state_version = 0;
359 terminate_butler_thread ();
360 //terminate_midi_thread ();
362 if (click_data != default_click) {
363 delete [] click_data;
366 if (click_emphasis_data != default_click_emphasis) {
367 delete [] click_emphasis_data;
372 delete _scratch_buffers;
373 delete _silent_buffers;
376 AudioDiskstream::free_working_buffers();
378 Route::SyncOrderKeys.clear();
380 #undef TRACK_DESTRUCTION
381 #ifdef TRACK_DESTRUCTION
382 cerr << "delete named selections\n";
383 #endif /* TRACK_DESTRUCTION */
384 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
385 NamedSelectionList::iterator tmp;
394 #ifdef TRACK_DESTRUCTION
395 cerr << "delete playlists\n";
396 #endif /* TRACK_DESTRUCTION */
397 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
398 PlaylistList::iterator tmp;
403 (*i)->drop_references ();
408 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
409 PlaylistList::iterator tmp;
414 (*i)->drop_references ();
420 unused_playlists.clear ();
422 #ifdef TRACK_DESTRUCTION
423 cerr << "delete regions\n";
424 #endif /* TRACK_DESTRUCTION */
426 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
427 RegionList::iterator tmp;
432 i->second->drop_references ();
439 #ifdef TRACK_DESTRUCTION
440 cerr << "delete routes\n";
441 #endif /* TRACK_DESTRUCTION */
443 RCUWriter<RouteList> writer (routes);
444 boost::shared_ptr<RouteList> r = writer.get_copy ();
445 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
446 (*i)->drop_references ();
449 /* writer goes out of scope and updates master */
454 #ifdef TRACK_DESTRUCTION
455 cerr << "delete diskstreams\n";
456 #endif /* TRACK_DESTRUCTION */
458 RCUWriter<DiskstreamList> dwriter (diskstreams);
459 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
460 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
461 (*i)->drop_references ();
465 diskstreams.flush ();
467 #ifdef TRACK_DESTRUCTION
468 cerr << "delete audio sources\n";
469 #endif /* TRACK_DESTRUCTION */
470 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
471 SourceMap::iterator tmp;
476 i->second->drop_references ();
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete route groups\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
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 */
551 if (Stateful::loading_state_version < 3000) {
552 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
554 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
559 _clicking = Config->get_clicking ();
563 error << _("could not setup Click I/O") << endmsg;
570 /* default state for Click: dual-mono to first 2 physical outputs */
572 for (int physport = 0; physport < 2; ++physport) {
573 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
575 if (physical_output.length()) {
576 if (_click_io->add_port (physical_output, this)) {
577 // relax, even though its an error
582 if (_click_io->n_ports () > ChanCount::ZERO) {
583 _clicking = Config->get_clicking ();
588 catch (failed_constructor& err) {
589 error << _("cannot setup Click I/O") << endmsg;
592 BootMessage (_("Compute I/O Latencies"));
594 set_worst_io_latencies ();
597 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
600 BootMessage (_("Set up standard connections"));
602 /* Create a set of Bundle objects that map
603 to the physical I/O currently available. We create both
604 mono and stereo bundles, so that the common cases of mono
605 and stereo tracks get bundles to put in their mixer strip
606 in / out menus. There may be a nicer way of achieving that;
607 it doesn't really scale that well to higher channel counts
610 /* mono output bundles */
612 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
614 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
616 shared_ptr<Bundle> c (new Bundle (buf, true));
617 c->add_channel (_("mono"));
618 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
623 /* stereo output bundles */
625 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
626 if (np + 1 < n_physical_outputs) {
628 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
629 shared_ptr<Bundle> c (new Bundle (buf, true));
630 c->add_channel (_("L"));
631 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
632 c->add_channel (_("R"));
633 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
639 /* mono input bundles */
641 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
643 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
645 shared_ptr<Bundle> c (new Bundle (buf, false));
646 c->add_channel (_("mono"));
647 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
652 /* stereo input bundles */
654 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
655 if (np + 1 < n_physical_inputs) {
657 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
659 shared_ptr<Bundle> c (new Bundle (buf, false));
660 c->add_channel (_("L"));
661 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
662 c->add_channel (_("R"));
663 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
669 BootMessage (_("Setup signal flow and plugins"));
673 if (!no_auto_connect()) {
675 if (_master_out && Config->get_auto_connect_standard_busses()) {
677 /* if requested auto-connect the outputs to the first N physical ports.
680 uint32_t limit = _master_out->n_outputs().n_total();
682 for (uint32_t n = 0; n < limit; ++n) {
683 Port* p = _master_out->output()->nth (n);
684 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
686 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
687 if (_master_out->output()->connect (p, connect_to, this)) {
688 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
698 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
699 are undefined, at best.
702 /* control out listens to master bus (but ignores it
703 under some conditions)
706 uint32_t limit = _control_out->n_inputs().n_audio();
709 for (uint32_t n = 0; n < limit; ++n) {
710 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
711 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
714 string connect_to = o->name();
715 if (_control_out->input()->connect (p, connect_to, this)) {
716 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
724 /* if control out is not connected,
725 connect control out to physical outs, but use ones after the master if possible
728 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
730 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
732 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
735 _control_out->output()->connect_ports_to_bundle (b, this);
737 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
738 Config->get_monitor_bus_preferred_bundle())
744 /* XXX this logic is wrong for mixed port types */
746 uint32_t shift = _master_out->n_outputs().n_audio();
747 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
748 limit = _control_out->n_outputs().n_audio();
750 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
752 for (uint32_t n = 0; n < limit; ++n) {
754 Port* p = _control_out->output()->nth (n);
755 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
757 if (!connect_to.empty()) {
758 if (_control_out->output()->connect (p, connect_to, this)) {
759 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
770 /* catch up on send+insert cnts */
772 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
774 /* hook us up to the engine */
776 BootMessage (_("Connect to engine"));
778 _engine.set_session (this);
782 Session::hookup_io ()
784 /* stop graph reordering notifications from
785 causing resorts, etc.
788 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
793 /* we delay creating the auditioner till now because
794 it makes its own connections to ports.
795 the engine has to be running for this to work.
799 auditioner.reset (new Auditioner (*this));
802 catch (failed_constructor& err) {
803 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
807 /* load bundles, which we may have postponed earlier on */
808 if (_bundle_xml_node) {
809 load_bundles (*_bundle_xml_node);
810 delete _bundle_xml_node;
813 /* Tell all IO objects to connect themselves together */
815 IO::enable_connecting ();
817 /* Now reset all panners */
819 Delivery::reset_panners ();
821 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
825 boost::shared_ptr<RouteList> r = routes.reader ();
827 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
829 if ((*x)->is_control() || (*x)->is_master()) {
833 (*x)->listen_via (_control_out,
834 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
839 /* Anyone who cares about input state, wake up and do something */
841 IOConnectionsComplete (); /* EMIT SIGNAL */
843 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
845 /* now handle the whole enchilada as if it was one
851 /* update the full solo state, which can't be
852 correctly determined on a per-route basis, but
853 needs the global overview that only the session
857 update_route_solo_state ();
861 Session::playlist_length_changed ()
863 /* we can't just increase end_location->end() if pl->get_maximum_extent()
864 if larger. if the playlist used to be the longest playlist,
865 and its now shorter, we have to decrease end_location->end(). hence,
866 we have to iterate over all diskstreams and check the
867 playlists currently in use.
873 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
875 boost::shared_ptr<Playlist> playlist;
877 if ((playlist = dstream->playlist()) != 0) {
878 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
881 /* see comment in playlist_length_changed () */
886 Session::record_enabling_legal () const
888 /* this used to be in here, but survey says.... we don't need to restrict it */
889 // if (record_status() == Recording) {
893 if (Config->get_all_safe()) {
900 Session::reset_input_monitor_state ()
902 if (transport_rolling()) {
904 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
906 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
907 if ((*i)->record_enabled ()) {
908 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
909 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
913 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
915 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
916 if ((*i)->record_enabled ()) {
917 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
918 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
925 Session::auto_punch_start_changed (Location* location)
927 replace_event (Event::PunchIn, location->start());
929 if (get_record_enabled() && config.get_punch_in()) {
930 /* capture start has been changed, so save new pending state */
931 save_state ("", true);
936 Session::auto_punch_end_changed (Location* location)
938 nframes_t when_to_stop = location->end();
939 // when_to_stop += _worst_output_latency + _worst_input_latency;
940 replace_event (Event::PunchOut, when_to_stop);
944 Session::auto_punch_changed (Location* location)
946 nframes_t when_to_stop = location->end();
948 replace_event (Event::PunchIn, location->start());
949 //when_to_stop += _worst_output_latency + _worst_input_latency;
950 replace_event (Event::PunchOut, when_to_stop);
954 Session::auto_loop_changed (Location* location)
956 replace_event (Event::AutoLoop, location->end(), location->start());
958 if (transport_rolling() && play_loop) {
960 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
962 if (_transport_frame > location->end()) {
963 // relocate to beginning of loop
964 clear_events (Event::LocateRoll);
966 request_locate (location->start(), true);
969 else if (Config->get_seamless_loop() && !loop_changing) {
971 // schedule a locate-roll to refill the diskstreams at the
973 loop_changing = true;
975 if (location->end() > last_loopend) {
976 clear_events (Event::LocateRoll);
977 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
984 last_loopend = location->end();
988 Session::set_auto_punch_location (Location* location)
992 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
993 auto_punch_start_changed_connection.disconnect();
994 auto_punch_end_changed_connection.disconnect();
995 auto_punch_changed_connection.disconnect();
996 existing->set_auto_punch (false, this);
997 remove_event (existing->start(), Event::PunchIn);
998 clear_events (Event::PunchOut);
999 auto_punch_location_changed (0);
1004 if (location == 0) {
1008 if (location->end() <= location->start()) {
1009 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1013 auto_punch_start_changed_connection.disconnect();
1014 auto_punch_end_changed_connection.disconnect();
1015 auto_punch_changed_connection.disconnect();
1017 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1018 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1019 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1021 location->set_auto_punch (true, this);
1024 auto_punch_changed (location);
1026 auto_punch_location_changed (location);
1030 Session::set_auto_loop_location (Location* location)
1034 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1035 auto_loop_start_changed_connection.disconnect();
1036 auto_loop_end_changed_connection.disconnect();
1037 auto_loop_changed_connection.disconnect();
1038 existing->set_auto_loop (false, this);
1039 remove_event (existing->end(), Event::AutoLoop);
1040 auto_loop_location_changed (0);
1045 if (location == 0) {
1049 if (location->end() <= location->start()) {
1050 error << _("Session: you can't use a mark for auto loop") << endmsg;
1054 last_loopend = location->end();
1056 auto_loop_start_changed_connection.disconnect();
1057 auto_loop_end_changed_connection.disconnect();
1058 auto_loop_changed_connection.disconnect();
1060 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1061 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1062 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1064 location->set_auto_loop (true, this);
1066 /* take care of our stuff first */
1068 auto_loop_changed (location);
1070 /* now tell everyone else */
1072 auto_loop_location_changed (location);
1076 Session::locations_added (Location *)
1082 Session::locations_changed ()
1084 _locations.apply (*this, &Session::handle_locations_changed);
1088 Session::handle_locations_changed (Locations::LocationList& locations)
1090 Locations::LocationList::iterator i;
1092 bool set_loop = false;
1093 bool set_punch = false;
1095 for (i = locations.begin(); i != locations.end(); ++i) {
1099 if (location->is_auto_punch()) {
1100 set_auto_punch_location (location);
1103 if (location->is_auto_loop()) {
1104 set_auto_loop_location (location);
1108 if (location->is_start()) {
1109 start_location = location;
1111 if (location->is_end()) {
1112 end_location = location;
1117 set_auto_loop_location (0);
1120 set_auto_punch_location (0);
1127 Session::enable_record ()
1129 /* XXX really atomic compare+swap here */
1130 if (g_atomic_int_get (&_record_status) != Recording) {
1131 g_atomic_int_set (&_record_status, Recording);
1132 _last_record_location = _transport_frame;
1133 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1135 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1136 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1137 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1138 if ((*i)->record_enabled ()) {
1139 (*i)->monitor_input (true);
1144 RecordStateChanged ();
1149 Session::disable_record (bool rt_context, bool force)
1153 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1155 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1156 g_atomic_int_set (&_record_status, Disabled);
1158 if (rs == Recording) {
1159 g_atomic_int_set (&_record_status, Enabled);
1163 // FIXME: timestamp correct? [DR]
1164 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1165 // does this /need/ to be sent in all cases?
1167 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1169 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1170 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1172 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1173 if ((*i)->record_enabled ()) {
1174 (*i)->monitor_input (false);
1179 RecordStateChanged (); /* emit signal */
1182 remove_pending_capture_state ();
1188 Session::step_back_from_record ()
1190 /* XXX really atomic compare+swap here */
1191 if (g_atomic_int_get (&_record_status) == Recording) {
1192 g_atomic_int_set (&_record_status, Enabled);
1194 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1195 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1197 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1198 if ((*i)->record_enabled ()) {
1199 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1200 (*i)->monitor_input (false);
1208 Session::maybe_enable_record ()
1210 g_atomic_int_set (&_record_status, Enabled);
1212 /* this function is currently called from somewhere other than an RT thread.
1213 this save_state() call therefore doesn't impact anything.
1216 save_state ("", true);
1218 if (_transport_speed) {
1219 if (!config.get_punch_in()) {
1223 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1224 RecordStateChanged (); /* EMIT SIGNAL */
1231 Session::audible_frame () const
1237 /* the first of these two possible settings for "offset"
1238 mean that the audible frame is stationary until
1239 audio emerges from the latency compensation
1242 the second means that the audible frame is stationary
1243 until audio would emerge from a physical port
1244 in the absence of any plugin latency compensation
1247 offset = _worst_output_latency;
1249 if (offset > current_block_size) {
1250 offset -= current_block_size;
1252 /* XXX is this correct? if we have no external
1253 physical connections and everything is internal
1254 then surely this is zero? still, how
1255 likely is that anyway?
1257 offset = current_block_size;
1260 if (synced_to_jack()) {
1261 tf = _engine.transport_frame();
1263 tf = _transport_frame;
1268 if (!non_realtime_work_pending()) {
1272 /* check to see if we have passed the first guaranteed
1273 audible frame past our last start position. if not,
1274 return that last start point because in terms
1275 of audible frames, we have not moved yet.
1278 if (_transport_speed > 0.0f) {
1280 if (!play_loop || !have_looped) {
1281 if (tf < _last_roll_location + offset) {
1282 return _last_roll_location;
1290 } else if (_transport_speed < 0.0f) {
1292 /* XXX wot? no backward looping? */
1294 if (tf > _last_roll_location - offset) {
1295 return _last_roll_location;
1307 Session::set_frame_rate (nframes_t frames_per_second)
1309 /** \fn void Session::set_frame_size(nframes_t)
1310 the AudioEngine object that calls this guarantees
1311 that it will not be called while we are also in
1312 ::process(). Its fine to do things that block
1316 _base_frame_rate = frames_per_second;
1320 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1324 // XXX we need some equivalent to this, somehow
1325 // SndFileSource::setup_standard_crossfades (frames_per_second);
1329 /* XXX need to reset/reinstantiate all LADSPA plugins */
1333 Session::set_block_size (nframes_t nframes)
1335 /* the AudioEngine guarantees
1336 that it will not be called while we are also in
1337 ::process(). It is therefore fine to do things that block
1342 current_block_size = nframes;
1344 ensure_buffers(_scratch_buffers->available());
1346 delete [] _gain_automation_buffer;
1347 _gain_automation_buffer = new gain_t[nframes];
1349 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1351 boost::shared_ptr<RouteList> r = routes.reader ();
1353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1354 (*i)->set_block_size (nframes);
1357 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1358 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1359 (*i)->set_block_size (nframes);
1362 set_worst_io_latencies ();
1367 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1370 nframes_t fade_frames;
1372 /* Don't allow fade of less 1 frame */
1374 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1381 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1385 default_fade_msecs = fade_msecs;
1386 default_fade_steepness = steepness;
1389 // jlc, WTF is this!
1390 Glib::RWLock::ReaderLock lm (route_lock);
1391 AudioRegion::set_default_fade (steepness, fade_frames);
1396 /* XXX have to do this at some point */
1397 /* foreach region using default fade, reset, then
1398 refill_all_diskstream_buffers ();
1403 struct RouteSorter {
1404 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1405 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1407 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1410 if (r1->fed_by.empty()) {
1411 if (r2->fed_by.empty()) {
1412 /* no ardour-based connections inbound to either route. just use signal order */
1413 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1415 /* r2 has connections, r1 does not; run r1 early */
1419 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1426 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1428 shared_ptr<Route> r2;
1430 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1431 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1435 /* make a copy of the existing list of routes that feed r1 */
1437 set<shared_ptr<Route> > existing = r1->fed_by;
1439 /* for each route that feeds r1, recurse, marking it as feeding
1443 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1446 /* r2 is a route that feeds r1 which somehow feeds base. mark
1447 base as being fed by r2
1450 rbase->fed_by.insert (r2);
1454 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1458 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1462 /* now recurse, so that we can mark base as being fed by
1463 all routes that feed r2
1466 trace_terminal (r2, rbase);
1473 Session::resort_routes ()
1475 /* don't do anything here with signals emitted
1476 by Routes while we are being destroyed.
1479 if (_state_of_the_state & Deletion) {
1486 RCUWriter<RouteList> writer (routes);
1487 shared_ptr<RouteList> r = writer.get_copy ();
1488 resort_routes_using (r);
1489 /* writer goes out of scope and forces update */
1494 Session::resort_routes_using (shared_ptr<RouteList> r)
1496 RouteList::iterator i, j;
1498 for (i = r->begin(); i != r->end(); ++i) {
1500 (*i)->fed_by.clear ();
1502 for (j = r->begin(); j != r->end(); ++j) {
1504 /* although routes can feed themselves, it will
1505 cause an endless recursive descent if we
1506 detect it. so don't bother checking for
1514 if ((*j)->feeds (*i)) {
1515 (*i)->fed_by.insert (*j);
1520 for (i = r->begin(); i != r->end(); ++i) {
1521 trace_terminal (*i, *i);
1528 cerr << "finished route resort\n";
1530 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1531 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1538 list<boost::shared_ptr<MidiTrack> >
1539 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1541 char track_name[32];
1542 uint32_t track_id = 0;
1545 RouteList new_routes;
1546 list<boost::shared_ptr<MidiTrack> > ret;
1547 //uint32_t control_id;
1549 // FIXME: need physical I/O and autoconnect stuff for MIDI
1551 /* count existing midi tracks */
1554 shared_ptr<RouteList> r = routes.reader ();
1556 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1557 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1558 if (!(*i)->is_hidden()) {
1560 //channels_used += (*i)->n_inputs().n_midi();
1566 vector<string> physinputs;
1567 vector<string> physoutputs;
1569 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1570 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1572 // control_id = ntracks() + nbusses();
1576 /* check for duplicate route names, since we might have pre-existing
1577 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1578 save, close,restart,add new route - first named route is now
1586 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1588 if (route_by_name (track_name) == 0) {
1592 } while (track_id < (UINT_MAX-1));
1594 shared_ptr<MidiTrack> track;
1597 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1599 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1600 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1605 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1606 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1612 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1616 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1617 port = physinputs[(channels_used+x)%nphysical_in];
1620 if (port.length() && track->connect_input (track->input (x), port, this)) {
1626 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1630 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1631 port = physoutputs[(channels_used+x)%nphysical_out];
1632 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1634 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1638 if (port.length() && track->connect_output (track->output (x), port, this)) {
1643 channels_used += track->n_inputs ().n_midi();
1647 track->midi_diskstream()->non_realtime_input_change();
1648 track->set_route_group (route_group, 0);
1650 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1651 //track->set_remote_control_id (control_id);
1653 new_routes.push_back (track);
1654 ret.push_back (track);
1657 catch (failed_constructor &err) {
1658 error << _("Session: could not create new midi track.") << endmsg;
1661 /* we need to get rid of this, since the track failed to be created */
1662 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1665 RCUWriter<DiskstreamList> writer (diskstreams);
1666 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1667 ds->remove (track->midi_diskstream());
1674 catch (AudioEngine::PortRegistrationFailure& pfe) {
1676 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;
1679 /* we need to get rid of this, since the track failed to be created */
1680 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1683 RCUWriter<DiskstreamList> writer (diskstreams);
1684 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1685 ds->remove (track->midi_diskstream());
1696 if (!new_routes.empty()) {
1697 add_routes (new_routes, false);
1698 save_state (_current_snapshot_name);
1704 list<boost::shared_ptr<AudioTrack> >
1705 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1707 char track_name[32];
1708 uint32_t track_id = 0;
1710 uint32_t channels_used = 0;
1712 RouteList new_routes;
1713 list<boost::shared_ptr<AudioTrack> > ret;
1714 uint32_t control_id;
1716 /* count existing audio tracks */
1719 shared_ptr<RouteList> r = routes.reader ();
1721 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1722 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1723 if (!(*i)->is_hidden()) {
1725 channels_used += (*i)->n_inputs().n_audio();
1731 vector<string> physinputs;
1732 vector<string> physoutputs;
1734 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1735 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1737 control_id = ntracks() + nbusses() + 1;
1741 /* check for duplicate route names, since we might have pre-existing
1742 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1743 save, close,restart,add new route - first named route is now
1751 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1753 if (route_by_name (track_name) == 0) {
1757 } while (track_id < (UINT_MAX-1));
1759 shared_ptr<AudioTrack> track;
1762 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1764 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1765 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1766 input_channels, output_channels)
1771 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1772 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1773 input_channels, output_channels)
1778 if (!physinputs.empty()) {
1779 uint32_t nphysical_in = physinputs.size();
1781 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1785 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1786 port = physinputs[(channels_used+x)%nphysical_in];
1789 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1795 if (!physoutputs.empty()) {
1796 uint32_t nphysical_out = physoutputs.size();
1798 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1801 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1802 port = physoutputs[(channels_used+x)%nphysical_out];
1803 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1804 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1805 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1809 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1815 channels_used += track->n_inputs ().n_audio();
1817 track->set_route_group (route_group, 0);
1819 track->audio_diskstream()->non_realtime_input_change();
1821 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1822 track->set_remote_control_id (control_id);
1825 new_routes.push_back (track);
1826 ret.push_back (track);
1829 catch (failed_constructor &err) {
1830 error << _("Session: could not create new audio track.") << endmsg;
1833 /* we need to get rid of this, since the track failed to be created */
1834 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1837 RCUWriter<DiskstreamList> writer (diskstreams);
1838 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1839 ds->remove (track->audio_diskstream());
1846 catch (AudioEngine::PortRegistrationFailure& pfe) {
1848 error << pfe.what() << endmsg;
1851 /* we need to get rid of this, since the track failed to be created */
1852 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1855 RCUWriter<DiskstreamList> writer (diskstreams);
1856 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1857 ds->remove (track->audio_diskstream());
1868 if (!new_routes.empty()) {
1869 add_routes (new_routes, true);
1876 Session::set_remote_control_ids ()
1878 RemoteModel m = Config->get_remote_model();
1880 shared_ptr<RouteList> r = routes.reader ();
1882 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1883 if ( MixerOrdered == m) {
1884 long order = (*i)->order_key(N_("signal"));
1885 (*i)->set_remote_control_id( order+1 );
1886 } else if ( EditorOrdered == m) {
1887 long order = (*i)->order_key(N_("editor"));
1888 (*i)->set_remote_control_id( order+1 );
1889 } else if ( UserOrdered == m) {
1890 //do nothing ... only changes to remote id's are initiated by user
1897 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1900 uint32_t bus_id = 1;
1902 uint32_t channels_used = 0;
1905 uint32_t control_id;
1907 /* count existing audio busses */
1910 shared_ptr<RouteList> r = routes.reader ();
1912 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1913 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1915 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1918 channels_used += (*i)->n_inputs().n_audio();
1924 vector<string> physinputs;
1925 vector<string> physoutputs;
1927 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1928 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1930 n_physical_audio_outputs = physoutputs.size();
1931 n_physical_audio_inputs = physinputs.size();
1933 control_id = ntracks() + nbusses() + 1;
1938 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1942 if (route_by_name (bus_name) == 0) {
1946 } while (bus_id < (UINT_MAX-1));
1949 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1951 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1952 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1953 input_channels, output_channels)
1959 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1960 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1961 input_channels, output_channels)
1966 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1969 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1970 port = physinputs[((n+x)%n_physical_audio_inputs)];
1973 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1978 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1981 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1982 port = physoutputs[((n+x)%n_physical_outputs)];
1983 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1985 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1989 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1994 channels_used += bus->n_inputs ().n_audio();
1996 bus->set_route_group (route_group, 0);
1997 bus->set_remote_control_id (control_id);
2000 ret.push_back (bus);
2004 catch (failed_constructor &err) {
2005 error << _("Session: could not create new audio route.") << endmsg;
2009 catch (AudioEngine::PortRegistrationFailure& pfe) {
2010 error << pfe.what() << endmsg;
2020 add_routes (ret, true);
2028 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2032 uint32_t control_id;
2034 uint32_t number = 1;
2036 if (!tree.read (template_path.c_str())) {
2040 XMLNode* node = tree.root();
2042 control_id = ntracks() + nbusses() + 1;
2046 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2048 std::string node_name = IO::name_from_state (*node_copy.children().front());
2050 /* generate a new name by adding a number to the end of the template name */
2053 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2057 if (route_by_name (name) == 0) {
2061 } while (number < UINT_MAX);
2063 if (number == UINT_MAX) {
2064 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2068 IO::set_name_in_state (*node_copy.children().front(), name);
2070 Track::zero_diskstream_id_in_xml (node_copy);
2073 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2076 error << _("Session: cannot create track/bus from template description") << endmsg;
2080 if (boost::dynamic_pointer_cast<Track>(route)) {
2081 /* force input/output change signals so that the new diskstream
2082 picks up the configuration of the route. During session
2083 loading this normally happens in a different way.
2085 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2086 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2089 route->set_remote_control_id (control_id);
2092 ret.push_back (route);
2095 catch (failed_constructor &err) {
2096 error << _("Session: could not create new route from template") << endmsg;
2100 catch (AudioEngine::PortRegistrationFailure& pfe) {
2101 error << pfe.what() << endmsg;
2110 add_routes (ret, true);
2117 Session::add_routes (RouteList& new_routes, bool save)
2120 RCUWriter<RouteList> writer (routes);
2121 shared_ptr<RouteList> r = writer.get_copy ();
2122 r->insert (r->end(), new_routes.begin(), new_routes.end());
2125 /* if there is no control out and we're not in the middle of loading,
2126 resort the graph here. if there is a control out, we will resort
2127 toward the end of this method. if we are in the middle of loading,
2128 we will resort when done.
2131 if (!_control_out && IO::connecting_legal) {
2132 resort_routes_using (r);
2136 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2138 boost::weak_ptr<Route> wpr (*x);
2140 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2141 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2142 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2143 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2144 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2145 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2147 if ((*x)->is_master()) {
2151 if ((*x)->is_control()) {
2152 _control_out = (*x);
2156 if (_control_out && IO::connecting_legal) {
2158 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2159 if ((*x)->is_control() || (*x)->is_master()) {
2162 (*x)->listen_via (_control_out,
2163 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2173 save_state (_current_snapshot_name);
2176 RouteAdded (new_routes); /* EMIT SIGNAL */
2180 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2182 boost::shared_ptr<RouteList> r = routes.reader ();
2183 boost::shared_ptr<Send> s;
2187 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2188 if (boost::dynamic_pointer_cast<Track>(*i)) {
2189 if ((s = (*i)->internal_send_for (dest)) != 0) {
2190 s->amp()->gain_control()->set_value (0.0);
2197 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2199 boost::shared_ptr<RouteList> r = routes.reader ();
2200 boost::shared_ptr<Send> s;
2204 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2205 if (boost::dynamic_pointer_cast<Track>(*i)) {
2206 if ((s = (*i)->internal_send_for (dest)) != 0) {
2207 s->amp()->gain_control()->set_value (1.0);
2214 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2216 boost::shared_ptr<RouteList> r = routes.reader ();
2217 boost::shared_ptr<Send> s;
2221 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2222 if (boost::dynamic_pointer_cast<Track>(*i)) {
2223 if ((s = (*i)->internal_send_for (dest)) != 0) {
2224 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2231 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2233 boost::shared_ptr<RouteList> r = routes.reader ();
2234 boost::shared_ptr<RouteList> t (new RouteList);
2236 /* only send tracks */
2238 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2239 if (boost::dynamic_pointer_cast<Track>(*i)) {
2244 add_internal_sends (dest, p, t);
2249 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2251 if (dest->is_control() || dest->is_master()) {
2255 if (!dest->internal_return()) {
2256 dest->add_internal_return();
2259 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2261 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2265 (*i)->listen_via (dest, p, true, true);
2270 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2272 /* need to do this in case we're rolling at the time, to prevent false underruns */
2273 dstream->do_refill_with_alloc ();
2275 dstream->set_block_size (current_block_size);
2278 RCUWriter<DiskstreamList> writer (diskstreams);
2279 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2280 ds->push_back (dstream);
2281 /* writer goes out of scope, copies ds back to main */
2284 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2285 /* this will connect to future changes, and check the current length */
2286 diskstream_playlist_changed (dstream);
2288 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2290 dstream->prepare ();
2295 Session::remove_route (shared_ptr<Route> route)
2298 RCUWriter<RouteList> writer (routes);
2299 shared_ptr<RouteList> rs = writer.get_copy ();
2303 /* deleting the master out seems like a dumb
2304 idea, but its more of a UI policy issue
2308 if (route == _master_out) {
2309 _master_out = shared_ptr<Route> ();
2312 if (route == _control_out) {
2314 /* cancel control outs for all routes */
2316 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2317 (*r)->drop_listen (_control_out);
2320 _control_out.reset ();
2323 update_route_solo_state ();
2325 /* writer goes out of scope, forces route list update */
2328 boost::shared_ptr<Track> t;
2329 boost::shared_ptr<Diskstream> ds;
2331 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2332 ds = t->diskstream();
2338 RCUWriter<DiskstreamList> dsl (diskstreams);
2339 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2344 find_current_end ();
2346 // We need to disconnect the routes inputs and outputs
2348 route->input()->disconnect (0);
2349 route->output()->disconnect (0);
2351 update_latency_compensation (false, false);
2354 /* get rid of it from the dead wood collection in the route list manager */
2356 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2360 /* try to cause everyone to drop their references */
2362 route->drop_references ();
2364 sync_order_keys (N_("session"));
2366 /* save the new state of the world */
2368 if (save_state (_current_snapshot_name)) {
2369 save_history (_current_snapshot_name);
2374 Session::route_mute_changed (void* /*src*/)
2380 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2382 boost::shared_ptr<Route> route = wpr.lock();
2384 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2388 if (route->listening()) {
2390 } else if (_listen_cnt > 0) {
2396 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2398 if (solo_update_disabled) {
2403 boost::shared_ptr<Route> route = wpr.lock ();
2406 /* should not happen */
2407 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2411 shared_ptr<RouteList> r = routes.reader ();
2414 if (route->soloed()) {
2420 /* now mod the solo level of all other routes except master & control outs
2421 so that they will be silent if appropriate.
2424 solo_update_disabled = true;
2425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2427 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2429 (*i)->mod_solo_level (delta);
2433 /* make sure master is never muted by solo */
2435 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2436 _master_out->mod_solo_level (1);
2439 /* ditto for control outs make sure master is never muted by solo */
2441 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2442 _control_out->mod_solo_level (1);
2445 solo_update_disabled = false;
2446 update_route_solo_state (r);
2447 SoloChanged (); /* EMIT SIGNAL */
2452 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2454 /* now figure out if anything that matters is soloed */
2456 bool something_soloed = false;
2459 r = routes.reader();
2462 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2463 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2464 something_soloed = true;
2469 if (something_soloed != _non_soloed_outs_muted) {
2470 _non_soloed_outs_muted = something_soloed;
2471 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2476 Session::route_by_name (string name)
2478 shared_ptr<RouteList> r = routes.reader ();
2480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2481 if ((*i)->name() == name) {
2486 return shared_ptr<Route> ((Route*) 0);
2490 Session::route_by_id (PBD::ID id)
2492 shared_ptr<RouteList> r = routes.reader ();
2494 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2495 if ((*i)->id() == id) {
2500 return shared_ptr<Route> ((Route*) 0);
2504 Session::route_by_remote_id (uint32_t id)
2506 shared_ptr<RouteList> r = routes.reader ();
2508 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2509 if ((*i)->remote_control_id() == id) {
2514 return shared_ptr<Route> ((Route*) 0);
2518 Session::find_current_end ()
2520 if (_state_of_the_state & Loading) {
2524 nframes_t max = get_maximum_extent ();
2526 if (max > end_location->end()) {
2527 end_location->set_end (max);
2529 DurationChanged(); /* EMIT SIGNAL */
2534 Session::get_maximum_extent () const
2539 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2541 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2542 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2544 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2545 if ((me = pl->get_maximum_extent()) > max) {
2553 boost::shared_ptr<Diskstream>
2554 Session::diskstream_by_name (string name)
2556 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2558 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2559 if ((*i)->name() == name) {
2564 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2567 boost::shared_ptr<Diskstream>
2568 Session::diskstream_by_id (const PBD::ID& id)
2570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2572 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2573 if ((*i)->id() == id) {
2578 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2581 /* Region management */
2584 Session::new_region_name (string old)
2586 string::size_type last_period;
2588 string::size_type len = old.length() + 64;
2591 if ((last_period = old.find_last_of ('.')) == string::npos) {
2593 /* no period present - add one explicitly */
2596 last_period = old.length() - 1;
2601 number = atoi (old.substr (last_period+1).c_str());
2605 while (number < (UINT_MAX-1)) {
2607 RegionList::const_iterator i;
2612 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2615 for (i = regions.begin(); i != regions.end(); ++i) {
2616 if (i->second->name() == sbuf) {
2621 if (i == regions.end()) {
2626 if (number != (UINT_MAX-1)) {
2630 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2635 Session::region_name (string& result, string base, bool newlevel)
2640 if (base.find("/") != string::npos) {
2641 base = base.substr(base.find_last_of("/") + 1);
2646 Glib::Mutex::Lock lm (region_lock);
2648 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2657 string::size_type pos;
2659 pos = base.find_last_of ('.');
2661 /* pos may be npos, but then we just use entire base */
2663 subbase = base.substr (0, pos);
2668 Glib::Mutex::Lock lm (region_lock);
2670 map<string,uint32_t>::iterator x;
2674 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2676 region_name_map[subbase] = 1;
2679 snprintf (buf, sizeof (buf), ".%d", x->second);
2690 Session::add_region (boost::shared_ptr<Region> region)
2692 vector<boost::shared_ptr<Region> > v;
2693 v.push_back (region);
2698 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2703 Glib::Mutex::Lock lm (region_lock);
2705 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2707 boost::shared_ptr<Region> region = *ii;
2711 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2715 RegionList::iterator x;
2717 for (x = regions.begin(); x != regions.end(); ++x) {
2719 if (region->region_list_equivalent (x->second)) {
2724 if (x == regions.end()) {
2726 pair<RegionList::key_type,RegionList::mapped_type> entry;
2728 entry.first = region->id();
2729 entry.second = region;
2731 pair<RegionList::iterator,bool> x = regions.insert (entry);
2743 /* mark dirty because something has changed even if we didn't
2744 add the region to the region list.
2751 vector<boost::weak_ptr<Region> > v;
2752 boost::shared_ptr<Region> first_r;
2754 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2756 boost::shared_ptr<Region> region = *ii;
2760 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2763 v.push_back (region);
2770 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2771 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2773 update_region_name_map (region);
2777 RegionsAdded (v); /* EMIT SIGNAL */
2783 Session::update_region_name_map (boost::shared_ptr<Region> region)
2785 string::size_type last_period = region->name().find_last_of ('.');
2787 if (last_period != string::npos && last_period < region->name().length() - 1) {
2789 string base = region->name().substr (0, last_period);
2790 string number = region->name().substr (last_period+1);
2791 map<string,uint32_t>::iterator x;
2793 /* note that if there is no number, we get zero from atoi,
2797 region_name_map[base] = atoi (number);
2802 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2804 boost::shared_ptr<Region> region (weak_region.lock ());
2810 if (what_changed & Region::HiddenChanged) {
2811 /* relay hidden changes */
2812 RegionHiddenChange (region);
2815 if (what_changed & NameChanged) {
2816 update_region_name_map (region);
2821 Session::remove_region (boost::weak_ptr<Region> weak_region)
2823 RegionList::iterator i;
2824 boost::shared_ptr<Region> region (weak_region.lock ());
2830 bool removed = false;
2833 Glib::Mutex::Lock lm (region_lock);
2835 if ((i = regions.find (region->id())) != regions.end()) {
2841 /* mark dirty because something has changed even if we didn't
2842 remove the region from the region list.
2848 RegionRemoved(region); /* EMIT SIGNAL */
2852 boost::shared_ptr<Region>
2853 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2855 RegionList::iterator i;
2856 boost::shared_ptr<Region> region;
2858 Glib::Mutex::Lock lm (region_lock);
2860 for (i = regions.begin(); i != regions.end(); ++i) {
2864 if (region->whole_file()) {
2866 if (child->source_equivalent (region)) {
2872 return boost::shared_ptr<Region> ();
2876 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2878 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2879 (*i)->get_region_list_equivalent_regions (region, result);
2883 Session::destroy_region (boost::shared_ptr<Region> region)
2885 vector<boost::shared_ptr<Source> > srcs;
2888 if (region->playlist()) {
2889 region->playlist()->destroy_region (region);
2892 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2893 srcs.push_back (region->source (n));
2897 region->drop_references ();
2899 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2901 (*i)->mark_for_remove ();
2902 (*i)->drop_references ();
2904 cerr << "source was not used by any playlist\n";
2911 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2913 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2914 destroy_region (*i);
2920 Session::remove_last_capture ()
2922 list<boost::shared_ptr<Region> > r;
2924 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2926 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2927 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2930 r.insert (r.end(), l.begin(), l.end());
2935 destroy_regions (r);
2937 save_state (_current_snapshot_name);
2943 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2949 /* Source Management */
2952 Session::add_source (boost::shared_ptr<Source> source)
2954 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2955 pair<SourceMap::iterator,bool> result;
2957 entry.first = source->id();
2958 entry.second = source;
2961 Glib::Mutex::Lock lm (source_lock);
2962 result = sources.insert (entry);
2965 if (result.second) {
2966 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2970 boost::shared_ptr<AudioFileSource> afs;
2972 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2973 if (Config->get_auto_analyse_audio()) {
2974 Analyser::queue_source_for_analysis (source, false);
2980 Session::remove_source (boost::weak_ptr<Source> src)
2982 SourceMap::iterator i;
2983 boost::shared_ptr<Source> source = src.lock();
2990 Glib::Mutex::Lock lm (source_lock);
2992 if ((i = sources.find (source->id())) != sources.end()) {
2997 if (!_state_of_the_state & InCleanup) {
2999 /* save state so we don't end up with a session file
3000 referring to non-existent sources.
3003 save_state (_current_snapshot_name);
3007 boost::shared_ptr<Source>
3008 Session::source_by_id (const PBD::ID& id)
3010 Glib::Mutex::Lock lm (source_lock);
3011 SourceMap::iterator i;
3012 boost::shared_ptr<Source> source;
3014 if ((i = sources.find (id)) != sources.end()) {
3021 boost::shared_ptr<Source>
3022 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3024 Glib::Mutex::Lock lm (source_lock);
3026 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3027 cerr << "comparing " << path << " with " << i->second->name() << endl;
3028 boost::shared_ptr<AudioFileSource> afs
3029 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3031 if (afs && afs->path() == path && chn == afs->channel()) {
3035 return boost::shared_ptr<Source>();
3040 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3043 string old_basename = PBD::basename_nosuffix (oldname);
3044 string new_legalized = legalize_for_path (newname);
3046 /* note: we know (or assume) the old path is already valid */
3050 /* destructive file sources have a name of the form:
3052 /path/to/Tnnnn-NAME(%[LR])?.wav
3054 the task here is to replace NAME with the new name.
3057 /* find last slash */
3061 string::size_type slash;
3062 string::size_type dash;
3064 if ((slash = path.find_last_of ('/')) == string::npos) {
3068 dir = path.substr (0, slash+1);
3070 /* '-' is not a legal character for the NAME part of the path */
3072 if ((dash = path.find_last_of ('-')) == string::npos) {
3076 prefix = path.substr (slash+1, dash-(slash+1));
3081 path += new_legalized;
3082 path += ".wav"; /* XXX gag me with a spoon */
3086 /* non-destructive file sources have a name of the form:
3088 /path/to/NAME-nnnnn(%[LR])?.ext
3090 the task here is to replace NAME with the new name.
3095 string::size_type slash;
3096 string::size_type dash;
3097 string::size_type postfix;
3099 /* find last slash */
3101 if ((slash = path.find_last_of ('/')) == string::npos) {
3105 dir = path.substr (0, slash+1);
3107 /* '-' is not a legal character for the NAME part of the path */
3109 if ((dash = path.find_last_of ('-')) == string::npos) {
3113 suffix = path.substr (dash+1);
3115 // Suffix is now everything after the dash. Now we need to eliminate
3116 // the nnnnn part, which is done by either finding a '%' or a '.'
3118 postfix = suffix.find_last_of ("%");
3119 if (postfix == string::npos) {
3120 postfix = suffix.find_last_of ('.');
3123 if (postfix != string::npos) {
3124 suffix = suffix.substr (postfix);
3126 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3130 const uint32_t limit = 10000;
3131 char buf[PATH_MAX+1];
3133 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3135 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3137 if (access (buf, F_OK) != 0) {
3145 error << "FATAL ERROR! Could not find a " << endl;
3153 /** Return the full path (in some session directory) for a new embedded source.
3154 * \a name must be a session-unique name that does not contain slashes
3155 * (e.g. as returned by new_*_source_name)
3158 Session::new_source_path_from_name (DataType type, const string& name)
3160 assert(name.find("/") == string::npos);
3162 SessionDirectory sdir(get_best_session_directory_for_new_source());
3165 if (type == DataType::AUDIO) {
3166 p = sdir.sound_path();
3167 } else if (type == DataType::MIDI) {
3168 p = sdir.midi_path();
3170 error << "Unknown source type, unable to create file path" << endmsg;
3175 return p.to_string();
3179 Session::peak_path (Glib::ustring base) const
3181 sys::path peakfile_path(_session_dir->peak_path());
3182 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3183 return peakfile_path.to_string();
3186 /** Return a unique name based on \a base for a new internal audio source */
3188 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3192 char buf[PATH_MAX+1];
3193 const uint32_t limit = 10000;
3197 legalized = legalize_for_path (base);
3199 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3200 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3202 vector<space_and_path>::iterator i;
3203 uint32_t existing = 0;
3205 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3207 SessionDirectory sdir((*i).path);
3209 spath = sdir.sound_path().to_string();
3214 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3215 spath.c_str(), cnt, legalized.c_str());
3216 } else if (nchan == 2) {
3218 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3219 spath.c_str(), cnt, legalized.c_str());
3221 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3222 spath.c_str(), cnt, legalized.c_str());
3224 } else if (nchan < 26) {
3225 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3226 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3228 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3229 spath.c_str(), cnt, legalized.c_str());
3238 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3239 } else if (nchan == 2) {
3241 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3243 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3245 } else if (nchan < 26) {
3246 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3248 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3252 if (sys::exists(buf)) {
3258 if (existing == 0) {
3263 error << string_compose(
3264 _("There are already %1 recordings for %2, which I consider too many."),
3265 limit, base) << endmsg;
3267 throw failed_constructor();
3271 return Glib::path_get_basename(buf);
3274 /** Create a new embedded audio source */
3275 boost::shared_ptr<AudioFileSource>
3276 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3278 const size_t n_chans = ds.n_channels().n_audio();
3279 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3280 const string path = new_source_path_from_name(DataType::AUDIO, name);
3281 return boost::dynamic_pointer_cast<AudioFileSource> (
3282 SourceFactory::createWritable (
3283 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3286 /** Return a unique name based on \a base for a new internal MIDI source */
3288 Session::new_midi_source_name (const string& base)
3291 char buf[PATH_MAX+1];
3292 const uint32_t limit = 10000;
3296 legalized = legalize_for_path (base);
3298 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3299 for (cnt = 1; cnt <= limit; ++cnt) {
3301 vector<space_and_path>::iterator i;
3302 uint32_t existing = 0;
3304 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3306 SessionDirectory sdir((*i).path);
3308 sys::path p = sdir.midi_path();
3311 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3313 if (sys::exists (buf)) {
3318 if (existing == 0) {
3323 error << string_compose(
3324 _("There are already %1 recordings for %2, which I consider too many."),
3325 limit, base) << endmsg;
3327 throw failed_constructor();
3331 return Glib::path_get_basename(buf);
3335 /** Create a new embedded MIDI source */
3336 boost::shared_ptr<MidiSource>
3337 Session::create_midi_source_for_session (MidiDiskstream& ds)
3339 const string name = new_midi_source_name (ds.name());
3340 const string path = new_source_path_from_name (DataType::MIDI, name);
3342 return boost::dynamic_pointer_cast<SMFSource> (
3343 SourceFactory::createWritable (
3344 DataType::MIDI, *this, path, true, false, frame_rate()));
3348 /* Playlist management */
3350 boost::shared_ptr<Playlist>
3351 Session::playlist_by_name (string name)
3353 Glib::Mutex::Lock lm (playlist_lock);
3354 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3355 if ((*i)->name() == name) {
3359 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3360 if ((*i)->name() == name) {
3365 return boost::shared_ptr<Playlist>();
3369 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3371 Glib::Mutex::Lock lm (playlist_lock);
3372 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3373 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3374 list.push_back (*i);
3377 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3378 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3379 list.push_back (*i);
3385 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3387 if (playlist->hidden()) {
3392 Glib::Mutex::Lock lm (playlist_lock);
3393 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3394 playlists.insert (playlists.begin(), playlist);
3395 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3396 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3401 playlist->release();
3406 PlaylistAdded (playlist); /* EMIT SIGNAL */
3410 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3413 Glib::Mutex::Lock lm (playlist_lock);
3414 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3417 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3424 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3426 boost::shared_ptr<Playlist> pl(wpl.lock());
3432 PlaylistList::iterator x;
3435 /* its not supposed to be visible */
3440 Glib::Mutex::Lock lm (playlist_lock);
3444 unused_playlists.insert (pl);
3446 if ((x = playlists.find (pl)) != playlists.end()) {
3447 playlists.erase (x);
3453 playlists.insert (pl);
3455 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3456 unused_playlists.erase (x);
3463 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3465 if (_state_of_the_state & Deletion) {
3469 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3476 Glib::Mutex::Lock lm (playlist_lock);
3478 PlaylistList::iterator i;
3480 i = find (playlists.begin(), playlists.end(), playlist);
3481 if (i != playlists.end()) {
3482 playlists.erase (i);
3485 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3486 if (i != unused_playlists.end()) {
3487 unused_playlists.erase (i);
3494 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3498 Session::set_audition (boost::shared_ptr<Region> r)
3500 pending_audition_region = r;
3501 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3502 schedule_butler_transport_work ();
3506 Session::audition_playlist ()
3508 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3509 ev->region.reset ();
3514 Session::non_realtime_set_audition ()
3516 if (!pending_audition_region) {
3517 auditioner->audition_current_playlist ();
3519 auditioner->audition_region (pending_audition_region);
3520 pending_audition_region.reset ();
3522 AuditionActive (true); /* EMIT SIGNAL */
3526 Session::audition_region (boost::shared_ptr<Region> r)
3528 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3534 Session::cancel_audition ()
3536 if (auditioner->active()) {
3537 auditioner->cancel_audition ();
3538 AuditionActive (false); /* EMIT SIGNAL */
3543 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3545 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3549 Session::remove_empty_sounds ()
3551 vector<string> audio_filenames;
3553 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3555 Glib::Mutex::Lock lm (source_lock);
3557 TapeFileMatcher tape_file_matcher;
3559 remove_if (audio_filenames.begin(), audio_filenames.end(),
3560 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3562 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3564 sys::path audio_file_path (_session_dir->sound_path());
3566 audio_file_path /= *i;
3568 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3572 sys::remove (audio_file_path);
3573 const string peakfile = peak_path (audio_file_path.to_string());
3574 sys::remove (peakfile);
3576 catch (const sys::filesystem_error& err)
3578 error << err.what() << endmsg;
3585 Session::is_auditioning () const
3587 /* can be called before we have an auditioner object */
3589 return auditioner->active();
3596 Session::set_all_solo (bool yn)
3598 shared_ptr<RouteList> r = routes.reader ();
3600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3601 if (!(*i)->is_hidden()) {
3602 (*i)->set_solo (yn, this);
3610 Session::set_all_listen (bool yn)
3612 shared_ptr<RouteList> r = routes.reader ();
3614 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3615 if (!(*i)->is_hidden()) {
3616 (*i)->set_listen (yn, this);
3624 Session::set_all_mute (bool yn)
3626 shared_ptr<RouteList> r = routes.reader ();
3628 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3629 if (!(*i)->is_hidden()) {
3630 (*i)->set_mute (yn, this);
3638 Session::n_diskstreams () const
3642 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3644 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3645 if (!(*i)->hidden()) {
3653 Session::graph_reordered ()
3655 /* don't do this stuff if we are setting up connections
3656 from a set_state() call or creating new tracks.
3659 if (_state_of_the_state & InitialConnecting) {
3663 /* every track/bus asked for this to be handled but it was deferred because
3664 we were connecting. do it now.
3667 request_input_change_handling ();
3671 /* force all diskstreams to update their capture offset values to
3672 reflect any changes in latencies within the graph.
3675 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3677 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3678 (*i)->set_capture_offset ();
3683 Session::record_disenable_all ()
3685 record_enable_change_all (false);
3689 Session::record_enable_all ()
3691 record_enable_change_all (true);
3695 Session::record_enable_change_all (bool yn)
3697 shared_ptr<RouteList> r = routes.reader ();
3699 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3700 boost::shared_ptr<Track> t;
3702 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3703 t->set_record_enable (yn, this);
3707 /* since we don't keep rec-enable state, don't mark session dirty */
3711 Session::add_processor (Processor* processor)
3713 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3718 Session::remove_processor (Processor* processor)
3722 PortInsert* port_insert;
3724 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3725 insert_bitset[port_insert->bit_slot()] = false;
3726 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3727 send_bitset[send->bit_slot()] = false;
3728 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3729 return_bitset[send->bit_slot()] = false;
3736 Session::available_capture_duration ()
3738 float sample_bytes_on_disk = 4.0; // keep gcc happy
3740 switch (config.get_native_file_data_format()) {
3742 sample_bytes_on_disk = 4.0;
3746 sample_bytes_on_disk = 3.0;
3750 sample_bytes_on_disk = 2.0;
3754 /* impossible, but keep some gcc versions happy */
3755 fatal << string_compose (_("programming error: %1"),
3756 X_("illegal native file data format"))
3761 double scale = 4096.0 / sample_bytes_on_disk;
3763 if (_total_free_4k_blocks * scale > (double) max_frames) {
3767 return (nframes_t) floor (_total_free_4k_blocks * scale);
3771 Session::add_bundle (shared_ptr<Bundle> bundle)
3774 RCUWriter<BundleList> writer (_bundles);
3775 boost::shared_ptr<BundleList> b = writer.get_copy ();
3776 b->push_back (bundle);
3779 BundleAdded (bundle); /* EMIT SIGNAL */
3785 Session::remove_bundle (shared_ptr<Bundle> bundle)
3787 bool removed = false;
3790 RCUWriter<BundleList> writer (_bundles);
3791 boost::shared_ptr<BundleList> b = writer.get_copy ();
3792 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3794 if (i != b->end()) {
3801 BundleRemoved (bundle); /* EMIT SIGNAL */
3808 Session::bundle_by_name (string name) const
3810 boost::shared_ptr<BundleList> b = _bundles.reader ();
3812 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3813 if ((*i)->name() == name) {
3818 return boost::shared_ptr<Bundle> ();
3822 Session::tempo_map_changed (Change)
3826 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3827 (*i)->update_after_tempo_map_change ();
3830 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3831 (*i)->update_after_tempo_map_change ();
3837 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3838 * the given count with the current block size.
3841 Session::ensure_buffers (ChanCount howmany)
3843 if (current_block_size == 0) {
3844 return; // too early? (is this ok?)
3847 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3848 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3849 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3850 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3851 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3854 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3858 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3860 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3861 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3866 Session::next_insert_id ()
3868 /* this doesn't really loop forever. just think about it */
3871 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3872 if (!insert_bitset[n]) {
3873 insert_bitset[n] = true;
3879 /* none available, so resize and try again */
3881 insert_bitset.resize (insert_bitset.size() + 16, false);
3886 Session::next_send_id ()
3888 /* this doesn't really loop forever. just think about it */
3891 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3892 if (!send_bitset[n]) {
3893 send_bitset[n] = true;
3899 /* none available, so resize and try again */
3901 send_bitset.resize (send_bitset.size() + 16, false);
3906 Session::next_return_id ()
3908 /* this doesn't really loop forever. just think about it */
3911 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3912 if (!return_bitset[n]) {
3913 return_bitset[n] = true;
3919 /* none available, so resize and try again */
3921 return_bitset.resize (return_bitset.size() + 16, false);
3926 Session::mark_send_id (uint32_t id)
3928 if (id >= send_bitset.size()) {
3929 send_bitset.resize (id+16, false);
3931 if (send_bitset[id]) {
3932 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3934 send_bitset[id] = true;
3938 Session::mark_return_id (uint32_t id)
3940 if (id >= return_bitset.size()) {
3941 return_bitset.resize (id+16, false);
3943 if (return_bitset[id]) {
3944 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3946 return_bitset[id] = true;
3950 Session::mark_insert_id (uint32_t id)
3952 if (id >= insert_bitset.size()) {
3953 insert_bitset.resize (id+16, false);
3955 if (insert_bitset[id]) {
3956 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3958 insert_bitset[id] = true;
3961 /* Named Selection management */
3964 Session::named_selection_by_name (string name)
3966 Glib::Mutex::Lock lm (named_selection_lock);
3967 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3968 if ((*i)->name == name) {
3976 Session::add_named_selection (NamedSelection* named_selection)
3979 Glib::Mutex::Lock lm (named_selection_lock);
3980 named_selections.insert (named_selections.begin(), named_selection);
3983 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3989 NamedSelectionAdded (); /* EMIT SIGNAL */
3993 Session::remove_named_selection (NamedSelection* named_selection)
3995 bool removed = false;
3998 Glib::Mutex::Lock lm (named_selection_lock);
4000 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4002 if (i != named_selections.end()) {
4004 named_selections.erase (i);
4011 NamedSelectionRemoved (); /* EMIT SIGNAL */
4016 Session::reset_native_file_format ()
4018 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4020 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4021 (*i)->reset_write_sources (false);
4026 Session::route_name_unique (string n) const
4028 shared_ptr<RouteList> r = routes.reader ();
4030 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4031 if ((*i)->name() == n) {
4040 Session::route_name_internal (string n) const
4042 if (auditioner && auditioner->name() == n) {
4046 if (_click_io && _click_io->name() == n) {
4054 Session::n_playlists () const
4056 Glib::Mutex::Lock lm (playlist_lock);
4057 return playlists.size();
4061 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4063 if (!force && howmany <= _npan_buffers) {
4067 if (_pan_automation_buffer) {
4069 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4070 delete [] _pan_automation_buffer[i];
4073 delete [] _pan_automation_buffer;
4076 _pan_automation_buffer = new pan_t*[howmany];
4078 for (uint32_t i = 0; i < howmany; ++i) {
4079 _pan_automation_buffer[i] = new pan_t[nframes];
4082 _npan_buffers = howmany;
4086 Session::freeze (InterThreadInfo& itt)
4088 shared_ptr<RouteList> r = routes.reader ();
4090 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4092 boost::shared_ptr<Track> t;
4094 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4095 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4105 boost::shared_ptr<Region>
4106 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4107 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4108 InterThreadInfo& itt, bool enable_processing)
4110 boost::shared_ptr<Region> result;
4111 boost::shared_ptr<Playlist> playlist;
4112 boost::shared_ptr<AudioFileSource> fsource;
4114 char buf[PATH_MAX+1];
4115 ChanCount nchans(track.audio_diskstream()->n_channels());
4117 nframes_t this_chunk;
4120 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4121 const string sound_dir = sdir.sound_path().to_string();
4122 nframes_t len = end - start;
4125 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4126 end, start) << endmsg;
4130 // any bigger than this seems to cause stack overflows in called functions
4131 const nframes_t chunk_size = (128 * 1024)/4;
4133 // block all process callback handling
4135 block_processing ();
4137 /* call tree *MUST* hold route_lock */
4139 if ((playlist = track.diskstream()->playlist()) == 0) {
4143 /* external redirects will be a problem */
4145 if (track.has_external_redirects()) {
4149 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4151 for (x = 0; x < 99999; ++x) {
4152 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4153 if (access (buf, F_OK) != 0) {
4159 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4164 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4165 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4168 catch (failed_constructor& err) {
4169 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4173 srcs.push_back (fsource);
4176 /* XXX need to flush all redirects */
4181 /* create a set of reasonably-sized buffers */
4182 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4183 buffers.set_count(nchans);
4185 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4186 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4188 afs->prepare_for_peakfile_writes ();
4191 while (to_do && !itt.cancel) {
4193 this_chunk = min (to_do, chunk_size);
4195 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4200 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4201 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4204 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4210 start += this_chunk;
4211 to_do -= this_chunk;
4213 itt.progress = (float) (1.0 - ((double) to_do / len));
4222 xnow = localtime (&now);
4224 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4225 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4228 afs->update_header (position, *xnow, now);
4229 afs->flush_header ();
4233 /* construct a region to represent the bounced material */
4235 result = RegionFactory::create (srcs, 0,
4236 srcs.front()->length(srcs.front()->timeline_position()),
4237 region_name_from_path (srcs.front()->name(), true));
4242 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4243 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4246 afs->mark_for_remove ();
4249 (*src)->drop_references ();
4253 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4254 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4257 afs->done_with_peakfile_writes ();
4261 unblock_processing ();
4267 Session::get_silent_buffers (ChanCount count)
4269 assert(_silent_buffers->available() >= count);
4270 _silent_buffers->set_count(count);
4272 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4273 for (size_t i= 0; i < count.get(*t); ++i) {
4274 _silent_buffers->get(*t, i).clear();
4278 return *_silent_buffers;
4282 Session::get_scratch_buffers (ChanCount count)
4284 if (count != ChanCount::ZERO) {
4285 assert(_scratch_buffers->available() >= count);
4286 _scratch_buffers->set_count(count);
4288 _scratch_buffers->set_count (_scratch_buffers->available());
4291 return *_scratch_buffers;
4295 Session::get_mix_buffers (ChanCount count)
4297 assert(_mix_buffers->available() >= count);
4298 _mix_buffers->set_count(count);
4299 return *_mix_buffers;
4303 Session::ntracks () const
4306 shared_ptr<RouteList> r = routes.reader ();
4308 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4309 if (boost::dynamic_pointer_cast<Track> (*i)) {
4318 Session::nbusses () const
4321 shared_ptr<RouteList> r = routes.reader ();
4323 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4324 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4333 Session::add_automation_list(AutomationList *al)
4335 automation_lists[al->id()] = al;
4339 Session::compute_initial_length ()
4341 return _engine.frame_rate() * 60 * 5;
4345 Session::sync_order_keys (std::string const & base)
4347 if (!Config->get_sync_all_route_ordering()) {
4348 /* leave order keys as they are */
4352 boost::shared_ptr<RouteList> r = routes.reader ();
4354 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4355 (*i)->sync_order_keys (base);
4358 Route::SyncOrderKeys (base); // EMIT SIGNAL
4362 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4364 Session::have_rec_enabled_diskstream () const
4366 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4369 /** Update the state of our rec-enabled diskstreams flag */
4371 Session::update_have_rec_enabled_diskstream ()
4373 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4374 DiskstreamList::iterator i = dsl->begin ();
4375 while (i != dsl->end () && (*i)->record_enabled () == false) {
4379 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4381 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4383 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4384 RecordStateChanged (); /* EMIT SIGNAL */
4389 Session::listen_position_changed ()
4393 switch (Config->get_listen_position()) {
4394 case AfterFaderListen:
4398 case PreFaderListen:
4403 boost::shared_ptr<RouteList> r = routes.reader ();
4405 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4406 (*i)->put_control_outs_at (p);
4411 Session::solo_control_mode_changed ()
4413 /* cancel all solo or all listen when solo control mode changes */
4415 if (Config->get_solo_control_is_listen_control()) {
4416 set_all_solo (false);
4418 set_all_listen (false);
4423 Session::route_group_changed ()
4425 RouteGroupChanged (); /* EMIT SIGNAL */