2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/filename_extensions.h"
65 #include "ardour/internal_send.h"
66 #include "ardour/io_processor.h"
67 #include "ardour/midi_diskstream.h"
68 #include "ardour/midi_playlist.h"
69 #include "ardour/midi_region.h"
70 #include "ardour/midi_track.h"
71 #include "ardour/named_selection.h"
72 #include "ardour/playlist.h"
73 #include "ardour/plugin_insert.h"
74 #include "ardour/port_insert.h"
75 #include "ardour/processor.h"
76 #include "ardour/recent_sessions.h"
77 #include "ardour/region_factory.h"
78 #include "ardour/return.h"
79 #include "ardour/route_group.h"
80 #include "ardour/send.h"
81 #include "ardour/session.h"
82 #include "ardour/session_directory.h"
83 #include "ardour/session_directory.h"
84 #include "ardour/session_metadata.h"
85 #include "ardour/slave.h"
86 #include "ardour/smf_source.h"
87 #include "ardour/source_factory.h"
88 #include "ardour/tape_file_matcher.h"
89 #include "ardour/tempo.h"
90 #include "ardour/utils.h"
95 using namespace ARDOUR;
97 using boost::shared_ptr;
99 bool Session::_disable_all_loaded_plugins = false;
101 sigc::signal<void,std::string> Session::Dialog;
102 sigc::signal<int> Session::AskAboutPendingState;
103 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
109 sigc::signal<void> Session::AutoBindingOn;
110 sigc::signal<void> Session::AutoBindingOff;
111 sigc::signal<void, std::string, std::string> Session::Exported;
113 Session::Session (AudioEngine &eng,
114 const string& fullpath,
115 const string& snapshot_name,
119 _target_transport_speed (0.0),
120 _requested_return_frame (-1),
121 _scratch_buffers(new BufferSet()),
122 _silent_buffers(new BufferSet()),
123 _mix_buffers(new BufferSet()),
125 _mmc_port (default_mmc_port),
126 _mtc_port (default_mtc_port),
127 _midi_port (default_midi_port),
128 _midi_clock_port (default_midi_clock_port),
129 _session_dir (new SessionDirectory(fullpath)),
130 pending_events (2048),
132 butler_mixdown_buffer (0),
133 butler_gain_buffer (0),
134 post_transport_work((PostTransportWork)0),
135 _send_smpte_update (false),
136 midi_thread (pthread_t (0)),
137 midi_requests (128), // the size of this should match the midi request pool size
138 diskstreams (new DiskstreamList),
139 routes (new RouteList),
140 _total_free_4k_blocks (0),
141 _bundles (new BundleList),
142 _bundle_xml_node (0),
145 click_emphasis_data (0),
147 _metadata (new SessionMetadata()),
148 _have_rec_enabled_diskstream (false)
153 interpolation.add_channel_to (0, 0);
155 if (!eng.connected()) {
156 throw failed_constructor();
159 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
161 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
162 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
164 first_stage_init (fullpath, snapshot_name);
166 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
169 if (create (new_session, mix_template, compute_initial_length())) {
171 throw failed_constructor ();
175 if (second_stage_init (new_session)) {
177 throw failed_constructor ();
180 store_recent_sessions(_name, _path);
182 bool was_dirty = dirty();
184 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
186 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
187 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
190 DirtyChanged (); /* EMIT SIGNAL */
194 Session::Session (AudioEngine &eng,
196 string snapshot_name,
197 AutoConnectOption input_ac,
198 AutoConnectOption output_ac,
199 uint32_t control_out_channels,
200 uint32_t master_out_channels,
201 uint32_t requested_physical_in,
202 uint32_t requested_physical_out,
203 nframes_t initial_length)
206 _target_transport_speed (0.0),
207 _requested_return_frame (-1),
208 _scratch_buffers(new BufferSet()),
209 _silent_buffers(new BufferSet()),
210 _mix_buffers(new BufferSet()),
212 _mmc_port (default_mmc_port),
213 _mtc_port (default_mtc_port),
214 _midi_port (default_midi_port),
215 _midi_clock_port (default_midi_clock_port),
216 _session_dir ( new SessionDirectory(fullpath)),
217 pending_events (2048),
219 butler_mixdown_buffer (0),
220 butler_gain_buffer (0),
221 post_transport_work((PostTransportWork)0),
222 _send_smpte_update (false),
223 midi_thread (pthread_t (0)),
225 diskstreams (new DiskstreamList),
226 routes (new RouteList),
227 _total_free_4k_blocks (0),
228 _bundles (new BundleList),
229 _bundle_xml_node (0),
230 _click_io ((IO *) 0),
232 click_emphasis_data (0),
234 _metadata (new SessionMetadata()),
235 _have_rec_enabled_diskstream (false)
239 interpolation.add_channel_to (0, 0);
241 if (!eng.connected()) {
242 throw failed_constructor();
245 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
247 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
248 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
250 if (n_physical_inputs) {
251 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
254 if (n_physical_outputs) {
255 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
258 first_stage_init (fullpath, snapshot_name);
260 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
263 if (create (new_session, string(), initial_length)) {
265 throw failed_constructor ();
270 /* set up Master Out and Control Out if necessary */
275 if (master_out_channels) {
276 ChanCount count(DataType::AUDIO, master_out_channels);
277 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
278 r->input()->ensure_io (count, false, this);
279 r->output()->ensure_io (count, false, this);
280 r->set_remote_control_id (control_id);
284 /* prohibit auto-connect to master, because there isn't one */
285 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
288 if (control_out_channels) {
289 ChanCount count(DataType::AUDIO, control_out_channels);
290 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
291 r->input()->ensure_io (count, false, this);
292 r->output()->ensure_io (count, false, this);
293 r->set_remote_control_id (control_id++);
299 add_routes (rl, false);
304 if (no_auto_connect()) {
305 input_ac = AutoConnectOption (0);
306 output_ac = AutoConnectOption (0);
309 Config->set_input_auto_connect (input_ac);
310 Config->set_output_auto_connect (output_ac);
312 if (second_stage_init (new_session)) {
314 throw failed_constructor ();
317 store_recent_sessions (_name, _path);
319 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
321 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
332 /* if we got to here, leaving pending capture state around
336 remove_pending_capture_state ();
338 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
340 _engine.remove_session ();
342 GoingAway (); /* EMIT SIGNAL */
348 /* clear history so that no references to objects are held any more */
352 /* clear state tree so that no references to objects are held any more */
356 /* reset dynamic state version back to default */
358 Stateful::loading_state_version = 0;
360 terminate_butler_thread ();
361 //terminate_midi_thread ();
363 if (click_data != default_click) {
364 delete [] click_data;
367 if (click_emphasis_data != default_click_emphasis) {
368 delete [] click_emphasis_data;
373 delete _scratch_buffers;
374 delete _silent_buffers;
377 AudioDiskstream::free_working_buffers();
379 Route::SyncOrderKeys.clear();
381 #undef TRACK_DESTRUCTION
382 #ifdef TRACK_DESTRUCTION
383 cerr << "delete named selections\n";
384 #endif /* TRACK_DESTRUCTION */
385 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
386 NamedSelectionList::iterator tmp;
395 #ifdef TRACK_DESTRUCTION
396 cerr << "delete playlists\n";
397 #endif /* TRACK_DESTRUCTION */
398 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
399 PlaylistList::iterator tmp;
404 (*i)->drop_references ();
409 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
410 PlaylistList::iterator tmp;
415 (*i)->drop_references ();
421 unused_playlists.clear ();
423 #ifdef TRACK_DESTRUCTION
424 cerr << "delete regions\n";
425 #endif /* TRACK_DESTRUCTION */
427 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
428 RegionList::iterator tmp;
433 i->second->drop_references ();
440 #ifdef TRACK_DESTRUCTION
441 cerr << "delete routes\n";
442 #endif /* TRACK_DESTRUCTION */
444 RCUWriter<RouteList> writer (routes);
445 boost::shared_ptr<RouteList> r = writer.get_copy ();
446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
447 (*i)->drop_references ();
450 /* writer goes out of scope and updates master */
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete diskstreams\n";
457 #endif /* TRACK_DESTRUCTION */
459 RCUWriter<DiskstreamList> dwriter (diskstreams);
460 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
461 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
462 (*i)->drop_references ();
466 diskstreams.flush ();
468 #ifdef TRACK_DESTRUCTION
469 cerr << "delete audio sources\n";
470 #endif /* TRACK_DESTRUCTION */
471 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
472 SourceMap::iterator tmp;
477 i->second->drop_references ();
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete route groups\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
491 delete [] butler_mixdown_buffer;
492 delete [] butler_gain_buffer;
494 Crossfade::set_buffer_size (0);
500 Session::set_worst_io_latencies ()
502 _worst_output_latency = 0;
503 _worst_input_latency = 0;
505 if (!_engine.connected()) {
509 boost::shared_ptr<RouteList> r = routes.reader ();
511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
512 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
513 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
518 Session::when_engine_running ()
520 string first_physical_output;
522 BootMessage (_("Set block size and sample rate"));
524 set_block_size (_engine.frames_per_cycle());
525 set_frame_rate (_engine.frame_rate());
527 BootMessage (_("Using configuration"));
529 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
531 /* every time we reconnect, recompute worst case output latencies */
533 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
535 if (synced_to_jack()) {
536 _engine.transport_stop ();
539 if (config.get_jack_time_master()) {
540 _engine.transport_locate (_transport_frame);
548 _click_io.reset (new ClickIO (*this, "click"));
550 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
552 /* existing state for Click */
554 if (_click_io->set_state (*child->children().front(), Stateful::loading_state_version) == 0) {
556 _clicking = Config->get_clicking ();
560 error << _("could not setup Click I/O") << endmsg;
566 /* default state for Click: dual-mono to first 2 physical outputs */
568 for (int physport = 0; physport < 2; ++physport) {
569 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
571 if (physical_output.length()) {
572 if (_click_io->add_port (physical_output, this)) {
573 // relax, even though its an error
578 if (_click_io->n_ports () > ChanCount::ZERO) {
579 _clicking = Config->get_clicking ();
584 catch (failed_constructor& err) {
585 error << _("cannot setup Click I/O") << endmsg;
588 BootMessage (_("Compute I/O Latencies"));
590 set_worst_io_latencies ();
593 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
596 BootMessage (_("Set up standard connections"));
598 /* Create a set of Bundle objects that map
599 to the physical I/O currently available. We create both
600 mono and stereo bundles, so that the common cases of mono
601 and stereo tracks get bundles to put in their mixer strip
602 in / out menus. There may be a nicer way of achieving that;
603 it doesn't really scale that well to higher channel counts
606 /* mono output bundles */
608 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
610 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
612 shared_ptr<Bundle> c (new Bundle (buf, true));
613 c->add_channel (_("mono"));
614 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
619 /* stereo output bundles */
621 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
622 if (np + 1 < n_physical_outputs) {
624 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
625 shared_ptr<Bundle> c (new Bundle (buf, true));
626 c->add_channel (_("L"));
627 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
628 c->add_channel (_("R"));
629 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
635 /* mono input bundles */
637 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
639 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
641 shared_ptr<Bundle> c (new Bundle (buf, false));
642 c->add_channel (_("mono"));
643 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
648 /* stereo input bundles */
650 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
651 if (np + 1 < n_physical_inputs) {
653 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
655 shared_ptr<Bundle> c (new Bundle (buf, false));
656 c->add_channel (_("L"));
657 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
658 c->add_channel (_("R"));
659 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
665 BootMessage (_("Setup signal flow and plugins"));
669 if (!no_auto_connect()) {
671 if (_master_out && Config->get_auto_connect_standard_busses()) {
673 /* if requested auto-connect the outputs to the first N physical ports.
676 uint32_t limit = _master_out->n_outputs().n_total();
678 for (uint32_t n = 0; n < limit; ++n) {
679 Port* p = _master_out->output()->nth (n);
680 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
682 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
683 if (_master_out->output()->connect (p, connect_to, this)) {
684 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
694 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
695 are undefined, at best.
698 /* control out listens to master bus (but ignores it
699 under some conditions)
702 uint32_t limit = _control_out->n_inputs().n_audio();
705 for (uint32_t n = 0; n < limit; ++n) {
706 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
707 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
710 string connect_to = o->name();
711 if (_control_out->input()->connect (p, connect_to, this)) {
712 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
720 /* if control out is not connected,
721 connect control out to physical outs, but use ones after the master if possible
724 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
726 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
728 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
731 _control_out->output()->connect_ports_to_bundle (b, this);
733 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
734 Config->get_monitor_bus_preferred_bundle())
740 /* XXX this logic is wrong for mixed port types */
742 uint32_t shift = _master_out->n_outputs().n_audio();
743 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
744 limit = _control_out->n_outputs().n_audio();
746 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
748 for (uint32_t n = 0; n < limit; ++n) {
750 Port* p = _control_out->output()->nth (n);
751 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
753 if (!connect_to.empty()) {
754 if (_control_out->output()->connect (p, connect_to, this)) {
755 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
766 /* catch up on send+insert cnts */
768 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
770 /* hook us up to the engine */
772 BootMessage (_("Connect to engine"));
774 _engine.set_session (this);
778 Session::hookup_io ()
780 /* stop graph reordering notifications from
781 causing resorts, etc.
784 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
789 /* we delay creating the auditioner till now because
790 it makes its own connections to ports.
791 the engine has to be running for this to work.
795 auditioner.reset (new Auditioner (*this));
798 catch (failed_constructor& err) {
799 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
803 /* load bundles, which we may have postponed earlier on */
804 if (_bundle_xml_node) {
805 load_bundles (*_bundle_xml_node);
806 delete _bundle_xml_node;
809 /* Tell all IO objects to connect themselves together */
811 IO::enable_connecting ();
813 /* Now reset all panners */
815 Delivery::reset_panners ();
817 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
821 boost::shared_ptr<RouteList> r = routes.reader ();
823 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
825 if ((*x)->is_control() || (*x)->is_master()) {
829 (*x)->listen_via (_control_out,
830 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
835 /* Anyone who cares about input state, wake up and do something */
837 IOConnectionsComplete (); /* EMIT SIGNAL */
839 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
841 /* now handle the whole enchilada as if it was one
847 /* update the full solo state, which can't be
848 correctly determined on a per-route basis, but
849 needs the global overview that only the session
853 update_route_solo_state ();
857 Session::playlist_length_changed ()
859 /* we can't just increase end_location->end() if pl->get_maximum_extent()
860 if larger. if the playlist used to be the longest playlist,
861 and its now shorter, we have to decrease end_location->end(). hence,
862 we have to iterate over all diskstreams and check the
863 playlists currently in use.
869 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
871 boost::shared_ptr<Playlist> playlist;
873 if ((playlist = dstream->playlist()) != 0) {
874 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
877 /* see comment in playlist_length_changed () */
882 Session::record_enabling_legal () const
884 /* this used to be in here, but survey says.... we don't need to restrict it */
885 // if (record_status() == Recording) {
889 if (Config->get_all_safe()) {
896 Session::reset_input_monitor_state ()
898 if (transport_rolling()) {
900 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
902 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
903 if ((*i)->record_enabled ()) {
904 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
905 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
909 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
911 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
912 if ((*i)->record_enabled ()) {
913 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
914 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
921 Session::auto_punch_start_changed (Location* location)
923 replace_event (Event::PunchIn, location->start());
925 if (get_record_enabled() && config.get_punch_in()) {
926 /* capture start has been changed, so save new pending state */
927 save_state ("", true);
932 Session::auto_punch_end_changed (Location* location)
934 nframes_t when_to_stop = location->end();
935 // when_to_stop += _worst_output_latency + _worst_input_latency;
936 replace_event (Event::PunchOut, when_to_stop);
940 Session::auto_punch_changed (Location* location)
942 nframes_t when_to_stop = location->end();
944 replace_event (Event::PunchIn, location->start());
945 //when_to_stop += _worst_output_latency + _worst_input_latency;
946 replace_event (Event::PunchOut, when_to_stop);
950 Session::auto_loop_changed (Location* location)
952 replace_event (Event::AutoLoop, location->end(), location->start());
954 if (transport_rolling() && play_loop) {
956 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
958 if (_transport_frame > location->end()) {
959 // relocate to beginning of loop
960 clear_events (Event::LocateRoll);
962 request_locate (location->start(), true);
965 else if (Config->get_seamless_loop() && !loop_changing) {
967 // schedule a locate-roll to refill the diskstreams at the
969 loop_changing = true;
971 if (location->end() > last_loopend) {
972 clear_events (Event::LocateRoll);
973 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
980 last_loopend = location->end();
984 Session::set_auto_punch_location (Location* location)
988 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
989 auto_punch_start_changed_connection.disconnect();
990 auto_punch_end_changed_connection.disconnect();
991 auto_punch_changed_connection.disconnect();
992 existing->set_auto_punch (false, this);
993 remove_event (existing->start(), Event::PunchIn);
994 clear_events (Event::PunchOut);
995 auto_punch_location_changed (0);
1000 if (location == 0) {
1004 if (location->end() <= location->start()) {
1005 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1009 auto_punch_start_changed_connection.disconnect();
1010 auto_punch_end_changed_connection.disconnect();
1011 auto_punch_changed_connection.disconnect();
1013 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1014 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1015 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1017 location->set_auto_punch (true, this);
1020 auto_punch_changed (location);
1022 auto_punch_location_changed (location);
1026 Session::set_auto_loop_location (Location* location)
1030 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1031 auto_loop_start_changed_connection.disconnect();
1032 auto_loop_end_changed_connection.disconnect();
1033 auto_loop_changed_connection.disconnect();
1034 existing->set_auto_loop (false, this);
1035 remove_event (existing->end(), Event::AutoLoop);
1036 auto_loop_location_changed (0);
1041 if (location == 0) {
1045 if (location->end() <= location->start()) {
1046 error << _("Session: you can't use a mark for auto loop") << endmsg;
1050 last_loopend = location->end();
1052 auto_loop_start_changed_connection.disconnect();
1053 auto_loop_end_changed_connection.disconnect();
1054 auto_loop_changed_connection.disconnect();
1056 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1057 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1058 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1060 location->set_auto_loop (true, this);
1062 /* take care of our stuff first */
1064 auto_loop_changed (location);
1066 /* now tell everyone else */
1068 auto_loop_location_changed (location);
1072 Session::locations_added (Location *)
1078 Session::locations_changed ()
1080 _locations.apply (*this, &Session::handle_locations_changed);
1084 Session::handle_locations_changed (Locations::LocationList& locations)
1086 Locations::LocationList::iterator i;
1088 bool set_loop = false;
1089 bool set_punch = false;
1091 for (i = locations.begin(); i != locations.end(); ++i) {
1095 if (location->is_auto_punch()) {
1096 set_auto_punch_location (location);
1099 if (location->is_auto_loop()) {
1100 set_auto_loop_location (location);
1104 if (location->is_start()) {
1105 start_location = location;
1107 if (location->is_end()) {
1108 end_location = location;
1113 set_auto_loop_location (0);
1116 set_auto_punch_location (0);
1123 Session::enable_record ()
1125 /* XXX really atomic compare+swap here */
1126 if (g_atomic_int_get (&_record_status) != Recording) {
1127 g_atomic_int_set (&_record_status, Recording);
1128 _last_record_location = _transport_frame;
1129 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1131 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1132 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1133 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1134 if ((*i)->record_enabled ()) {
1135 (*i)->monitor_input (true);
1140 RecordStateChanged ();
1145 Session::disable_record (bool rt_context, bool force)
1149 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1151 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1152 g_atomic_int_set (&_record_status, Disabled);
1154 if (rs == Recording) {
1155 g_atomic_int_set (&_record_status, Enabled);
1159 // FIXME: timestamp correct? [DR]
1160 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1161 // does this /need/ to be sent in all cases?
1163 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1165 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1166 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1168 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1169 if ((*i)->record_enabled ()) {
1170 (*i)->monitor_input (false);
1175 RecordStateChanged (); /* emit signal */
1178 remove_pending_capture_state ();
1184 Session::step_back_from_record ()
1186 /* XXX really atomic compare+swap here */
1187 if (g_atomic_int_get (&_record_status) == Recording) {
1188 g_atomic_int_set (&_record_status, Enabled);
1190 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1191 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1193 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1194 if ((*i)->record_enabled ()) {
1195 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1196 (*i)->monitor_input (false);
1204 Session::maybe_enable_record ()
1206 g_atomic_int_set (&_record_status, Enabled);
1208 /* this function is currently called from somewhere other than an RT thread.
1209 this save_state() call therefore doesn't impact anything.
1212 save_state ("", true);
1214 if (_transport_speed) {
1215 if (!config.get_punch_in()) {
1219 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1220 RecordStateChanged (); /* EMIT SIGNAL */
1227 Session::audible_frame () const
1233 /* the first of these two possible settings for "offset"
1234 mean that the audible frame is stationary until
1235 audio emerges from the latency compensation
1238 the second means that the audible frame is stationary
1239 until audio would emerge from a physical port
1240 in the absence of any plugin latency compensation
1243 offset = _worst_output_latency;
1245 if (offset > current_block_size) {
1246 offset -= current_block_size;
1248 /* XXX is this correct? if we have no external
1249 physical connections and everything is internal
1250 then surely this is zero? still, how
1251 likely is that anyway?
1253 offset = current_block_size;
1256 if (synced_to_jack()) {
1257 tf = _engine.transport_frame();
1259 tf = _transport_frame;
1264 if (!non_realtime_work_pending()) {
1268 /* check to see if we have passed the first guaranteed
1269 audible frame past our last start position. if not,
1270 return that last start point because in terms
1271 of audible frames, we have not moved yet.
1274 if (_transport_speed > 0.0f) {
1276 if (!play_loop || !have_looped) {
1277 if (tf < _last_roll_location + offset) {
1278 return _last_roll_location;
1286 } else if (_transport_speed < 0.0f) {
1288 /* XXX wot? no backward looping? */
1290 if (tf > _last_roll_location - offset) {
1291 return _last_roll_location;
1303 Session::set_frame_rate (nframes_t frames_per_second)
1305 /** \fn void Session::set_frame_size(nframes_t)
1306 the AudioEngine object that calls this guarantees
1307 that it will not be called while we are also in
1308 ::process(). Its fine to do things that block
1312 _base_frame_rate = frames_per_second;
1316 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1320 // XXX we need some equivalent to this, somehow
1321 // SndFileSource::setup_standard_crossfades (frames_per_second);
1325 /* XXX need to reset/reinstantiate all LADSPA plugins */
1329 Session::set_block_size (nframes_t nframes)
1331 /* the AudioEngine guarantees
1332 that it will not be called while we are also in
1333 ::process(). It is therefore fine to do things that block
1338 current_block_size = nframes;
1340 ensure_buffers(_scratch_buffers->available());
1342 delete [] _gain_automation_buffer;
1343 _gain_automation_buffer = new gain_t[nframes];
1345 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1347 boost::shared_ptr<RouteList> r = routes.reader ();
1349 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1350 (*i)->set_block_size (nframes);
1353 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1354 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1355 (*i)->set_block_size (nframes);
1358 set_worst_io_latencies ();
1363 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1366 nframes_t fade_frames;
1368 /* Don't allow fade of less 1 frame */
1370 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1377 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1381 default_fade_msecs = fade_msecs;
1382 default_fade_steepness = steepness;
1385 // jlc, WTF is this!
1386 Glib::RWLock::ReaderLock lm (route_lock);
1387 AudioRegion::set_default_fade (steepness, fade_frames);
1392 /* XXX have to do this at some point */
1393 /* foreach region using default fade, reset, then
1394 refill_all_diskstream_buffers ();
1399 struct RouteSorter {
1400 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1401 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1403 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1406 if (r1->fed_by.empty()) {
1407 if (r2->fed_by.empty()) {
1408 /* no ardour-based connections inbound to either route. just use signal order */
1409 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1411 /* r2 has connections, r1 does not; run r1 early */
1415 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1422 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1424 shared_ptr<Route> r2;
1426 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1427 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1431 /* make a copy of the existing list of routes that feed r1 */
1433 set<shared_ptr<Route> > existing = r1->fed_by;
1435 /* for each route that feeds r1, recurse, marking it as feeding
1439 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1442 /* r2 is a route that feeds r1 which somehow feeds base. mark
1443 base as being fed by r2
1446 rbase->fed_by.insert (r2);
1450 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1454 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1458 /* now recurse, so that we can mark base as being fed by
1459 all routes that feed r2
1462 trace_terminal (r2, rbase);
1469 Session::resort_routes ()
1471 /* don't do anything here with signals emitted
1472 by Routes while we are being destroyed.
1475 if (_state_of_the_state & Deletion) {
1482 RCUWriter<RouteList> writer (routes);
1483 shared_ptr<RouteList> r = writer.get_copy ();
1484 resort_routes_using (r);
1485 /* writer goes out of scope and forces update */
1490 Session::resort_routes_using (shared_ptr<RouteList> r)
1492 RouteList::iterator i, j;
1494 for (i = r->begin(); i != r->end(); ++i) {
1496 (*i)->fed_by.clear ();
1498 for (j = r->begin(); j != r->end(); ++j) {
1500 /* although routes can feed themselves, it will
1501 cause an endless recursive descent if we
1502 detect it. so don't bother checking for
1510 if ((*j)->feeds (*i)) {
1511 (*i)->fed_by.insert (*j);
1516 for (i = r->begin(); i != r->end(); ++i) {
1517 trace_terminal (*i, *i);
1524 cerr << "finished route resort\n";
1526 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1527 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1534 list<boost::shared_ptr<MidiTrack> >
1535 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1537 char track_name[32];
1538 uint32_t track_id = 0;
1541 RouteList new_routes;
1542 list<boost::shared_ptr<MidiTrack> > ret;
1543 //uint32_t control_id;
1545 // FIXME: need physical I/O and autoconnect stuff for MIDI
1547 /* count existing midi tracks */
1550 shared_ptr<RouteList> r = routes.reader ();
1552 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1553 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1554 if (!(*i)->is_hidden()) {
1556 //channels_used += (*i)->n_inputs().n_midi();
1562 vector<string> physinputs;
1563 vector<string> physoutputs;
1565 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1566 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1568 // control_id = ntracks() + nbusses();
1572 /* check for duplicate route names, since we might have pre-existing
1573 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1574 save, close,restart,add new route - first named route is now
1582 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1584 if (route_by_name (track_name) == 0) {
1588 } while (track_id < (UINT_MAX-1));
1590 shared_ptr<MidiTrack> track;
1593 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1595 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1596 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1601 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1602 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1608 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1612 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1613 port = physinputs[(channels_used+x)%nphysical_in];
1616 if (port.length() && track->connect_input (track->input (x), port, this)) {
1622 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1626 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1627 port = physoutputs[(channels_used+x)%nphysical_out];
1628 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1630 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1634 if (port.length() && track->connect_output (track->output (x), port, this)) {
1639 channels_used += track->n_inputs ().n_midi();
1643 track->midi_diskstream()->non_realtime_input_change();
1644 track->set_route_group (route_group, 0);
1646 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1647 //track->set_remote_control_id (control_id);
1649 new_routes.push_back (track);
1650 ret.push_back (track);
1653 catch (failed_constructor &err) {
1654 error << _("Session: could not create new midi track.") << endmsg;
1657 /* we need to get rid of this, since the track failed to be created */
1658 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1661 RCUWriter<DiskstreamList> writer (diskstreams);
1662 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1663 ds->remove (track->midi_diskstream());
1670 catch (AudioEngine::PortRegistrationFailure& pfe) {
1672 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;
1675 /* we need to get rid of this, since the track failed to be created */
1676 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1679 RCUWriter<DiskstreamList> writer (diskstreams);
1680 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1681 ds->remove (track->midi_diskstream());
1692 if (!new_routes.empty()) {
1693 add_routes (new_routes, false);
1694 save_state (_current_snapshot_name);
1700 list<boost::shared_ptr<AudioTrack> >
1701 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1703 char track_name[32];
1704 uint32_t track_id = 0;
1706 uint32_t channels_used = 0;
1708 RouteList new_routes;
1709 list<boost::shared_ptr<AudioTrack> > ret;
1710 uint32_t control_id;
1712 /* count existing audio tracks */
1715 shared_ptr<RouteList> r = routes.reader ();
1717 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1718 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1719 if (!(*i)->is_hidden()) {
1721 channels_used += (*i)->n_inputs().n_audio();
1727 vector<string> physinputs;
1728 vector<string> physoutputs;
1730 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1731 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1733 control_id = ntracks() + nbusses() + 1;
1737 /* check for duplicate route names, since we might have pre-existing
1738 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1739 save, close,restart,add new route - first named route is now
1747 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1749 if (route_by_name (track_name) == 0) {
1753 } while (track_id < (UINT_MAX-1));
1755 shared_ptr<AudioTrack> track;
1758 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1760 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1761 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1762 input_channels, output_channels)
1767 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1768 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1769 input_channels, output_channels)
1774 if (!physinputs.empty()) {
1775 uint32_t nphysical_in = physinputs.size();
1777 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1781 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1782 port = physinputs[(channels_used+x)%nphysical_in];
1785 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1791 if (!physoutputs.empty()) {
1792 uint32_t nphysical_out = physoutputs.size();
1794 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1797 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1798 port = physoutputs[(channels_used+x)%nphysical_out];
1799 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1800 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1801 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1805 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1811 channels_used += track->n_inputs ().n_audio();
1813 track->set_route_group (route_group, 0);
1815 track->audio_diskstream()->non_realtime_input_change();
1817 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1818 track->set_remote_control_id (control_id);
1821 new_routes.push_back (track);
1822 ret.push_back (track);
1825 catch (failed_constructor &err) {
1826 error << _("Session: could not create new audio track.") << endmsg;
1829 /* we need to get rid of this, since the track failed to be created */
1830 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1833 RCUWriter<DiskstreamList> writer (diskstreams);
1834 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1835 ds->remove (track->audio_diskstream());
1842 catch (AudioEngine::PortRegistrationFailure& pfe) {
1844 error << pfe.what() << endmsg;
1847 /* we need to get rid of this, since the track failed to be created */
1848 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1851 RCUWriter<DiskstreamList> writer (diskstreams);
1852 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1853 ds->remove (track->audio_diskstream());
1864 if (!new_routes.empty()) {
1865 add_routes (new_routes, true);
1872 Session::set_remote_control_ids ()
1874 RemoteModel m = Config->get_remote_model();
1876 shared_ptr<RouteList> r = routes.reader ();
1878 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1879 if ( MixerOrdered == m) {
1880 long order = (*i)->order_key(N_("signal"));
1881 (*i)->set_remote_control_id( order+1 );
1882 } else if ( EditorOrdered == m) {
1883 long order = (*i)->order_key(N_("editor"));
1884 (*i)->set_remote_control_id( order+1 );
1885 } else if ( UserOrdered == m) {
1886 //do nothing ... only changes to remote id's are initiated by user
1893 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1896 uint32_t bus_id = 1;
1898 uint32_t channels_used = 0;
1901 uint32_t control_id;
1903 /* count existing audio busses */
1906 shared_ptr<RouteList> r = routes.reader ();
1908 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1909 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1911 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1914 channels_used += (*i)->n_inputs().n_audio();
1920 vector<string> physinputs;
1921 vector<string> physoutputs;
1923 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1924 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1926 n_physical_audio_outputs = physoutputs.size();
1927 n_physical_audio_inputs = physinputs.size();
1929 control_id = ntracks() + nbusses() + 1;
1934 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1938 if (route_by_name (bus_name) == 0) {
1942 } while (bus_id < (UINT_MAX-1));
1945 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1947 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1948 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1949 input_channels, output_channels)
1955 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1956 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1957 input_channels, output_channels)
1962 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1965 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1966 port = physinputs[((n+x)%n_physical_audio_inputs)];
1969 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1974 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1977 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1978 port = physoutputs[((n+x)%n_physical_outputs)];
1979 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1981 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1985 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1990 channels_used += bus->n_inputs ().n_audio();
1992 bus->set_route_group (route_group, 0);
1993 bus->set_remote_control_id (control_id);
1996 ret.push_back (bus);
2000 catch (failed_constructor &err) {
2001 error << _("Session: could not create new audio route.") << endmsg;
2005 catch (AudioEngine::PortRegistrationFailure& pfe) {
2006 error << pfe.what() << endmsg;
2016 add_routes (ret, true);
2024 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2028 uint32_t control_id;
2030 uint32_t number = 1;
2032 if (!tree.read (template_path.c_str())) {
2036 XMLNode* node = tree.root();
2038 control_id = ntracks() + nbusses() + 1;
2042 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2044 std::string node_name = IO::name_from_state (*node_copy.children().front());
2046 /* generate a new name by adding a number to the end of the template name */
2049 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2053 if (route_by_name (name) == 0) {
2057 } while (number < UINT_MAX);
2059 if (number == UINT_MAX) {
2060 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2064 IO::set_name_in_state (*node_copy.children().front(), name);
2066 Track::zero_diskstream_id_in_xml (node_copy);
2069 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2072 error << _("Session: cannot create track/bus from template description") << endmsg;
2076 if (boost::dynamic_pointer_cast<Track>(route)) {
2077 /* force input/output change signals so that the new diskstream
2078 picks up the configuration of the route. During session
2079 loading this normally happens in a different way.
2081 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2082 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2085 route->set_remote_control_id (control_id);
2088 ret.push_back (route);
2091 catch (failed_constructor &err) {
2092 error << _("Session: could not create new route from template") << endmsg;
2096 catch (AudioEngine::PortRegistrationFailure& pfe) {
2097 error << pfe.what() << endmsg;
2106 add_routes (ret, true);
2113 Session::add_routes (RouteList& new_routes, bool save)
2116 RCUWriter<RouteList> writer (routes);
2117 shared_ptr<RouteList> r = writer.get_copy ();
2118 r->insert (r->end(), new_routes.begin(), new_routes.end());
2121 /* if there is no control out and we're not in the middle of loading,
2122 resort the graph here. if there is a control out, we will resort
2123 toward the end of this method. if we are in the middle of loading,
2124 we will resort when done.
2127 if (!_control_out && IO::connecting_legal) {
2128 resort_routes_using (r);
2132 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2134 boost::weak_ptr<Route> wpr (*x);
2136 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2137 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2138 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2139 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2140 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2141 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2143 if ((*x)->is_master()) {
2147 if ((*x)->is_control()) {
2148 _control_out = (*x);
2152 if (_control_out && IO::connecting_legal) {
2154 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2155 if ((*x)->is_control() || (*x)->is_master()) {
2158 (*x)->listen_via (_control_out,
2159 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2169 save_state (_current_snapshot_name);
2172 RouteAdded (new_routes); /* EMIT SIGNAL */
2176 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2178 boost::shared_ptr<RouteList> r = routes.reader ();
2179 boost::shared_ptr<Send> s;
2183 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2184 if (boost::dynamic_pointer_cast<Track>(*i)) {
2185 if ((s = (*i)->internal_send_for (dest)) != 0) {
2186 s->amp()->gain_control()->set_value (0.0);
2193 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2195 boost::shared_ptr<RouteList> r = routes.reader ();
2196 boost::shared_ptr<Send> s;
2200 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2201 if (boost::dynamic_pointer_cast<Track>(*i)) {
2202 if ((s = (*i)->internal_send_for (dest)) != 0) {
2203 s->amp()->gain_control()->set_value (1.0);
2210 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2212 boost::shared_ptr<RouteList> r = routes.reader ();
2213 boost::shared_ptr<Send> s;
2217 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2218 if (boost::dynamic_pointer_cast<Track>(*i)) {
2219 if ((s = (*i)->internal_send_for (dest)) != 0) {
2220 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2227 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2229 boost::shared_ptr<RouteList> r = routes.reader ();
2230 boost::shared_ptr<RouteList> t (new RouteList);
2232 /* only send tracks */
2234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2235 if (boost::dynamic_pointer_cast<Track>(*i)) {
2240 add_internal_sends (dest, p, t);
2245 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2247 if (dest->is_control() || dest->is_master()) {
2251 if (!dest->internal_return()) {
2252 dest->add_internal_return();
2255 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2257 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2261 (*i)->listen_via (dest, p, true, true);
2266 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2268 /* need to do this in case we're rolling at the time, to prevent false underruns */
2269 dstream->do_refill_with_alloc ();
2271 dstream->set_block_size (current_block_size);
2274 RCUWriter<DiskstreamList> writer (diskstreams);
2275 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2276 ds->push_back (dstream);
2277 /* writer goes out of scope, copies ds back to main */
2280 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2281 /* this will connect to future changes, and check the current length */
2282 diskstream_playlist_changed (dstream);
2284 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2286 dstream->prepare ();
2291 Session::remove_route (shared_ptr<Route> route)
2294 RCUWriter<RouteList> writer (routes);
2295 shared_ptr<RouteList> rs = writer.get_copy ();
2299 /* deleting the master out seems like a dumb
2300 idea, but its more of a UI policy issue
2304 if (route == _master_out) {
2305 _master_out = shared_ptr<Route> ();
2308 if (route == _control_out) {
2310 /* cancel control outs for all routes */
2312 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2313 (*r)->drop_listen (_control_out);
2316 _control_out.reset ();
2319 update_route_solo_state ();
2321 /* writer goes out of scope, forces route list update */
2324 boost::shared_ptr<Track> t;
2325 boost::shared_ptr<Diskstream> ds;
2327 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2328 ds = t->diskstream();
2334 RCUWriter<DiskstreamList> dsl (diskstreams);
2335 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2340 find_current_end ();
2342 // We need to disconnect the routes inputs and outputs
2344 route->input()->disconnect (0);
2345 route->output()->disconnect (0);
2347 update_latency_compensation (false, false);
2350 /* get rid of it from the dead wood collection in the route list manager */
2352 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2356 /* try to cause everyone to drop their references */
2358 route->drop_references ();
2360 sync_order_keys (N_("session"));
2362 /* save the new state of the world */
2364 if (save_state (_current_snapshot_name)) {
2365 save_history (_current_snapshot_name);
2370 Session::route_mute_changed (void* /*src*/)
2376 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2378 boost::shared_ptr<Route> route = wpr.lock();
2380 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2384 if (route->listening()) {
2386 } else if (_listen_cnt > 0) {
2392 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2394 if (solo_update_disabled) {
2399 boost::shared_ptr<Route> route = wpr.lock ();
2402 /* should not happen */
2403 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2407 shared_ptr<RouteList> r = routes.reader ();
2410 if (route->soloed()) {
2416 /* now mod the solo level of all other routes except master & control outs
2417 so that they will be silent if appropriate.
2420 solo_update_disabled = true;
2421 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2423 if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
2425 (*i)->mod_solo_level (delta);
2429 /* make sure master is never muted by solo */
2431 if (route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
2432 _master_out->mod_solo_level (1);
2435 /* ditto for control outs make sure master is never muted by solo */
2437 if (route != _control_out && _control_out && _control_out->solo_level() == 0) {
2438 _control_out->mod_solo_level (1);
2441 solo_update_disabled = false;
2442 update_route_solo_state (r);
2443 SoloChanged (); /* EMIT SIGNAL */
2448 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2450 /* now figure out if anything that matters is soloed */
2452 bool something_soloed = false;
2455 r = routes.reader();
2458 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2459 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
2460 something_soloed = true;
2465 if (something_soloed != _non_soloed_outs_muted) {
2466 _non_soloed_outs_muted = something_soloed;
2467 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2472 Session::route_by_name (string name)
2474 shared_ptr<RouteList> r = routes.reader ();
2476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2477 if ((*i)->name() == name) {
2482 return shared_ptr<Route> ((Route*) 0);
2486 Session::route_by_id (PBD::ID id)
2488 shared_ptr<RouteList> r = routes.reader ();
2490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2491 if ((*i)->id() == id) {
2496 return shared_ptr<Route> ((Route*) 0);
2500 Session::route_by_remote_id (uint32_t id)
2502 shared_ptr<RouteList> r = routes.reader ();
2504 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2505 if ((*i)->remote_control_id() == id) {
2510 return shared_ptr<Route> ((Route*) 0);
2514 Session::find_current_end ()
2516 if (_state_of_the_state & Loading) {
2520 nframes_t max = get_maximum_extent ();
2522 if (max > end_location->end()) {
2523 end_location->set_end (max);
2525 DurationChanged(); /* EMIT SIGNAL */
2530 Session::get_maximum_extent () const
2535 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2537 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2538 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2540 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2541 if ((me = pl->get_maximum_extent()) > max) {
2549 boost::shared_ptr<Diskstream>
2550 Session::diskstream_by_name (string name)
2552 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2554 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2555 if ((*i)->name() == name) {
2560 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2563 boost::shared_ptr<Diskstream>
2564 Session::diskstream_by_id (const PBD::ID& id)
2566 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2568 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2569 if ((*i)->id() == id) {
2574 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2577 /* Region management */
2580 Session::new_region_name (string old)
2582 string::size_type last_period;
2584 string::size_type len = old.length() + 64;
2587 if ((last_period = old.find_last_of ('.')) == string::npos) {
2589 /* no period present - add one explicitly */
2592 last_period = old.length() - 1;
2597 number = atoi (old.substr (last_period+1).c_str());
2601 while (number < (UINT_MAX-1)) {
2603 RegionList::const_iterator i;
2608 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2611 for (i = regions.begin(); i != regions.end(); ++i) {
2612 if (i->second->name() == sbuf) {
2617 if (i == regions.end()) {
2622 if (number != (UINT_MAX-1)) {
2626 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2631 Session::region_name (string& result, string base, bool newlevel)
2636 if (base.find("/") != string::npos) {
2637 base = base.substr(base.find_last_of("/") + 1);
2642 Glib::Mutex::Lock lm (region_lock);
2644 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2653 string::size_type pos;
2655 pos = base.find_last_of ('.');
2657 /* pos may be npos, but then we just use entire base */
2659 subbase = base.substr (0, pos);
2664 Glib::Mutex::Lock lm (region_lock);
2666 map<string,uint32_t>::iterator x;
2670 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2672 region_name_map[subbase] = 1;
2675 snprintf (buf, sizeof (buf), ".%d", x->second);
2686 Session::add_region (boost::shared_ptr<Region> region)
2688 vector<boost::shared_ptr<Region> > v;
2689 v.push_back (region);
2694 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2699 Glib::Mutex::Lock lm (region_lock);
2701 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2703 boost::shared_ptr<Region> region = *ii;
2707 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2711 RegionList::iterator x;
2713 for (x = regions.begin(); x != regions.end(); ++x) {
2715 if (region->region_list_equivalent (x->second)) {
2720 if (x == regions.end()) {
2722 pair<RegionList::key_type,RegionList::mapped_type> entry;
2724 entry.first = region->id();
2725 entry.second = region;
2727 pair<RegionList::iterator,bool> x = regions.insert (entry);
2739 /* mark dirty because something has changed even if we didn't
2740 add the region to the region list.
2747 vector<boost::weak_ptr<Region> > v;
2748 boost::shared_ptr<Region> first_r;
2750 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2752 boost::shared_ptr<Region> region = *ii;
2756 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2759 v.push_back (region);
2766 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2767 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2769 update_region_name_map (region);
2773 RegionsAdded (v); /* EMIT SIGNAL */
2779 Session::update_region_name_map (boost::shared_ptr<Region> region)
2781 string::size_type last_period = region->name().find_last_of ('.');
2783 if (last_period != string::npos && last_period < region->name().length() - 1) {
2785 string base = region->name().substr (0, last_period);
2786 string number = region->name().substr (last_period+1);
2787 map<string,uint32_t>::iterator x;
2789 /* note that if there is no number, we get zero from atoi,
2793 region_name_map[base] = atoi (number);
2798 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2800 boost::shared_ptr<Region> region (weak_region.lock ());
2806 if (what_changed & Region::HiddenChanged) {
2807 /* relay hidden changes */
2808 RegionHiddenChange (region);
2811 if (what_changed & NameChanged) {
2812 update_region_name_map (region);
2817 Session::remove_region (boost::weak_ptr<Region> weak_region)
2819 RegionList::iterator i;
2820 boost::shared_ptr<Region> region (weak_region.lock ());
2826 bool removed = false;
2829 Glib::Mutex::Lock lm (region_lock);
2831 if ((i = regions.find (region->id())) != regions.end()) {
2837 /* mark dirty because something has changed even if we didn't
2838 remove the region from the region list.
2844 RegionRemoved(region); /* EMIT SIGNAL */
2848 boost::shared_ptr<Region>
2849 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2851 RegionList::iterator i;
2852 boost::shared_ptr<Region> region;
2854 Glib::Mutex::Lock lm (region_lock);
2856 for (i = regions.begin(); i != regions.end(); ++i) {
2860 if (region->whole_file()) {
2862 if (child->source_equivalent (region)) {
2868 return boost::shared_ptr<Region> ();
2872 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2874 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2875 (*i)->get_region_list_equivalent_regions (region, result);
2879 Session::destroy_region (boost::shared_ptr<Region> region)
2881 vector<boost::shared_ptr<Source> > srcs;
2884 if (region->playlist()) {
2885 region->playlist()->destroy_region (region);
2888 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2889 srcs.push_back (region->source (n));
2893 region->drop_references ();
2895 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2897 (*i)->mark_for_remove ();
2898 (*i)->drop_references ();
2900 cerr << "source was not used by any playlist\n";
2907 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2909 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2910 destroy_region (*i);
2916 Session::remove_last_capture ()
2918 list<boost::shared_ptr<Region> > r;
2920 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2922 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2923 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2926 r.insert (r.end(), l.begin(), l.end());
2931 destroy_regions (r);
2933 save_state (_current_snapshot_name);
2939 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2945 /* Source Management */
2948 Session::add_source (boost::shared_ptr<Source> source)
2950 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2951 pair<SourceMap::iterator,bool> result;
2953 entry.first = source->id();
2954 entry.second = source;
2957 Glib::Mutex::Lock lm (source_lock);
2958 result = sources.insert (entry);
2961 if (result.second) {
2962 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2966 boost::shared_ptr<AudioFileSource> afs;
2968 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2969 if (Config->get_auto_analyse_audio()) {
2970 Analyser::queue_source_for_analysis (source, false);
2976 Session::remove_source (boost::weak_ptr<Source> src)
2978 SourceMap::iterator i;
2979 boost::shared_ptr<Source> source = src.lock();
2986 Glib::Mutex::Lock lm (source_lock);
2988 if ((i = sources.find (source->id())) != sources.end()) {
2993 if (!_state_of_the_state & InCleanup) {
2995 /* save state so we don't end up with a session file
2996 referring to non-existent sources.
2999 save_state (_current_snapshot_name);
3003 boost::shared_ptr<Source>
3004 Session::source_by_id (const PBD::ID& id)
3006 Glib::Mutex::Lock lm (source_lock);
3007 SourceMap::iterator i;
3008 boost::shared_ptr<Source> source;
3010 if ((i = sources.find (id)) != sources.end()) {
3017 boost::shared_ptr<Source>
3018 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3020 Glib::Mutex::Lock lm (source_lock);
3022 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3023 cerr << "comparing " << path << " with " << i->second->name() << endl;
3024 boost::shared_ptr<AudioFileSource> afs
3025 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3027 if (afs && afs->path() == path && chn == afs->channel()) {
3031 return boost::shared_ptr<Source>();
3036 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3039 string old_basename = PBD::basename_nosuffix (oldname);
3040 string new_legalized = legalize_for_path (newname);
3042 /* note: we know (or assume) the old path is already valid */
3046 /* destructive file sources have a name of the form:
3048 /path/to/Tnnnn-NAME(%[LR])?.wav
3050 the task here is to replace NAME with the new name.
3053 /* find last slash */
3057 string::size_type slash;
3058 string::size_type dash;
3060 if ((slash = path.find_last_of ('/')) == string::npos) {
3064 dir = path.substr (0, slash+1);
3066 /* '-' is not a legal character for the NAME part of the path */
3068 if ((dash = path.find_last_of ('-')) == string::npos) {
3072 prefix = path.substr (slash+1, dash-(slash+1));
3077 path += new_legalized;
3078 path += ".wav"; /* XXX gag me with a spoon */
3082 /* non-destructive file sources have a name of the form:
3084 /path/to/NAME-nnnnn(%[LR])?.ext
3086 the task here is to replace NAME with the new name.
3091 string::size_type slash;
3092 string::size_type dash;
3093 string::size_type postfix;
3095 /* find last slash */
3097 if ((slash = path.find_last_of ('/')) == string::npos) {
3101 dir = path.substr (0, slash+1);
3103 /* '-' is not a legal character for the NAME part of the path */
3105 if ((dash = path.find_last_of ('-')) == string::npos) {
3109 suffix = path.substr (dash+1);
3111 // Suffix is now everything after the dash. Now we need to eliminate
3112 // the nnnnn part, which is done by either finding a '%' or a '.'
3114 postfix = suffix.find_last_of ("%");
3115 if (postfix == string::npos) {
3116 postfix = suffix.find_last_of ('.');
3119 if (postfix != string::npos) {
3120 suffix = suffix.substr (postfix);
3122 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3126 const uint32_t limit = 10000;
3127 char buf[PATH_MAX+1];
3129 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3131 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3133 if (access (buf, F_OK) != 0) {
3141 error << "FATAL ERROR! Could not find a " << endl;
3149 /** Return the full path (in some session directory) for a new embedded source.
3150 * \a name must be a session-unique name that does not contain slashes
3151 * (e.g. as returned by new_*_source_name)
3154 Session::new_source_path_from_name (DataType type, const string& name)
3156 assert(name.find("/") == string::npos);
3158 SessionDirectory sdir(get_best_session_directory_for_new_source());
3161 if (type == DataType::AUDIO) {
3162 p = sdir.sound_path();
3163 } else if (type == DataType::MIDI) {
3164 p = sdir.midi_path();
3166 error << "Unknown source type, unable to create file path" << endmsg;
3171 return p.to_string();
3175 Session::peak_path (Glib::ustring base) const
3177 sys::path peakfile_path(_session_dir->peak_path());
3178 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3179 return peakfile_path.to_string();
3182 /** Return a unique name based on \a base for a new internal audio source */
3184 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3188 char buf[PATH_MAX+1];
3189 const uint32_t limit = 10000;
3193 legalized = legalize_for_path (base);
3195 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3196 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3198 vector<space_and_path>::iterator i;
3199 uint32_t existing = 0;
3201 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3203 SessionDirectory sdir((*i).path);
3205 spath = sdir.sound_path().to_string();
3210 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3211 spath.c_str(), cnt, legalized.c_str());
3212 } else if (nchan == 2) {
3214 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3215 spath.c_str(), cnt, legalized.c_str());
3217 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3218 spath.c_str(), cnt, legalized.c_str());
3220 } else if (nchan < 26) {
3221 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3222 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3224 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3225 spath.c_str(), cnt, legalized.c_str());
3234 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3235 } else if (nchan == 2) {
3237 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3239 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3241 } else if (nchan < 26) {
3242 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3244 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3248 if (sys::exists(buf)) {
3254 if (existing == 0) {
3259 error << string_compose(
3260 _("There are already %1 recordings for %2, which I consider too many."),
3261 limit, base) << endmsg;
3263 throw failed_constructor();
3267 return Glib::path_get_basename(buf);
3270 /** Create a new embedded audio source */
3271 boost::shared_ptr<AudioFileSource>
3272 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3274 const size_t n_chans = ds.n_channels().n_audio();
3275 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3276 const string path = new_source_path_from_name(DataType::AUDIO, name);
3277 return boost::dynamic_pointer_cast<AudioFileSource> (
3278 SourceFactory::createWritable (
3279 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3282 /** Return a unique name based on \a base for a new internal MIDI source */
3284 Session::new_midi_source_name (const string& base)
3287 char buf[PATH_MAX+1];
3288 const uint32_t limit = 10000;
3292 legalized = legalize_for_path (base);
3294 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3295 for (cnt = 1; cnt <= limit; ++cnt) {
3297 vector<space_and_path>::iterator i;
3298 uint32_t existing = 0;
3300 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3302 SessionDirectory sdir((*i).path);
3304 sys::path p = sdir.midi_path();
3307 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3309 if (sys::exists (buf)) {
3314 if (existing == 0) {
3319 error << string_compose(
3320 _("There are already %1 recordings for %2, which I consider too many."),
3321 limit, base) << endmsg;
3323 throw failed_constructor();
3327 return Glib::path_get_basename(buf);
3331 /** Create a new embedded MIDI source */
3332 boost::shared_ptr<MidiSource>
3333 Session::create_midi_source_for_session (MidiDiskstream& ds)
3335 const string name = new_midi_source_name (ds.name());
3336 const string path = new_source_path_from_name (DataType::MIDI, name);
3338 return boost::dynamic_pointer_cast<SMFSource> (
3339 SourceFactory::createWritable (
3340 DataType::MIDI, *this, path, true, false, frame_rate()));
3344 /* Playlist management */
3346 boost::shared_ptr<Playlist>
3347 Session::playlist_by_name (string name)
3349 Glib::Mutex::Lock lm (playlist_lock);
3350 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3351 if ((*i)->name() == name) {
3355 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3356 if ((*i)->name() == name) {
3361 return boost::shared_ptr<Playlist>();
3365 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3367 Glib::Mutex::Lock lm (playlist_lock);
3368 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3369 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3370 list.push_back (*i);
3373 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3374 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3375 list.push_back (*i);
3381 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3383 if (playlist->hidden()) {
3388 Glib::Mutex::Lock lm (playlist_lock);
3389 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3390 playlists.insert (playlists.begin(), playlist);
3391 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3392 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3397 playlist->release();
3402 PlaylistAdded (playlist); /* EMIT SIGNAL */
3406 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3409 Glib::Mutex::Lock lm (playlist_lock);
3410 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3413 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3420 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3422 boost::shared_ptr<Playlist> pl(wpl.lock());
3428 PlaylistList::iterator x;
3431 /* its not supposed to be visible */
3436 Glib::Mutex::Lock lm (playlist_lock);
3440 unused_playlists.insert (pl);
3442 if ((x = playlists.find (pl)) != playlists.end()) {
3443 playlists.erase (x);
3449 playlists.insert (pl);
3451 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3452 unused_playlists.erase (x);
3459 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3461 if (_state_of_the_state & Deletion) {
3465 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3472 Glib::Mutex::Lock lm (playlist_lock);
3474 PlaylistList::iterator i;
3476 i = find (playlists.begin(), playlists.end(), playlist);
3477 if (i != playlists.end()) {
3478 playlists.erase (i);
3481 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3482 if (i != unused_playlists.end()) {
3483 unused_playlists.erase (i);
3490 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3494 Session::set_audition (boost::shared_ptr<Region> r)
3496 pending_audition_region = r;
3497 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3498 schedule_butler_transport_work ();
3502 Session::audition_playlist ()
3504 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3505 ev->region.reset ();
3510 Session::non_realtime_set_audition ()
3512 if (!pending_audition_region) {
3513 auditioner->audition_current_playlist ();
3515 auditioner->audition_region (pending_audition_region);
3516 pending_audition_region.reset ();
3518 AuditionActive (true); /* EMIT SIGNAL */
3522 Session::audition_region (boost::shared_ptr<Region> r)
3524 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3530 Session::cancel_audition ()
3532 if (auditioner->active()) {
3533 auditioner->cancel_audition ();
3534 AuditionActive (false); /* EMIT SIGNAL */
3539 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3541 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3545 Session::remove_empty_sounds ()
3547 vector<string> audio_filenames;
3549 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3551 Glib::Mutex::Lock lm (source_lock);
3553 TapeFileMatcher tape_file_matcher;
3555 remove_if (audio_filenames.begin(), audio_filenames.end(),
3556 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3558 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3560 sys::path audio_file_path (_session_dir->sound_path());
3562 audio_file_path /= *i;
3564 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3568 sys::remove (audio_file_path);
3569 const string peakfile = peak_path (audio_file_path.to_string());
3570 sys::remove (peakfile);
3572 catch (const sys::filesystem_error& err)
3574 error << err.what() << endmsg;
3581 Session::is_auditioning () const
3583 /* can be called before we have an auditioner object */
3585 return auditioner->active();
3592 Session::set_all_solo (bool yn)
3594 shared_ptr<RouteList> r = routes.reader ();
3596 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3597 if (!(*i)->is_hidden()) {
3598 (*i)->set_solo (yn, this);
3606 Session::set_all_listen (bool yn)
3608 shared_ptr<RouteList> r = routes.reader ();
3610 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3611 if (!(*i)->is_hidden()) {
3612 (*i)->set_listen (yn, this);
3620 Session::set_all_mute (bool yn)
3622 shared_ptr<RouteList> r = routes.reader ();
3624 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3625 if (!(*i)->is_hidden()) {
3626 (*i)->set_mute (yn, this);
3634 Session::n_diskstreams () const
3638 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3640 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3641 if (!(*i)->hidden()) {
3649 Session::graph_reordered ()
3651 /* don't do this stuff if we are setting up connections
3652 from a set_state() call or creating new tracks.
3655 if (_state_of_the_state & InitialConnecting) {
3659 /* every track/bus asked for this to be handled but it was deferred because
3660 we were connecting. do it now.
3663 request_input_change_handling ();
3667 /* force all diskstreams to update their capture offset values to
3668 reflect any changes in latencies within the graph.
3671 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3673 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3674 (*i)->set_capture_offset ();
3679 Session::record_disenable_all ()
3681 record_enable_change_all (false);
3685 Session::record_enable_all ()
3687 record_enable_change_all (true);
3691 Session::record_enable_change_all (bool yn)
3693 shared_ptr<RouteList> r = routes.reader ();
3695 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3696 boost::shared_ptr<Track> t;
3698 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3699 t->set_record_enable (yn, this);
3703 /* since we don't keep rec-enable state, don't mark session dirty */
3707 Session::add_processor (Processor* processor)
3709 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3714 Session::remove_processor (Processor* processor)
3718 PortInsert* port_insert;
3720 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3721 insert_bitset[port_insert->bit_slot()] = false;
3722 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3723 send_bitset[send->bit_slot()] = false;
3724 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3725 return_bitset[send->bit_slot()] = false;
3732 Session::available_capture_duration ()
3734 float sample_bytes_on_disk = 4.0; // keep gcc happy
3736 switch (config.get_native_file_data_format()) {
3738 sample_bytes_on_disk = 4.0;
3742 sample_bytes_on_disk = 3.0;
3746 sample_bytes_on_disk = 2.0;
3750 /* impossible, but keep some gcc versions happy */
3751 fatal << string_compose (_("programming error: %1"),
3752 X_("illegal native file data format"))
3757 double scale = 4096.0 / sample_bytes_on_disk;
3759 if (_total_free_4k_blocks * scale > (double) max_frames) {
3763 return (nframes_t) floor (_total_free_4k_blocks * scale);
3767 Session::add_bundle (shared_ptr<Bundle> bundle)
3770 RCUWriter<BundleList> writer (_bundles);
3771 boost::shared_ptr<BundleList> b = writer.get_copy ();
3772 b->push_back (bundle);
3775 BundleAdded (bundle); /* EMIT SIGNAL */
3781 Session::remove_bundle (shared_ptr<Bundle> bundle)
3783 bool removed = false;
3786 RCUWriter<BundleList> writer (_bundles);
3787 boost::shared_ptr<BundleList> b = writer.get_copy ();
3788 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3790 if (i != b->end()) {
3797 BundleRemoved (bundle); /* EMIT SIGNAL */
3804 Session::bundle_by_name (string name) const
3806 boost::shared_ptr<BundleList> b = _bundles.reader ();
3808 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3809 if ((*i)->name() == name) {
3814 return boost::shared_ptr<Bundle> ();
3818 Session::tempo_map_changed (Change)
3822 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3823 (*i)->update_after_tempo_map_change ();
3826 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3827 (*i)->update_after_tempo_map_change ();
3833 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3834 * the given count with the current block size.
3837 Session::ensure_buffers (ChanCount howmany)
3839 if (current_block_size == 0) {
3840 return; // too early? (is this ok?)
3843 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3844 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3845 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3846 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3847 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3850 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3854 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3856 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3857 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3862 Session::next_insert_id ()
3864 /* this doesn't really loop forever. just think about it */
3867 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3868 if (!insert_bitset[n]) {
3869 insert_bitset[n] = true;
3875 /* none available, so resize and try again */
3877 insert_bitset.resize (insert_bitset.size() + 16, false);
3882 Session::next_send_id ()
3884 /* this doesn't really loop forever. just think about it */
3887 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3888 if (!send_bitset[n]) {
3889 send_bitset[n] = true;
3895 /* none available, so resize and try again */
3897 send_bitset.resize (send_bitset.size() + 16, false);
3902 Session::next_return_id ()
3904 /* this doesn't really loop forever. just think about it */
3907 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3908 if (!return_bitset[n]) {
3909 return_bitset[n] = true;
3915 /* none available, so resize and try again */
3917 return_bitset.resize (return_bitset.size() + 16, false);
3922 Session::mark_send_id (uint32_t id)
3924 if (id >= send_bitset.size()) {
3925 send_bitset.resize (id+16, false);
3927 if (send_bitset[id]) {
3928 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3930 send_bitset[id] = true;
3934 Session::mark_return_id (uint32_t id)
3936 if (id >= return_bitset.size()) {
3937 return_bitset.resize (id+16, false);
3939 if (return_bitset[id]) {
3940 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3942 return_bitset[id] = true;
3946 Session::mark_insert_id (uint32_t id)
3948 if (id >= insert_bitset.size()) {
3949 insert_bitset.resize (id+16, false);
3951 if (insert_bitset[id]) {
3952 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3954 insert_bitset[id] = true;
3957 /* Named Selection management */
3960 Session::named_selection_by_name (string name)
3962 Glib::Mutex::Lock lm (named_selection_lock);
3963 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3964 if ((*i)->name == name) {
3972 Session::add_named_selection (NamedSelection* named_selection)
3975 Glib::Mutex::Lock lm (named_selection_lock);
3976 named_selections.insert (named_selections.begin(), named_selection);
3979 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3985 NamedSelectionAdded (); /* EMIT SIGNAL */
3989 Session::remove_named_selection (NamedSelection* named_selection)
3991 bool removed = false;
3994 Glib::Mutex::Lock lm (named_selection_lock);
3996 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3998 if (i != named_selections.end()) {
4000 named_selections.erase (i);
4007 NamedSelectionRemoved (); /* EMIT SIGNAL */
4012 Session::reset_native_file_format ()
4014 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4016 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4017 (*i)->reset_write_sources (false);
4022 Session::route_name_unique (string n) const
4024 shared_ptr<RouteList> r = routes.reader ();
4026 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4027 if ((*i)->name() == n) {
4036 Session::route_name_internal (string n) const
4038 if (auditioner && auditioner->name() == n) {
4042 if (_click_io && _click_io->name() == n) {
4050 Session::n_playlists () const
4052 Glib::Mutex::Lock lm (playlist_lock);
4053 return playlists.size();
4057 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4059 if (!force && howmany <= _npan_buffers) {
4063 if (_pan_automation_buffer) {
4065 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4066 delete [] _pan_automation_buffer[i];
4069 delete [] _pan_automation_buffer;
4072 _pan_automation_buffer = new pan_t*[howmany];
4074 for (uint32_t i = 0; i < howmany; ++i) {
4075 _pan_automation_buffer[i] = new pan_t[nframes];
4078 _npan_buffers = howmany;
4082 Session::freeze (InterThreadInfo& itt)
4084 shared_ptr<RouteList> r = routes.reader ();
4086 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4088 boost::shared_ptr<Track> t;
4090 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4091 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4101 boost::shared_ptr<Region>
4102 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4103 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4104 InterThreadInfo& itt, bool enable_processing)
4106 boost::shared_ptr<Region> result;
4107 boost::shared_ptr<Playlist> playlist;
4108 boost::shared_ptr<AudioFileSource> fsource;
4110 char buf[PATH_MAX+1];
4111 ChanCount nchans(track.audio_diskstream()->n_channels());
4113 nframes_t this_chunk;
4116 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4117 const string sound_dir = sdir.sound_path().to_string();
4118 nframes_t len = end - start;
4121 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4122 end, start) << endmsg;
4126 // any bigger than this seems to cause stack overflows in called functions
4127 const nframes_t chunk_size = (128 * 1024)/4;
4129 // block all process callback handling
4131 block_processing ();
4133 /* call tree *MUST* hold route_lock */
4135 if ((playlist = track.diskstream()->playlist()) == 0) {
4139 /* external redirects will be a problem */
4141 if (track.has_external_redirects()) {
4145 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4147 for (x = 0; x < 99999; ++x) {
4148 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4149 if (access (buf, F_OK) != 0) {
4155 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4160 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4161 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4164 catch (failed_constructor& err) {
4165 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4169 srcs.push_back (fsource);
4172 /* XXX need to flush all redirects */
4177 /* create a set of reasonably-sized buffers */
4178 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4179 buffers.set_count(nchans);
4181 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4182 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4184 afs->prepare_for_peakfile_writes ();
4187 while (to_do && !itt.cancel) {
4189 this_chunk = min (to_do, chunk_size);
4191 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4196 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4197 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4200 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4206 start += this_chunk;
4207 to_do -= this_chunk;
4209 itt.progress = (float) (1.0 - ((double) to_do / len));
4218 xnow = localtime (&now);
4220 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4221 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4224 afs->update_header (position, *xnow, now);
4225 afs->flush_header ();
4229 /* construct a region to represent the bounced material */
4231 result = RegionFactory::create (srcs, 0,
4232 srcs.front()->length(srcs.front()->timeline_position()),
4233 region_name_from_path (srcs.front()->name(), true));
4238 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4239 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4242 afs->mark_for_remove ();
4245 (*src)->drop_references ();
4249 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4250 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4253 afs->done_with_peakfile_writes ();
4257 unblock_processing ();
4263 Session::get_silent_buffers (ChanCount count)
4265 assert(_silent_buffers->available() >= count);
4266 _silent_buffers->set_count(count);
4268 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4269 for (size_t i= 0; i < count.get(*t); ++i) {
4270 _silent_buffers->get(*t, i).clear();
4274 return *_silent_buffers;
4278 Session::get_scratch_buffers (ChanCount count)
4280 if (count != ChanCount::ZERO) {
4281 assert(_scratch_buffers->available() >= count);
4282 _scratch_buffers->set_count(count);
4284 _scratch_buffers->set_count (_scratch_buffers->available());
4287 return *_scratch_buffers;
4291 Session::get_mix_buffers (ChanCount count)
4293 assert(_mix_buffers->available() >= count);
4294 _mix_buffers->set_count(count);
4295 return *_mix_buffers;
4299 Session::ntracks () const
4302 shared_ptr<RouteList> r = routes.reader ();
4304 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4305 if (boost::dynamic_pointer_cast<Track> (*i)) {
4314 Session::nbusses () const
4317 shared_ptr<RouteList> r = routes.reader ();
4319 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4320 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4329 Session::add_automation_list(AutomationList *al)
4331 automation_lists[al->id()] = al;
4335 Session::compute_initial_length ()
4337 return _engine.frame_rate() * 60 * 5;
4341 Session::sync_order_keys (std::string const & base)
4343 if (!Config->get_sync_all_route_ordering()) {
4344 /* leave order keys as they are */
4348 boost::shared_ptr<RouteList> r = routes.reader ();
4350 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4351 (*i)->sync_order_keys (base);
4354 Route::SyncOrderKeys (base); // EMIT SIGNAL
4358 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4360 Session::have_rec_enabled_diskstream () const
4362 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4365 /** Update the state of our rec-enabled diskstreams flag */
4367 Session::update_have_rec_enabled_diskstream ()
4369 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4370 DiskstreamList::iterator i = dsl->begin ();
4371 while (i != dsl->end () && (*i)->record_enabled () == false) {
4375 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4377 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4379 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4380 RecordStateChanged (); /* EMIT SIGNAL */
4385 Session::listen_position_changed ()
4389 switch (Config->get_listen_position()) {
4390 case AfterFaderListen:
4394 case PreFaderListen:
4399 boost::shared_ptr<RouteList> r = routes.reader ();
4401 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4402 (*i)->put_control_outs_at (p);
4407 Session::solo_control_mode_changed ()
4409 /* cancel all solo or all listen when solo control mode changes */
4411 if (Config->get_solo_control_is_listen_control()) {
4412 set_all_solo (false);
4414 set_all_listen (false);
4419 Session::route_group_changed ()
4421 RouteGroupChanged (); /* EMIT SIGNAL */